diff --git a/ChangeLog b/ChangeLog index d7ad59f675..f06cb9487d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,124 @@ +2015-05-26 Adhemerval Zanella + + * sysdeps/unix/sysv/linux/aarch64/gettimeofday.c (HAVE_VSYSCALL): + Define and include sysdep-vdso.h. + * sysdeps/unix/sysv/linux/s390/gettimeofday.c (HAVE_VSYSCALL): + Likewise. + * sysdeps/unix/sysv/linux/tile/gettimeofday.c (HAVE_VSYSCALL): + Likewise. + * sysdeps/unix/sysv/linux/aarch64/init-first.c (__vdso_gettimeofday): + Define with VDSO_SYMBOL and use PTR_MANGLE. + (__vdso_clock_gettime): Likewise. + (__vdso_clock_getres): Likewise. + (_libc_vdso_platform_setup): Likewise. + * sysdeps/unix/sysv/linux/i386/init-first.c (__vdso_clock_gettime): + Likewise. + (_libc_vdso_platform_setup): Likewise. + * sysdeps/unix/sysv/linux/powerpc/init-first.c (__vdso_gettimeofday): + Likewise. + (__vdso_clock_gettime): Likewise. + (__vdso_clock_getres): Likewise. + (__vdso_get_tbfreq): Likewise. + (__vdso_getcpu): Likewise. + (__vdso_time): Likewise. + (__vdso_sigtramp_rt64): Likewise. + (__vdso_signtramp32): Likewise. + (__vdso_sigtramp_rt32): Likewise. + (_libc_vdso_platform_setup): Likewise. + * sysdeps/unix/sysv/linux/s390/init-first.c (__vdso_gettimeofay): + Likewise. + (__vdso_clock_gettime): Likewise. + (__vdso_clock_getres): Likewise. + (_libc_vdso_platform_setup): Likewise. + * sysdeps/unix/sysv/linux/tile/init-first.c (__vdso_gettimeofday): + Likewise. + (__vdso_clock_gettime): Likewise. + (_libc_vdso_platform_setup): Likewise. + * sysdeps/unix/sysv/linux/x86_64/init-first.c (__vdso_clock_gettime): + Likewise. + (__vdso_getcpu): Likewise. + * sysdeps/unix/sysv/linux/aarch64/libc-vdso.h (__vdso_gettimeoday): + Use VDSO_SYMBOL macro to define. + (__vdso_clock_gettime): Likewise. + (__vdso_clock_getres): Likewise. + * sysdeps/unix/sysv/linux/powerpc/libc-vdso.h (__vdso_gettimeofday): + Likewise. + (__vdso_clock_gettime): Likewise. + (__vdso_clock_getres): Likewise. + (__vdso_get_tbfreq): Likewise. + (__vdso_getcpu): Likewise. + (__vdso_time): Likewise. + (__vdso_sigtramp_rt64): Likewise. + (__vdso_signtramp32): Likewise. + (__vdso_sigtramp_rt32): Likewise. + * sysdeps/unix/sysv/linux/s390/libc-vdso.h (__vdso_gettimeofday): + Likewise. + (__vdso_clock_gettime): Likewise. + (__vdso_clock_getres): Likewise. + * sysdeps/unix/sysv/linux/tile/libc-vdso.h (__vdso_gettimeofday): + Likewise. + (__vdso_clock_gettime): Likewise. + * sysdeps/unix/sysv/linux/x86/libc-vdso.h (__vdso_clock_gettime): + Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep.h (INLINE_VSYSCALL): Remove + macro. + (INTERNAL_VSYSCALL): Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h (INLINE_VSYSCALL): + Remove macro. + (INTERNAL_VSYSCALL): Likewise. + (INTERNAL_VSYSCALL_NCS): Likewise. + (INTERNAL_VSYSCALL_CALL): New macro. + (INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Use PTR_DEMANGLE. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h (INLINE_VSYSCALL): + Likewise. + (INTERNAL_VSYSCALL): Likewise. + (INTERNAL_VSYSCALL_NCS): Likewise. + (INTERNAL_VSYSCALL_CALL): New macro. + (INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Use PTR_DEMANGLE. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h + (INLINE_VSYSCALL): Remove macro. + (INTERNAL_VSYSCALL): Remove macro. + (INTERNAL_VSYSCALL_NCS): Remove macro. + (INTERNAL_VSYSCALL_CALL): New macro. + (INTERNAL_VSYSCALL_CALL_TYPE): New macro. + (INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Use INTERNAL_VSYSCALL_CALL. + (INTERNAL_VSYSCALL_NCS_TYPE): Likewise. + (HAVE_CLOCK_GETRES_VSYSCALL): New define. + (HAVE_CLOCK_GETTIME_VSYSCALL): Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h + (INLINE_VSYSCALL): Remove macro. + (INTERNAL_VSYSCALL): Likewise. + (INTERNAL_VSYSCALL_NCS): Likewise. + (INTERNAL_VSYSCALL_CALL): New macro. + (INTERNAL_VSYSCALL_CALL_TYPE): Likewise. + (INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Use INTERNAL_VSYSCALL_CALL and + PTR_DEMANGLE on vDSO pointer. + (INTERNAL_VSYSCALL_NCS_TYPE): Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep.h (INLINE_VSYSCALL): Remove + macro. + (INTERNAL_SYSCALL): Likewise. + (INTERNAL_VSYSCALL_NCS): Remove macro. + (INTERNAL_VSYSCALL_CALL): New macro. + * sysdeps/unix/sysv/linux/x86_64/sysdep.h (INLINE_VSYSCALL): + Remove macro. + (INTERNAL_VSYSCALL): Likewise. + * sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c: Include + sysdep-vdso.h instead of libc-vdso.h. + * sysdeps/unix/sysv/linux/clock_getres.c (INTERNAL_VSYSCALL): Remove + definition. + (INLINE_VSYSCALL): Likewise. + (HAVE_VSYSCALL) [HAVE_CLOCK_GETRES_VSYSCALL]: Define. + * sysdeps/unix/sysv/linux/clock_gettime.c (INTERNAL_VSYSCALL): Remove + definition. + (INLINE_VSYSCALL): Likewise. + (INTERNAL_VSYSCALL): Likewise. + (HAVE_VSYSCALL) [HAVE_CLOCK_GETTIME_VSYSCALL]: Define. + * sysdeps/unix/sysv/linux/timespec_get.c + (INTERNAL_VSYSCALL) [HAVE_CLOCK_GETTIME_VSYSCALL]: Define. + (timespec_get): Use ANSI prototype. + * sysdeps/unix/sysv/linux/sysdep-vdso.h: New file: default vDSO macros + and definition for Linux. + 2015-05-25 Andrew Senkevich * elf/Makefile (localplt-built-dso): libmvec added to localplt test. diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c index 67b7f6d566..daa6538a68 100644 --- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c @@ -21,7 +21,8 @@ #undef __gettimeofday -#include +#define HAVE_VSYSCALL +#include /* Get the current time of day and timezone information, putting it into *tv and *tz. If tz is null, *tz is not filled. diff --git a/sysdeps/unix/sysv/linux/aarch64/init-first.c b/sysdeps/unix/sysv/linux/aarch64/init-first.c index d99c821f6d..854189a793 100644 --- a/sysdeps/unix/sysv/linux/aarch64/init-first.c +++ b/sysdeps/unix/sysv/linux/aarch64/init-first.c @@ -23,18 +23,26 @@ # undef __clock_getres # include -void (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden; -void (*__vdso_clock_gettime) (clockid_t, struct timespec *); -void (*__vdso_clock_getres) (clockid_t, struct timespec *); +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 *); static inline void _libc_vdso_platform_setup (void) { PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537); - __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639); - __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639); - __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639); + void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639); + PTR_MANGLE (p); + VDSO_SYMBOL(gettimeofday) = p; + + p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639); + PTR_MANGLE (p); + VDSO_SYMBOL(clock_gettime) = p; + + p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639); + PTR_MANGLE (p); + VDSO_SYMBOL(clock_getres) = p; } # define VDSO_SETUP _libc_vdso_platform_setup diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h b/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h index 1f6bb36c3b..c5678a0127 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h @@ -21,10 +21,12 @@ #ifdef SHARED -extern void (*__vdso_gettimeofday) (struct timeval *, void *) +# include + +extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden; -extern void (*__vdso_clock_gettime) (clockid_t, struct timespec *); -extern void (*__vdso_clock_getres) (clockid_t, struct timespec *); +extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *); +extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *); #endif diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h index 91e03fcd6f..e69622a24b 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h +++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h @@ -151,75 +151,11 @@ #else /* not __ASSEMBLER__ */ -# ifdef SHARED -# define INLINE_VSYSCALL(name, nr, args...) \ - ({ \ - __label__ out; \ - __label__ iserr; \ - long sc_ret; \ - INTERNAL_SYSCALL_DECL (sc_err); \ - \ - if (__vdso_##name != NULL) \ - { \ - sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, 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 v_ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, 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 /* List of system calls which are supported as vsyscalls. */ # define HAVE_CLOCK_GETRES_VSYSCALL 1 # define HAVE_CLOCK_GETTIME_VSYSCALL 1 -# define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \ - ({ \ - LOAD_ARGS_##nr (args) \ - asm volatile ("blr %1" \ - : "=r" (_x0) \ - : "r" (funcptr) ASM_ARGS_##nr \ - : "x30", "memory"); \ - (long) _x0; \ - }) - - /* Define a macro which expands into the inline wrapper code for a system call. */ # undef INLINE_SYSCALL diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c index 9b31d8c925..5641967f67 100644 --- a/sysdeps/unix/sysv/linux/clock_getres.c +++ b/sysdeps/unix/sysv/linux/clock_getres.c @@ -21,14 +21,10 @@ #include #include "kernel-posix-cpu-timers.h" -#ifndef HAVE_CLOCK_GETRES_VSYSCALL -# undef INTERNAL_VSYSCALL -# define INTERNAL_VSYSCALL INTERNAL_SYSCALL -# undef INLINE_VSYSCALL -# define INLINE_VSYSCALL INLINE_SYSCALL -#else -# include +#ifdef HAVE_CLOCK_GETRES_VSYSCALL +# define HAVE_VSYSCALL #endif +#include #define SYSCALL_GETRES \ retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, res); \ diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index 93aa0951d7..457114f07e 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -21,23 +21,10 @@ #include #include "kernel-posix-cpu-timers.h" -#ifndef HAVE_CLOCK_GETTIME_VSYSCALL -# undef INTERNAL_VSYSCALL -# define INTERNAL_VSYSCALL INTERNAL_SYSCALL -# undef INLINE_VSYSCALL -# define INLINE_VSYSCALL INLINE_SYSCALL -#else -# include -#endif - -#ifndef SYSCALL_GETTIME -# define SYSCALL_GETTIME(id, tp) \ - INLINE_VSYSCALL (clock_gettime, 2, id, tp) -#endif -#ifndef INTERNAL_GETTIME -# define INTERNAL_GETTIME(id, tp) \ - INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp) +#ifdef HAVE_CLOCK_GETTIME_VSYSCALL +# define HAVE_VSYSCALL #endif +#include /* The REALTIME and MONOTONIC clock are definitely supported in the kernel. */ @@ -45,7 +32,7 @@ SYSDEP_GETTIME_CPUTIME; \ case CLOCK_REALTIME: \ case CLOCK_MONOTONIC: \ - retval = SYSCALL_GETTIME (clock_id, tp); \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ break /* We handled the REALTIME clock here. */ @@ -53,7 +40,7 @@ #define HANDLED_CPUTIME 1 #define SYSDEP_GETTIME_CPU(clock_id, tp) \ - retval = SYSCALL_GETTIME (clock_id, tp); \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ break #define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */ diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c index 5d09bec108..98d1827a73 100644 --- a/sysdeps/unix/sysv/linux/i386/init-first.c +++ b/sysdeps/unix/sysv/linux/i386/init-first.c @@ -20,9 +20,9 @@ # include # include # include -# include +# include -long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) +long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *) attribute_hidden; static long int @@ -41,7 +41,7 @@ __vdso_platform_setup (void) if (p == NULL) p = clock_gettime_syscall; PTR_MANGLE (p); - __vdso_clock_gettime = p; + VDSO_SYMBOL (clock_gettime) = p; } # define VDSO_SETUP __vdso_platform_setup 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 -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 -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 -# 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 #include -#include - +#include int sched_getcpu (void) diff --git a/sysdeps/unix/sysv/linux/s390/gettimeofday.c b/sysdeps/unix/sysv/linux/s390/gettimeofday.c index e8dee26842..9f98f293fa 100644 --- a/sysdeps/unix/sysv/linux/s390/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/s390/gettimeofday.c @@ -21,7 +21,8 @@ #include #include -#include +#define HAVE_VSYSCALL +#include /* Get the current time of day and timezone information, putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. diff --git a/sysdeps/unix/sysv/linux/s390/init-first.c b/sysdeps/unix/sysv/linux/s390/init-first.c index 2e00a99866..8129967ba5 100644 --- a/sysdeps/unix/sysv/linux/s390/init-first.c +++ b/sysdeps/unix/sysv/linux/s390/init-first.c @@ -23,15 +23,14 @@ # undef __clock_getres # include -long int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden; +long int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) + attribute_hidden; -long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) +long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *) __attribute__ ((nocommon)); -strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden) -long int (*__vdso_clock_getres) (clockid_t, struct timespec *) +long int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *) __attribute__ ((nocommon)); -strong_alias (__vdso_clock_getres, __GI___vdso_clock_getres attribute_hidden) static inline void @@ -39,9 +38,17 @@ _libc_vdso_platform_setup (void) { PREPARE_VERSION (linux2629, "LINUX_2.6.29", 123718585); - __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2629); - __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2629); - __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2629); + void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2629); + PTR_MANGLE (p); + VDSO_SYMBOL (gettimeofday) = p; + + p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2629); + PTR_MANGLE (p); + VDSO_SYMBOL (clock_gettime) = p; + + p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2629); + PTR_MANGLE (p); + VDSO_SYMBOL (clock_getres) = p; } # define VDSO_SETUP _libc_vdso_platform_setup diff --git a/sysdeps/unix/sysv/linux/s390/libc-vdso.h b/sysdeps/unix/sysv/linux/s390/libc-vdso.h index 3fd3d06b79..88d9eaf585 100644 --- a/sysdeps/unix/sysv/linux/s390/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/s390/libc-vdso.h @@ -22,12 +22,14 @@ #ifdef SHARED -extern long int (*__vdso_gettimeofday) (struct timeval *, void *) - attribute_hidden; +#include -extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *); +extern long int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) + attribute_hidden; -extern long int (*__vdso_clock_getres) (clockid_t, struct timespec *); +extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *); + +extern long int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *); #endif diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h index 9c194b80a7..a773a2856d 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h @@ -282,77 +282,22 @@ #define HAVE_CLOCK_GETRES_VSYSCALL 1 #define HAVE_CLOCK_GETTIME_VSYSCALL 1 -/* 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; \ - long int _ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, , nr, ##args); \ - if (!INTERNAL_SYSCALL_ERROR_P (_ret, )) \ - goto out; \ - if (INTERNAL_SYSCALL_ERRNO (_ret, ) != ENOSYS) \ - goto iserr; \ - } \ - \ - _ret = INTERNAL_SYSCALL (name, , nr, ##args); \ - if (INTERNAL_SYSCALL_ERROR_P (_ret, )) \ - { \ - iserr: \ - __set_errno (INTERNAL_SYSCALL_ERRNO (_ret, )); \ - _ret = -1L; \ - } \ - out: \ - (int) _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 _ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ - if (!INTERNAL_SYSCALL_ERROR_P (_ret, err) \ - || INTERNAL_SYSCALL_ERRNO (_ret, err) != ENOSYS) \ - goto out; \ - } \ - _ret = INTERNAL_SYSCALL (name, err, nr, ##args); \ - out: \ - _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, nr, args...) \ ({ \ long int _ret = ENOSYS; \ \ - if (__vdso_##name != NULL) \ - _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ + __typeof (__vdso_##name) vdsop = __vdso_##name; \ + PTR_DEMANGLE (vdsop); \ + if (vdsop != NULL) \ + _ret = INTERNAL_VSYSCALL_CALL (vdsop, err, nr, ##args); \ else \ err = 1 << 28; \ _ret; \ }) -#define INTERNAL_VSYSCALL_NCS(fn, err, nr, args...) \ +#define INTERNAL_VSYSCALL_CALL(fn, err, nr, args...) \ ({ \ DECLARGS_##nr(args) \ register long _ret asm("2"); \ diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h index 4631cb1160..c944634cde 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h @@ -288,77 +288,22 @@ #define HAVE_CLOCK_GETRES_VSYSCALL 1 #define HAVE_CLOCK_GETTIME_VSYSCALL 1 -/* 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; \ - long int _ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, , nr, ##args); \ - if (!INTERNAL_SYSCALL_ERROR_P (_ret, )) \ - goto out; \ - if (INTERNAL_SYSCALL_ERRNO (_ret, ) != ENOSYS) \ - goto iserr; \ - } \ - \ - _ret = INTERNAL_SYSCALL (name, , nr, ##args); \ - if (INTERNAL_SYSCALL_ERROR_P (_ret, )) \ - { \ - iserr: \ - __set_errno (INTERNAL_SYSCALL_ERRNO (_ret, )); \ - _ret = -1L; \ - } \ - out: \ - (int) _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 _ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ - if (!INTERNAL_SYSCALL_ERROR_P (_ret, err) \ - || INTERNAL_SYSCALL_ERRNO (_ret, err) != ENOSYS) \ - goto out; \ - } \ - _ret = INTERNAL_SYSCALL (name, err, nr, ##args); \ - out: \ - _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, nr, args...) \ ({ \ long int _ret = ENOSYS; \ \ - if (__vdso_##name != NULL) \ - _ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ + __typeof (__vdso_##name) vdsop = __vdso_##name; \ + PTR_DEMANGLE (vdsop); \ + if (vdsop != NULL) \ + _ret = INTERNAL_VSYSCALL_CALL (vdsop, err, nr, ##args); \ else \ err = 1 << 28; \ _ret; \ }) -#define INTERNAL_VSYSCALL_NCS(fn, err, nr, args...) \ +#define INTERNAL_VSYSCALL_CALL(fn, err, nr, args...) \ ({ \ DECLARGS_##nr(args) \ register long _ret asm("2"); \ diff --git a/sysdeps/unix/sysv/linux/sysdep-vdso.h b/sysdeps/unix/sysv/linux/sysdep-vdso.h new file mode 100644 index 0000000000..43e74b9e7c --- /dev/null +++ b/sysdeps/unix/sysv/linux/sysdep-vdso.h @@ -0,0 +1,98 @@ +/* vDSO common definition for Linux. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef SYSDEP_VDSO_LINUX_H +# define SYSDEP_VDSO_LINUX_H + +#define VDSO_SYMBOL(__name) __vdso_##__name + +#ifndef INTERNAL_VSYSCALL_CALL +# define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ + funcptr (args) +#endif + +#ifdef SHARED + +# ifdef HAVE_VSYSCALL + +# include + +# define INLINE_VSYSCALL(name, nr, args...) \ + ({ \ + __label__ out; \ + __label__ iserr; \ + INTERNAL_SYSCALL_DECL (sc_err); \ + long int sc_ret; \ + \ + __typeof (__vdso_##name) vdsop = __vdso_##name; \ + PTR_DEMANGLE (vdsop); \ + if (vdsop != NULL) \ + { \ + sc_ret = INTERNAL_VSYSCALL_CALL (vdsop, sc_err, 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; \ + }) + +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + ({ \ + __label__ out; \ + long v_ret; \ + \ + __typeof (__vdso_##name) vdsop = __vdso_##name; \ + PTR_DEMANGLE (vdsop); \ + if (vdsop != NULL) \ + { \ + v_ret = INTERNAL_VSYSCALL_CALL (vdsop, err, 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 INLINE_VSYSCALL(name, nr, args...) \ + INLINE_SYSCALL (name, nr, ##args) +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL (name, err, nr, ##args) +# endif /* HAVE_VSYSCALL */ + +# else /* SHARED */ + +# define INLINE_VSYSCALL(name, nr, args...) \ + INLINE_SYSCALL (name, nr, ##args) +# define INTERNAL_VSYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL (name, err, nr, ##args) + +#endif /* SHARED */ + +#endif /* SYSDEP_VDSO_LINUX_H */ diff --git a/sysdeps/unix/sysv/linux/tile/gettimeofday.c b/sysdeps/unix/sysv/linux/tile/gettimeofday.c index 8d34b403a2..13382ab70b 100644 --- a/sysdeps/unix/sysv/linux/tile/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/tile/gettimeofday.c @@ -19,7 +19,9 @@ #include #include #include -#include + +#define HAVE_VSYSCALL +#include int __gettimeofday (struct timeval *tv, struct timezone *tz) diff --git a/sysdeps/unix/sysv/linux/tile/init-first.c b/sysdeps/unix/sysv/linux/tile/init-first.c index 6b0e26a35e..29356c21bb 100644 --- a/sysdeps/unix/sysv/linux/tile/init-first.c +++ b/sysdeps/unix/sysv/linux/tile/init-first.c @@ -19,21 +19,27 @@ #include #include -struct syscall_return_value (*__vdso_gettimeofday) (struct timeval *, void *) +struct syscall_return_value (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, + void *) attribute_hidden; -struct syscall_return_value (*__vdso_clock_gettime) (clockid_t, - struct timespec *) +struct syscall_return_value (*VDSO_SYMBOL(clock_gettime)) (clockid_t, + struct timespec *) __attribute__ ((nocommon)); -strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden) static inline void _libc_vdso_platform_setup (void) { PREPARE_VERSION (linux26, "LINUX_2.6", 61765110); - __vdso_gettimeofday = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26); - __vdso_clock_gettime = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26); + + void *p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26); + PTR_MANGLE (p); + VDSO_SYMBOL (gettimeofday) = p; + + p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26); + PTR_MANGLE (p); + VDSO_SYMBOL (clock_gettime) = p; } #define VDSO_SETUP _libc_vdso_platform_setup diff --git a/sysdeps/unix/sysv/linux/tile/libc-vdso.h b/sysdeps/unix/sysv/linux/tile/libc-vdso.h index 44f828630f..2f5b23d34f 100644 --- a/sysdeps/unix/sysv/linux/tile/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/tile/libc-vdso.h @@ -22,19 +22,21 @@ #ifdef SHARED +#include + struct syscall_return_value { long int value; long int error; }; -extern struct syscall_return_value (*__vdso_gettimeofday) (struct timeval *, - void *) +extern struct syscall_return_value (*VDSO_SYMBOL (gettimeofday)) (struct + timeval *, + void *) attribute_hidden; -extern struct syscall_return_value (*__vdso_clock_gettime) (clockid_t, - struct timespec *); - +extern struct syscall_return_value (*VDSO_SYMBOL (clock_gettime)) (clockid_t, + struct + timespec *); #endif - #endif /* _LIBC_VDSO_H */ diff --git a/sysdeps/unix/sysv/linux/tile/sysdep.h b/sysdeps/unix/sysv/linux/tile/sysdep.h index 64c8920645..30d52e32c9 100644 --- a/sysdeps/unix/sysv/linux/tile/sysdep.h +++ b/sysdeps/unix/sysv/linux/tile/sysdep.h @@ -202,71 +202,19 @@ "=R02" (_clobber_r2), "=R03" (_clobber_r3), "=R04" (_clobber_r4), \ "=R05" (_clobber_r5), "=R10" (_clobber_r10) -/* 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; \ - \ - __typeof (__vdso_##name) vdsop = __vdso_##name; \ - if (vdsop != NULL) \ - { \ - 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) \ - 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; \ - }) -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - ({ \ - __label__ out; \ - long int v_ret; \ - \ - __typeof (__vdso_##name) vdsop = __vdso_##name; \ - if (vdsop != NULL) \ - { \ - 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; \ - } \ - v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \ - out: \ - v_ret; \ - }) -# else -# define INLINE_VSYSCALL(name, nr, args...) \ - INLINE_SYSCALL (name, nr, ##args) -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL (name, err, nr, ##args) -# endif -#endif /* not __ASSEMBLER__ */ +#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ + ({ \ + struct syscall_return_value rv = funcptr (args); \ + err = rv.error; \ + rv.value; \ + }) /* List of system calls which are supported as vsyscalls. */ #define HAVE_CLOCK_GETTIME_VSYSCALL 1 +#endif /* __ASSEMBLER__ */ + /* Pointer mangling support. */ #if IS_IN (rtld) /* We cannot use the thread descriptor because in ld.so we use setjmp diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c index 25616493cd..0e5f513f3d 100644 --- a/sysdeps/unix/sysv/linux/timespec_get.c +++ b/sysdeps/unix/sysv/linux/timespec_get.c @@ -18,31 +18,21 @@ #include #include -#ifndef HAVE_CLOCK_GETTIME_VSYSCALL -# undef INTERNAL_VSYSCALL -# define INTERNAL_VSYSCALL INTERNAL_SYSCALL -#else -# include +#ifdef HAVE_CLOCK_GETTIME_VSYSCALL +# define HAVE_VSYSCALL #endif - -#ifndef INTERNAL_GETTIME -# define INTERNAL_GETTIME(id, tp) \ - INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp) -#endif - +#include /* Set TS to calendar time based in time base BASE. */ int -timespec_get (ts, base) - struct timespec *ts; - int base; +timespec_get (struct timespec *ts, int base) { switch (base) { int res; INTERNAL_SYSCALL_DECL (err); case TIME_UTC: - res = INTERNAL_GETTIME (CLOCK_REALTIME, ts); + res = INTERNAL_VSYSCALL (clock_gettime, err, 2, CLOCK_REALTIME, ts); if (INTERNAL_SYSCALL_ERROR_P (res, err)) return 0; break; diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h index 79b6411d7e..fea9c2b7a1 100644 --- a/sysdeps/unix/sysv/linux/x86/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h @@ -24,7 +24,9 @@ #ifdef SHARED -extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) +# include + +extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *) attribute_hidden; #endif diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c index 25c38e4a8d..b7bdbd17ba 100644 --- a/sysdeps/unix/sysv/linux/x86_64/init-first.c +++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c @@ -22,9 +22,10 @@ # include # include -long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) +long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *) + attribute_hidden; +long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *) attribute_hidden; -long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden; extern long int __syscall_clock_gettime (clockid_t, struct timespec *); @@ -38,7 +39,7 @@ __vdso_platform_setup (void) if (p == NULL) p = __syscall_clock_gettime; PTR_MANGLE (p); - __vdso_clock_gettime = p; + VDSO_SYMBOL(clock_gettime) = p; p = _dl_vdso_vsym ("__vdso_getcpu", &linux26); /* If the vDSO is not available we fall back on the old vsyscall. */ @@ -46,7 +47,7 @@ __vdso_platform_setup (void) if (p == NULL) p = (void *) VSYSCALL_ADDR_vgetcpu; PTR_MANGLE (p); - __vdso_getcpu = p; + VDSO_SYMBOL(getcpu) = p; } # define VDSO_SETUP __vdso_platform_setup diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 3dbd7d2be4..cc6609347e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -252,61 +252,6 @@ # undef INTERNAL_SYSCALL_ERRNO # define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) -# ifdef SHARED -# define INLINE_VSYSCALL(name, nr, args...) \ - ({ \ - __label__ out; \ - __label__ iserr; \ - INTERNAL_SYSCALL_DECL (sc_err); \ - long int sc_ret; \ - \ - __typeof (__vdso_##name) vdsop = __vdso_##name; \ - PTR_DEMANGLE (vdsop); \ - if (vdsop != NULL) \ - { \ - sc_ret = vdsop (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; \ - }) -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - ({ \ - __label__ out; \ - long int v_ret; \ - \ - __typeof (__vdso_##name) vdsop = __vdso_##name; \ - PTR_DEMANGLE (vdsop); \ - if (vdsop != NULL) \ - { \ - v_ret = vdsop (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 INLINE_VSYSCALL(name, nr, args...) \ - INLINE_SYSCALL (name, nr, ##args) -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL (name, err, nr, ##args) -# endif - # define LOAD_ARGS_0() # define LOAD_REGS_0 # define ASM_ARGS_0