From patchwork Tue Dec 15 03:27:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 10009 Received: (qmail 37252 invoked by alias); 15 Dec 2015 03:27:40 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 37242 invoked by uid 89); 15 Dec 2015 03:27:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pf0-f175.google.com X-Received: by 10.98.31.216 with SMTP id l85mr28172584pfj.132.1450150055228; Mon, 14 Dec 2015 19:27:35 -0800 (PST) Date: Mon, 14 Dec 2015 19:27:33 -0800 From: "H.J. Lu" To: GNU C Library Subject: [PATCH] [BZ #19363] Use INTERNAL_SYSCALL_TIMES for Linux times Message-ID: <20151215032733.GA14426@gmail.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) The Linux times function, which returns clock_t, is implemented with INTERNAL_SYSCALL. Since INTERNAL_SYSCALL returns 32-bit integer and and clock_t is 64-bit on x32, there is mismatch on x32. times is the only such function since there is lseek.S for x32. This patch replaces INTERNAL_SYSCALL in Linux times.c with INTERNAL_SYSCALL_TIMES which is default to INTERNAL_SYSCALL and provides x32 times.c with proper INTERNAL_SYSCALL_TIMES. There is no code change on times for i686 nor x86-64. For x32, before this patch, there are 0000000 <__times>: 0: b8 64 00 00 40 mov $0x40000064,%eax 5: 0f 05 syscall 7: 48 63 d0 movslq %eax,%rdx ^^^^^^^^^^ Incorrect signed extension a: 48 83 fa f2 cmp $0xfffffffffffffff2,%rdx e: 75 07 jne 17 <__times+0x17> 10: 3d 00 f0 ff ff cmp $0xfffff000,%eax 15: 77 11 ja 28 <__times+0x28> 17: 48 83 fa ff cmp $0xffffffffffffffff,%rdx 1b: b8 00 00 00 00 mov $0x0,%eax 20: 48 0f 45 c2 cmovne %rdx,%rax 24: c3 retq After this patch, there are 00000000 <__times>: 0: b8 64 00 00 40 mov $0x40000064,%eax 5: 0f 05 syscall 7: 48 83 f8 f2 cmp $0xfffffffffffffff2,%rax b: 75 07 jne 14 <__times+0x14> d: 3d 00 f0 ff ff cmp $0xfffff000,%eax 12: 77 14 ja 28 <__times+0x28> 14: 48 83 f8 ff cmp $0xffffffffffffffff,%rax 18: ba 00 00 00 00 mov $0x0,%edx 1d: 48 0f 44 c2 cmove %rdx,%rax 21: c3 retq The incorrect signed extension is gone. Tested on i686, x86-64 and x32. OK for master? H.J. --- [BZ #19363] * sysdeps/unix/sysv/linux/times.c (INTERNAL_SYSCALL_TIMES): New. (__times): Replace INTERNAL_SYSCALL with INTERNAL_SYSCALL_TIMES. * sysdeps/unix/sysv/linux/x86_64/x32/times.c: New file. --- sysdeps/unix/sysv/linux/times.c | 6 +++++- sysdeps/unix/sysv/linux/x86_64/x32/times.c | 31 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/times.c diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c index 19b77cf..0dec69b 100644 --- a/sysdeps/unix/sysv/linux/times.c +++ b/sysdeps/unix/sysv/linux/times.c @@ -19,12 +19,16 @@ #include #include +#ifndef INTERNAL_SYSCALL_TIMES +# define INTERNAL_SYSCALL_TIMES(err, buf) \ + INTERNAL_SYSCALL (times, err, 1, buf) +#endif clock_t __times (struct tms *buf) { INTERNAL_SYSCALL_DECL (err); - clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf); + clock_t ret = INTERNAL_SYSCALL_TIMES(err, buf); if (INTERNAL_SYSCALL_ERROR_P (ret, err) && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0) && buf) diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/times.c b/sysdeps/unix/sysv/linux/x86_64/x32/times.c new file mode 100644 index 0000000..c32324f --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/x32/times.c @@ -0,0 +1,31 @@ +/* Linux times. X32 version. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* Incline Linux times system calls. */ +# define INTERNAL_SYSCALL_TIMES(err, buf) \ + ({ \ + unsigned long long int resultvar; \ + LOAD_ARGS_1 (buf) \ + LOAD_REGS_1 \ + asm volatile ( \ + "syscall\n\t" \ + : "=a" (resultvar) \ + : "0" (__NR_times) ASM_ARGS_1 : "memory", "cc", "r11", "cx"); \ + (long long int) resultvar; }) + +#include