]> granicus.if.org Git - strace/commitdiff
tests/times.test: workaround libc bug on x32
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 15 Dec 2015 15:26:29 +0000 (15:26 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 15 Dec 2015 23:34:03 +0000 (23:34 +0000)
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.

tests/times.c

index f0e7086b2919e0629da5fe00cf3a9e976d28b1d9..c34a9a3201cb2a85658456d69c81d0588ff5a4d1 100644 (file)
@@ -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, ",