This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] [BZ #19363] Use INTERNAL_SYSCALL_TIMES for Linux times
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Thu, 17 Dec 2015 11:46:06 -0800
- Subject: Re: [PATCH] [BZ #19363] Use INTERNAL_SYSCALL_TIMES for Linux times
- Authentication-results: sourceware.org; auth=none
- References: <20151215032733 dot GA14426 at gmail dot com> <20151215052534 dot GA1512 at altlinux dot org> <CAMe9rOqaFPgeKuiXNfPRwzH9hVM-e9X3=Vin_kMAjty9m3WazA at mail dot gmail dot com> <CAMe9rOr2OSw+QKz4F=svf2JfByXbaMGjDqejTjG2T+hnQQ3g3g at mail dot gmail dot com> <CAMe9rOoUxFRh9NcRPzFiwx33k3a6+xa2mTPFkbG+SLThX197fA at mail dot gmail dot com>
On Thu, Dec 17, 2015 at 5:31 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Dec 16, 2015 at 5:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Tue, Dec 15, 2015 at 5:52 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Mon, Dec 14, 2015 at 9:25 PM, Dmitry V. Levin <ldv@altlinux.org> wrote:
>>>> On Mon, Dec 14, 2015 at 07:27:33PM -0800, H.J. Lu wrote:
>>>>> 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
>>>>
>>>> Looks like there is another truncation remaining here that comes
>>>> from INTERNAL_SYSCALL_ERROR_P.
>>>>
>>>
>>> You are right. Here is the updated patch with all INTERNAL_SYSCALL*
>>> macros replaced by INTERNAL_SYSCALL_TIMES* macros.
>>>
>>> There is no code change on i686 nor x86-64. OK for master?
>>
>> Here is the updated patch using REGISTERS_CLOBBERED_BY_SYSCALL.
>> OK for master?
>>
>>
>
> Any comments? If people don't want to change
> sysdeps/unix/sysv/linux/times.c, I can make a
> copy and update it for x32.
It turns out that we only need to add x32 times.c I am checking
in this patch now.
--
H.J.
From 78bce218b25a1fd5e52632a8ed9317ff20c54c5e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 14 Dec 2015 19:09:13 -0800
Subject: [PATCH] Provide x32 times
Since times returns 64-bit clock_t on x32, we need to provide x32 times
by redefining INTERNAL_SYSCALL_NCS and INTERNAL_SYSCALL_ERROR_P with
64-bit return type for syscall. All system calls returning 64-bit
integer, which are lseek, time and times, must be handled specially for
x32. lseek is handled by x32 lseek.S and time doesn't check syscall
return. times is the only missed one. 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
^^^^^^^^^^^^^^^^^^^^^ 32-bit compare
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 08 jne 15 <__times+0x15>
d: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
13: 77 13 ja 28 <__times+0x28>
15: 48 83 f8 ff cmp $0xffffffffffffffff,%rax
19: ba 00 00 00 00 mov $0x0,%edx
1e: 48 0f 44 c2 cmove %rdx,%rax
22: c3 retq
The incorrect signed extension and 32-bit compare are gone.
[BZ #19363]
* sysdeps/unix/sysv/linux/x86_64/x32/times.c: New file.
---
sysdeps/unix/sysv/linux/x86_64/x32/times.c | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/times.c
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..3002d92
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/times.c
@@ -0,0 +1,38 @@
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Linux times system call returns 64-bit integer. */
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ unsigned long long int resultvar; \
+ LOAD_ARGS_##nr (args) \
+ LOAD_REGS_##nr \
+ asm volatile ( \
+ "syscall\n\t" \
+ : "=a" (resultvar) \
+ : "0" (name) ASM_ARGS_##nr : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \
+ (long long int) resultvar; })
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned long long int) (val) >= -4095LL)
+
+#include <sysdeps/unix/sysv/linux/times.c>
--
2.5.0