about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/powerpc
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.com>2015-04-17 10:58:31 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-05-26 10:10:36 -0300
commitf534255e4d276ee7b20b45637d16a00b122e5df3 (patch)
treeabbedc3d05bdfb526d0171fccd87fb84ecb1acd9 /sysdeps/unix/sysv/linux/powerpc
parent829a679fac1fe173e81cb2c08204d2da86cf3f3a (diff)
downloadglibc-f534255e4d276ee7b20b45637d16a00b122e5df3.tar.gz
glibc-f534255e4d276ee7b20b45637d16a00b122e5df3.tar.xz
glibc-f534255e4d276ee7b20b45637d16a00b122e5df3.zip
Consolidate vDSO macros and usage
This patch consolidate the Linux vDSO define and usage across all ports
that uses it.  The common vDSO definitions and calling through
{INLINE/INTERNAL}_VSYSCALL macros are moved to a common header
sysdep-vdso.h and vDSO name declaration and prototype is defined
using a common macro.

Also PTR_{MANGLE,DEMANGLE} is added to ports that does not use them
for vDSO calls (aarch64, powerpc, s390, and tile) and thus it will
reflect in code changes.  For ports that already implement pointer
mangling/demangling in vDSO system (i386, x32, x86_64) this patch
is mainly a code refactor.

Checked on x32, x86_64, x32, ppc64le, and aarch64.
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/init-first.c56
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/libc-vdso.h24
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h95
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h72
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c3
5 files changed, 81 insertions, 169 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c
index b4917d12a5..ee91c0bf9e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/init-first.c
+++ b/sysdeps/unix/sysv/linux/powerpc/init-first.c
@@ -23,17 +23,19 @@
 # undef __clock_getres
 # include <libc-vdso.h>
 
-void *__vdso_gettimeofday attribute_hidden;
-void *__vdso_clock_gettime;
-void *__vdso_clock_getres;
-void *__vdso_get_tbfreq;
-void *__vdso_getcpu;
-void *__vdso_time;
+int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
+  attribute_hidden;
+int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
+int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
+unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
+int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *);
+time_t (*VDSO_SYMBOL(time)) (time_t *);
+
 #if defined(__PPC64__) || defined(__powerpc64__)
-void *__vdso_sigtramp_rt64;
+void *VDSO_SYMBOL(sigtramp_rt64);
 #else
-void *__vdso_sigtramp32;
-void *__vdso_sigtramp_rt32;
+void *VDSO_SYMBOL(sigtramp32);
+void *VDSO_SYMBOL(sigtramp_rt32);
 #endif
 
 static inline void
@@ -41,26 +43,42 @@ _libc_vdso_platform_setup (void)
 {
   PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
 
-  __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
+  void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (gettimeofday) = p;
 
-  __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2615);
+  p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2615);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (clock_gettime) = p;
 
-  __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
+  p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (clock_getres) = p;
 
-  __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_get_tbfreq", &linux2615);
+  p = _dl_vdso_vsym ("__kernel_get_tbfreq", &linux2615);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (get_tbfreq) = p;
 
-  __vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615);
+  p = _dl_vdso_vsym ("__kernel_getcpu", &linux2615);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (getcpu) = p;
 
-  __vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
+  p = _dl_vdso_vsym ("__kernel_time", &linux2615);
+  PTR_MANGLE (p);
+  VDSO_SYMBOL (time) = p;
 
   /* PPC64 uses only one signal trampoline symbol, while PPC32 will use
      two depending if SA_SIGINFO is used (__kernel_sigtramp_rt32) or not
-     (__kernel_sigtramp32).  */
+     (__kernel_sigtramp32).
+     There is no need to pointer mangle these symbol because they will
+     used only for pointer comparison.  */
 #if defined(__PPC64__) || defined(__powerpc64__)
-  __vdso_sigtramp_rt64 = _dl_vdso_vsym ("__kernel_sigtramp_rt64", &linux2615);
+  VDSO_SYMBOL(sigtramp_rt64) = _dl_vdso_vsym ("__kernel_sigtramp_rt64",
+					      &linux2615);
 #else
-  __vdso_sigtramp32 = _dl_vdso_vsym ("__kernel_sigtramp32", &linux2615);
-  __vdso_sigtramp_rt32 = _dl_vdso_vsym ("__kernel_sigtramp_rt32", &linux2615);
+  VDSO_SYMBOL(sigtramp32) = _dl_vdso_vsym ("__kernel_sigtramp32", &linux2615);
+  VDSO_SYMBOL(sigtramp_rt32) = _dl_vdso_vsym ("__kernel_sigtramp_rt32",
+					      &linux2615);
 #endif
 }
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
index 63a7a9bf52..5868d248eb 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
@@ -22,23 +22,21 @@
 
 #ifdef SHARED
 
