]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
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 123b0b28fcd181d5fa34e4a55631f5c51c631c50..8482b88f8a712ddd146a0486b2239f83a4c2e4bf 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 cc720f1db687c12d68be680c84c96214aa1ecf85..44f828630fc237228ab0a48421ade90ec13221f1 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 6e7917c3416a4f6eec8e33188047f2980234a6f0..75dbfd79b906bc95fe01e05a9fc12ffa270f9198 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 074b91676472741c2e5f6242263a02e2a162de9c..64c89206456ce9d93a87b921213c7b3a481e9c9e 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;                                                          \