about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@ezchip.com>2015-01-05 12:06:15 -0500
committerChris Metcalf <cmetcalf@ezchip.com>2015-01-05 12:06:15 -0500
commit7ea793f39ca1362bc1d6587d29b1e7f52eb8a9a1 (patch)
treed652659b16f7182dad990df318c9d5aeab8b0a92 /sysdeps/unix/sysv/linux
parent1dca195e1c50d69fa4f0d18e821ec68f5d286df4 (diff)
downloadglibc-7ea793f39ca1362bc1d6587d29b1e7f52eb8a9a1.tar.gz
glibc-7ea793f39ca1362bc1d6587d29b1e7f52eb8a9a1.tar.xz
glibc-7ea793f39ca1362bc1d6587d29b1e7f52eb8a9a1.zip
tile: check error properly for vDSO calls
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.
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h12
-rw-r--r--sysdeps/unix/sysv/linux/tile/init-first.c6
-rw-r--r--sysdeps/unix/sysv/linux/tile/sysdep.h8
3 files changed, 20 insertions, 6 deletions
diff --git a/sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h
index cc720f1db6..44f828630f 100644
--- a/sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h
@@ -22,10 +22,18 @@
 
 #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
 
diff --git a/sysdeps/unix/sysv/linux/tile/init-first.c b/sysdeps/unix/sysv/linux/tile/init-first.c
index 6e7917c341..75dbfd79b9 100644
--- a/sysdeps/unix/sysv/linux/tile/init-first.c
+++ b/sysdeps/unix/sysv/linux/tile/init-first.c
@@ -19,9 +19,11 @@
 #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)
 
diff --git a/sysdeps/unix/sysv/linux/tile/sysdep.h b/sysdeps/unix/sysv/linux/tile/sysdep.h
index 074b916764..64c8920645 100644
--- a/sysdeps/unix/sysv/linux/tile/sysdep.h
+++ b/sysdeps/unix/sysv/linux/tile/sysdep.h
@@ -217,7 +217,9 @@
     __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)		      \
@@ -242,7 +244,9 @@
     __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;							      \