-extern void *__vdso_gettimeofday attribute_hidden;
+#include <sysdep-vdso.h>
 
-extern void *__vdso_clock_gettime;
-
-extern void *__vdso_clock_getres;
-
-extern void *__vdso_get_tbfreq;
-
-extern void *__vdso_getcpu;
-
-extern void *__vdso_time;
+extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
+  attribute_hidden;
+extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
+extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
+extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
+extern int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *);
+extern time_t (*VDSO_SYMBOL(time)) (time_t *);
 
 #if defined(__PPC64__) || defined(__powerpc64__)
-extern void *__vdso_sigtramp_rt64;
+extern void *VDSO_SYMBOL(sigtramp_rt64);
 #else
-extern void *__vdso_sigtramp32;
-extern void *__vdso_sigtramp_rt32;
+extern void *VDSO_SYMBOL(sigtramp32);
+extern void *VDSO_SYMBOL(sigtramp_rt32);
 #endif
 
 #if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
index 0b41e8cae0..cbce324159 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
@@ -50,77 +50,6 @@
 
 # include <errno.h>
 
-# ifdef SHARED
-#  define INLINE_VSYSCALL(name, nr, args...) \
-  ({									      \
-    __label__ out;							      \
-    __label__ iserr;							      \
-    INTERNAL_SYSCALL_DECL (sc_err);					      \
-    long int sc_ret;							      \
-									      \
-    if (__vdso_##name != NULL)						      \
-      {									      \
-	sc_ret =							      \
-	  INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, long int, nr, ##args);\
-	if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))			      \
-	  goto out;							      \
-	if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS)		      \
-	  goto iserr;							      \
-      }									      \
-									      \
-    sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args);		      \
-    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))			      \
-      {									      \
-      iserr:								      \
-        __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));		      \
-        sc_ret = -1L;							      \
-      }									      \
-  out:									      \
-    sc_ret;								      \
-  })
-# else
-#  define INLINE_VSYSCALL(name, nr, args...) \
-  INLINE_SYSCALL (name, nr, ##args)
-# endif
-
-# ifdef SHARED
-#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
-  ({									      \
-    __label__ out;							      \
-    long int v_ret;							      \
-									      \
-    if (__vdso_##name != NULL)						      \
-      {									      \
-	v_ret =								      \
-	  INTERNAL_VSYSCALL_NCS (__vdso_##name, err, long int, nr, ##args);   \
-	if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)			      \
-	    || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)		      \
-	  goto out;							      \
-      }									      \
-    v_ret = INTERNAL_SYSCALL (name, err, nr, ##args);			      \
-  out:									      \
-    v_ret;								      \
-  })
-# else
-#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
-  INTERNAL_SYSCALL (name, err, nr, ##args)
-# endif
-
-# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...)  \
-  ({									      \
-    type sc_ret = ENOSYS;						      \
-									      \
-    if (__vdso_##name != NULL)						      \
-      sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args);  \
-    else								      \
-      err = 1 << 28;							      \
-    sc_ret;								      \
-  })
-
-/* List of system calls which are supported as vsyscalls.  */
-# define HAVE_CLOCK_GETRES_VSYSCALL	1
-# define HAVE_CLOCK_GETTIME_VSYSCALL	1
-
 /* Define a macro which expands inline into the wrapper code for a VDSO
    call. This use is for internal calls that do not need to handle errors
    normally. It will never touch errno.
@@ -128,7 +57,7 @@
    function call, with the exception of LR (which is needed for the
    "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
    an error return status).  */
-# define INTERNAL_VSYSCALL_NCS(funcptr, err, type, nr, args...) \
+# define INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, nr, type, args...)	      \
   ({									      \
     register void *r0  __asm__ ("r0");					      \
     register long int r3  __asm__ ("r3");				      \
@@ -155,6 +84,9 @@
     rval;								      \
   })
 
+#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
+  INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, nr, long int, args)
+
 # undef INLINE_SYSCALL
 # define INLINE_SYSCALL(name, nr, args...)				\
   ({									\
@@ -216,6 +148,25 @@
 # undef INTERNAL_SYSCALL_ERRNO
 # define INTERNAL_SYSCALL_ERRNO(val, err)     (val)
 
+# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...)  \
+  ({									      \
+    type sc_ret = ENOSYS;						      \
+									      \
+    __typeof (__vdso_##name) vdsop = __vdso_##name;			      \
+    PTR_DEMANGLE (vdsop);						      \
+    if (vdsop != NULL)							      \
+      sc_ret = 								      \
+        INTERNAL_VSYSCALL_CALL_TYPE (vdsop, err, nr, type, ##args);	      \
+    else								      \
+      err = 1 << 28;							      \
+    sc_ret;								      \
+  })
+
+/* List of system calls which are supported as vsyscalls.  */
+# define HAVE_CLOCK_GETRES_VSYSCALL	1
+# define HAVE_CLOCK_GETTIME_VSYSCALL	1
+
+
 # define LOADARGS_0(name, dummy)					      \
 	r0 = name
 # define LOADARGS_1(name, __arg1) \
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
index 324e19ba9a..a727f38ee5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
@@ -61,74 +61,17 @@
 
 #endif /* __ASSEMBLER__ */
 
-/* This version is for kernels that implement system calls that
-   behave like function calls as far as register saving.
-   It falls back to the syscall in the case that the vDSO doesn't
-   exist or fails for ENOSYS */
-#ifdef SHARED
-# define INLINE_VSYSCALL(name, nr, args...) \
-  ({									      \
-    __label__ out;							      \
-    __label__ iserr;							      \
-    INTERNAL_SYSCALL_DECL (sc_err);					      \
-    long int sc_ret;							      \
-									      \
-    if (__vdso_##name != NULL)						      \
-      {									      \
-	sc_ret =							      \
-	  INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, long int, nr, ##args);\
-	if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))			      \
-	  goto out;							      \
-	if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS)		      \
-	  goto iserr;							      \
-      }									      \
-									      \
-    sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args);		      \
-    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))			      \
-      {									      \
-      iserr:								      \
-        __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));		      \
-        sc_ret = -1L;							      \
-      }									      \
-  out:									      \
-    sc_ret;								      \
-  })
-#else
-# define INLINE_VSYSCALL(name, nr, args...) \
-  INLINE_SYSCALL (name, nr, ##args)
-#endif
-
-#ifdef SHARED
-# define INTERNAL_VSYSCALL(name, err, nr, args...) \
-  ({									      \
-    __label__ out;							      \
-    long int v_ret;							      \
-									      \
-    if (__vdso_##name != NULL)						      \
-      {									      \
-	v_ret =								      \
-	  INTERNAL_VSYSCALL_NCS (__vdso_##name, err, long int, nr, ##args);   \
-	if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)			      \
-	    || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)		      \
-	  goto out;							      \
-      }									      \
-    v_ret = INTERNAL_SYSCALL (name, err, nr, ##args);			      \
-  out:									      \
-    v_ret;								      \
-  })
-#else
-# define INTERNAL_VSYSCALL(name, err, nr, args...) \
-  INTERNAL_SYSCALL (name, err, nr, ##args)
-#endif
-
 /* This version is for internal uses when there is no desire
    to set errno */
 #define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...)   \
   ({									      \
     type sc_ret = ENOSYS;						      \
 									      \
-    if (__vdso_##name != NULL)						      \
-      sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args);  \
+    __typeof (__vdso_##name) vdsop = __vdso_##name;			      \
+    PTR_DEMANGLE (vdsop);						      \
+    if (vdsop != NULL)							      \
+      sc_ret =								      \
+        INTERNAL_VSYSCALL_CALL_TYPE (vdsop, err, type, nr, ##args);	      \
     else								      \
       err = 1 << 28;							      \
     sc_ret;								      \
@@ -144,7 +87,7 @@
    gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
    the negation of the return value in the kernel gets reverted.  */
 
-#define INTERNAL_VSYSCALL_NCS(funcptr, err, type, nr, args...) \
+#define INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, type, nr, args...)    \
   ({									\
     register void *r0  __asm__ ("r0");					\
     register long int r3  __asm__ ("r3");				\
@@ -168,6 +111,9 @@
     rval;								\
   })
 
+#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)		\
+  INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, long int, nr, args)
+
 #undef INLINE_SYSCALL
 
 /* This version is for kernels that implement system calls that
diff --git a/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c b/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c
index 5bf540c19a..f93be0119a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c
+++ b/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c
@@ -17,8 +17,7 @@
 
 #include <sched.h>
 #include <sysdep.h>
-#include <libc-vdso.h>
-
+#include <sysdep-vdso.h>
 
 int
 sched_getcpu (void)