tile: check error properly for vDSO calls
authorChris Metcalf <cmetcalf@ezchip.com>
Mon, 5 Jan 2015 17:06:15 +0000 (12:06 -0500)
committerChris Metcalf <cmetcalf@ezchip.com>
Mon, 5 Jan 2015 17:06:15 +0000 (12:06 -0500)
The tile vDSO vsyscalls were not properly setting the error value.
Conventionally, tile returns the same "non-negative success, negative
errno" value that x86 does (in r0), but it also returns "zero or positive
errno" in r1, which is what the regular syscall code checks.  This change
uses that convention for the vDSO calls as well.

ChangeLog
sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h
sysdeps/unix/sysv/linux/tile/init-first.c
sysdeps/unix/sysv/linux/tile/sysdep.h

index 123b0b2..8482b88 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2015-01-05  Chris Metcalf  <cmetcalf@ezchip.com>
 
+        * sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h: Fix return type
+        for __vdso_* functions in declarations.
+        * sysdeps/unix/sysv/linux/tile/init-first.c: Likewise for
+        definitions.
+        * sysdeps/unix/sysv/linux/tile/sysdep.h (INLINE_VSYSCALL,
+        INTERNAL_VSYSCALL): Use struct return types to check for error.
+
        * sysdeps/ieee754/dbl-64/wordsize-64/s_llround.c [!defined _LP64
        && REGISTER_CAST_INT32_TO_INT64]: Provide explicit lround()
        function with cast from llround().
index cc720f1..44f8286 100644 (file)
 
 #ifdef SHARED
 
-extern long int (*__vdso_gettimeofday) (struct timeval *, void *)
+struct syscall_return_value
+{
+  long int value;
+  long int error;
+};
+
+extern struct syscall_return_value (*__vdso_gettimeofday) (struct timeval *,
+                                                           void *)
   attribute_hidden;
 
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+extern struct syscall_return_value (*__vdso_clock_gettime) (clockid_t,
+                                                            struct timespec *);
 
 #endif
 
index 6e7917c..75dbfd7 100644 (file)
 #include <dl-vdso.h>
 #include <bits/libc-vdso.h>
 
-long int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden;
+struct syscall_return_value (*__vdso_gettimeofday) (struct timeval *, void *)
+  attribute_hidden;
 
-long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+struct syscall_return_value (*__vdso_clock_gettime) (clockid_t,
+                                                     struct timespec *)
   __attribute__ ((nocommon));
 strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
 
index 074b916..64c8920 100644 (file)
     __typeof (__vdso_##name) vdsop = __vdso_##name;                          \
     if (vdsop != NULL)                                                       \
       {                                                                              \
-        sc_ret = vdsop (args);                                               \
+        struct syscall_return_value rv = vdsop (args);                       \
+        sc_ret = rv.value;                                                   \
+        sc_err = rv.error;                                                   \
         if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                              \
           goto out;                                                          \
         if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS)               \
     __typeof (__vdso_##name) vdsop = __vdso_##name;                          \
     if (vdsop != NULL)                                                       \
       {                                                                              \
-        v_ret = vdsop (args);                                                \
+        struct syscall_return_value rv = vdsop (args);                       \
+        v_ret = rv.value;                                                    \
+        err = rv.error;                                                              \
         if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)                           \
             || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)                \
           goto out;                                                          \