tests/times.test: workaround libc bug on x32
As glibc times wrapper on x32 is known to wrongly truncate and then sign extend the syscall return value, invoke the syscall directly on x32. * tests/times.c (main) [__NR_times && __x86_64__ && __ILP32__]: Invoke times syscall using inline asm.
This commit is contained in:
parent
c4afd6dc7a
commit
b6b38fa73b
@ -69,9 +69,29 @@ main (void)
|
||||
* prefer direct times syscall over libc's times function because
|
||||
* the latter is more prone to return value truncation.
|
||||
*/
|
||||
#if !defined __NR_times \
|
||||
|| defined LINUX_MIPSN32 \
|
||||
|| defined __x86_64__ && defined __ILP32__
|
||||
#undef USE_LIBC_SYSCALL
|
||||
#if defined __NR_times && \
|
||||
!defined(LINUX_MIPSN32) && \
|
||||
!(defined __x86_64__ && defined __ILP32__)
|
||||
# define USE_LIBC_SYSCALL 1
|
||||
#endif
|
||||
|
||||
#if defined USE_LIBC_SYSCALL
|
||||
long res = syscall(__NR_times, &tbuf);
|
||||
|
||||
if (-1L == res)
|
||||
return 77;
|
||||
else
|
||||
llres = (unsigned long) res;
|
||||
#elif defined __NR_times && defined __x86_64__ && defined __ILP32__
|
||||
register long arg asm("rdi") = (long) &tbuf;
|
||||
asm volatile("syscall\n\t"
|
||||
: "=a"(llres)
|
||||
: "0"(__NR_times), "r"(arg)
|
||||
: "memory", "cc", "r11", "cx");
|
||||
if (llres > 0xfffffffffffff000)
|
||||
return 77;
|
||||
#else
|
||||
clock_t res = times(&tbuf);
|
||||
|
||||
if ((clock_t) -1 == res)
|
||||
@ -80,13 +100,6 @@ main (void)
|
||||
llres = (unsigned long) res;
|
||||
else
|
||||
llres = res;
|
||||
#else
|
||||
long res = syscall(__NR_times, &tbuf);
|
||||
|
||||
if (-1L == res)
|
||||
return 77;
|
||||
else
|
||||
llres = (unsigned long) res;
|
||||
#endif
|
||||
|
||||
printf("times({tms_utime=%llu, tms_stime=%llu, ",
|
||||
|
Loading…
x
Reference in New Issue
Block a user