check error properly for tile vDSO calls

Message ID 549AF507.2070506@ezchip.com
State Committed
Headers

Commit Message

Chris Metcalf Dec. 24, 2014, 5:16 p.m. UTC
  The -Werror code pointed out that we were not properly setting
the error value for vDSO vsyscalls.  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 and fixes the warning.

2014-12-24  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.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h
index f5b04ba..382ca23 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 fa39b94..249dc99 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 d3b98bd..afecd02 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;                                                          \