mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 15:20:10 +00:00
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.
This commit is contained in:
parent
829a679fac
commit
f534255e4d
121
ChangeLog
121
ChangeLog
@ -1,3 +1,124 @@
|
|||||||
|
2015-05-26 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
* 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 <andrew.senkevich@intel.com>
|
2015-05-25 Andrew Senkevich <andrew.senkevich@intel.com>
|
||||||
|
|
||||||
* elf/Makefile (localplt-built-dso): libmvec added to localplt test.
|
* elf/Makefile (localplt-built-dso): libmvec added to localplt test.
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
#undef __gettimeofday
|
#undef __gettimeofday
|
||||||
|
|
||||||
#include <libc-vdso.h>
|
#define HAVE_VSYSCALL
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
/* Get the current time of day and timezone information,
|
/* Get the current time of day and timezone information,
|
||||||
putting it into *tv and *tz. If tz is null, *tz is not filled.
|
putting it into *tv and *tz. If tz is null, *tz is not filled.
|
||||||
|
@ -23,18 +23,26 @@
|
|||||||
# undef __clock_getres
|
# undef __clock_getres
|
||||||
# include <libc-vdso.h>
|
# include <libc-vdso.h>
|
||||||
|
|
||||||
void (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden;
|
int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
|
||||||
void (*__vdso_clock_gettime) (clockid_t, struct timespec *);
|
int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
|
||||||
void (*__vdso_clock_getres) (clockid_t, struct timespec *);
|
int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_libc_vdso_platform_setup (void)
|
_libc_vdso_platform_setup (void)
|
||||||
{
|
{
|
||||||
PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537);
|
PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537);
|
||||||
|
|
||||||
__vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639);
|
void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639);
|
||||||
__vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639);
|
PTR_MANGLE (p);
|
||||||
__vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639);
|
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
|
# define VDSO_SETUP _libc_vdso_platform_setup
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
|
||||||
extern void (*__vdso_gettimeofday) (struct timeval *, void *)
|
# include <sysdep-vdso.h>
|
||||||
|
|
||||||
|
extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
extern void (*__vdso_clock_gettime) (clockid_t, struct timespec *);
|
extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
|
||||||
extern void (*__vdso_clock_getres) (clockid_t, struct timespec *);
|
extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -151,75 +151,11 @@
|
|||||||
|
|
||||||
#else /* not __ASSEMBLER__ */
|
#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. */
|
/* List of system calls which are supported as vsyscalls. */
|
||||||
# define HAVE_CLOCK_GETRES_VSYSCALL 1
|
# define HAVE_CLOCK_GETRES_VSYSCALL 1
|
||||||
# define HAVE_CLOCK_GETTIME_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
|
/* Define a macro which expands into the inline wrapper code for a system
|
||||||
call. */
|
call. */
|
||||||
# undef INLINE_SYSCALL
|
# undef INLINE_SYSCALL
|
||||||
|
@ -21,14 +21,10 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "kernel-posix-cpu-timers.h"
|
#include "kernel-posix-cpu-timers.h"
|
||||||
|
|
||||||
#ifndef HAVE_CLOCK_GETRES_VSYSCALL
|
#ifdef HAVE_CLOCK_GETRES_VSYSCALL
|
||||||
# undef INTERNAL_VSYSCALL
|
# define HAVE_VSYSCALL
|
||||||
# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
|
|
||||||
# undef INLINE_VSYSCALL
|
|
||||||
# define INLINE_VSYSCALL INLINE_SYSCALL
|
|
||||||
#else
|
|
||||||
# include <libc-vdso.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
#define SYSCALL_GETRES \
|
#define SYSCALL_GETRES \
|
||||||
retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, res); \
|
retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, res); \
|
||||||
|
@ -21,23 +21,10 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "kernel-posix-cpu-timers.h"
|
#include "kernel-posix-cpu-timers.h"
|
||||||
|
|
||||||
#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
|
#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
|
||||||
# undef INTERNAL_VSYSCALL
|
# define HAVE_VSYSCALL
|
||||||
# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
|
|
||||||
# undef INLINE_VSYSCALL
|
|
||||||
# define INLINE_VSYSCALL INLINE_SYSCALL
|
|
||||||
#else
|
|
||||||
# include <libc-vdso.h>
|
|
||||||
#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)
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
/* The REALTIME and MONOTONIC clock are definitely supported in the
|
/* The REALTIME and MONOTONIC clock are definitely supported in the
|
||||||
kernel. */
|
kernel. */
|
||||||
@ -45,7 +32,7 @@
|
|||||||
SYSDEP_GETTIME_CPUTIME; \
|
SYSDEP_GETTIME_CPUTIME; \
|
||||||
case CLOCK_REALTIME: \
|
case CLOCK_REALTIME: \
|
||||||
case CLOCK_MONOTONIC: \
|
case CLOCK_MONOTONIC: \
|
||||||
retval = SYSCALL_GETTIME (clock_id, tp); \
|
retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \
|
||||||
break
|
break
|
||||||
|
|
||||||
/* We handled the REALTIME clock here. */
|
/* We handled the REALTIME clock here. */
|
||||||
@ -53,7 +40,7 @@
|
|||||||
#define HANDLED_CPUTIME 1
|
#define HANDLED_CPUTIME 1
|
||||||
|
|
||||||
#define SYSDEP_GETTIME_CPU(clock_id, tp) \
|
#define SYSDEP_GETTIME_CPU(clock_id, tp) \
|
||||||
retval = SYSCALL_GETTIME (clock_id, tp); \
|
retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \
|
||||||
break
|
break
|
||||||
#define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */
|
#define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
# include <time.h>
|
# include <time.h>
|
||||||
# include <sysdep.h>
|
# include <sysdep.h>
|
||||||
# include <dl-vdso.h>
|
# include <dl-vdso.h>
|
||||||
# include <libc-vdso.h>
|
# include <sysdep-vdso.h>
|
||||||
|
|
||||||
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
|
long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
static long int
|
static long int
|
||||||
@ -41,7 +41,7 @@ __vdso_platform_setup (void)
|
|||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = clock_gettime_syscall;
|
p = clock_gettime_syscall;
|
||||||
PTR_MANGLE (p);
|
PTR_MANGLE (p);
|
||||||
__vdso_clock_gettime = p;
|
VDSO_SYMBOL (clock_gettime) = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
# define VDSO_SETUP __vdso_platform_setup
|
# define VDSO_SETUP __vdso_platform_setup
|
||||||
|
@ -23,17 +23,19 @@
|
|||||||
# undef __clock_getres
|
# undef __clock_getres
|
||||||
# include <libc-vdso.h>
|
# include <libc-vdso.h>
|
||||||
|
|
||||||
void *__vdso_gettimeofday attribute_hidden;
|
int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
|
||||||
void *__vdso_clock_gettime;
|
attribute_hidden;
|
||||||
void *__vdso_clock_getres;
|
int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
|
||||||
void *__vdso_get_tbfreq;
|
int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
|
||||||
void *__vdso_getcpu;
|
unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
|
||||||
void *__vdso_time;
|
int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *);
|
||||||
|
time_t (*VDSO_SYMBOL(time)) (time_t *);
|
||||||
|
|
||||||
#if defined(__PPC64__) || defined(__powerpc64__)
|
#if defined(__PPC64__) || defined(__powerpc64__)
|
||||||
void *__vdso_sigtramp_rt64;
|
void *VDSO_SYMBOL(sigtramp_rt64);
|
||||||
#else
|
#else
|
||||||
void *__vdso_sigtramp32;
|
void *VDSO_SYMBOL(sigtramp32);
|
||||||
void *__vdso_sigtramp_rt32;
|
void *VDSO_SYMBOL(sigtramp_rt32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -41,26 +43,42 @@ _libc_vdso_platform_setup (void)
|
|||||||
{
|
{
|
||||||
PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
|
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
|
/* PPC64 uses only one signal trampoline symbol, while PPC32 will use
|
||||||
two depending if SA_SIGINFO is used (__kernel_sigtramp_rt32) or not
|
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__)
|
#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
|
#else
|
||||||
__vdso_sigtramp32 = _dl_vdso_vsym ("__kernel_sigtramp32", &linux2615);
|
VDSO_SYMBOL(sigtramp32) = _dl_vdso_vsym ("__kernel_sigtramp32", &linux2615);
|
||||||
__vdso_sigtramp_rt32 = _dl_vdso_vsym ("__kernel_sigtramp_rt32", &linux2615);
|
VDSO_SYMBOL(sigtramp_rt32) = _dl_vdso_vsym ("__kernel_sigtramp_rt32",
|
||||||
|
&linux2615);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,23 +22,21 @@
|
|||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
|
||||||
extern void *__vdso_gettimeofday attribute_hidden;
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
extern void *__vdso_clock_gettime;
|
extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
|
||||||
|
attribute_hidden;
|
||||||
extern void *__vdso_clock_getres;
|
extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
|
||||||
|
extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
|
||||||
extern void *__vdso_get_tbfreq;
|
extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
|
||||||
|
extern int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *);
|
||||||
extern void *__vdso_getcpu;
|
extern time_t (*VDSO_SYMBOL(time)) (time_t *);
|
||||||
|
|
||||||
extern void *__vdso_time;
|
|
||||||
|
|
||||||
#if defined(__PPC64__) || defined(__powerpc64__)
|
#if defined(__PPC64__) || defined(__powerpc64__)
|
||||||
extern void *__vdso_sigtramp_rt64;
|
extern void *VDSO_SYMBOL(sigtramp_rt64);
|
||||||
#else
|
#else
|
||||||
extern void *__vdso_sigtramp32;
|
extern void *VDSO_SYMBOL(sigtramp32);
|
||||||
extern void *__vdso_sigtramp_rt32;
|
extern void *VDSO_SYMBOL(sigtramp_rt32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2
|
#if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2
|
||||||
|
@ -50,77 +50,6 @@
|
|||||||
|
|
||||||
# include <errno.h>
|
# 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
|
/* 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
|
call. This use is for internal calls that do not need to handle errors
|
||||||
normally. It will never touch errno.
|
normally. It will never touch errno.
|
||||||
@ -128,7 +57,7 @@
|
|||||||
function call, with the exception of LR (which is needed for the
|
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
|
"sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
|
||||||
an error return status). */
|
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 void *r0 __asm__ ("r0"); \
|
||||||
register long int r3 __asm__ ("r3"); \
|
register long int r3 __asm__ ("r3"); \
|
||||||
@ -155,6 +84,9 @@
|
|||||||
rval; \
|
rval; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
|
||||||
|
INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, nr, long int, args)
|
||||||
|
|
||||||
# undef INLINE_SYSCALL
|
# undef INLINE_SYSCALL
|
||||||
# define INLINE_SYSCALL(name, nr, args...) \
|
# define INLINE_SYSCALL(name, nr, args...) \
|
||||||
({ \
|
({ \
|
||||||
@ -216,6 +148,25 @@
|
|||||||
# undef INTERNAL_SYSCALL_ERRNO
|
# undef INTERNAL_SYSCALL_ERRNO
|
||||||
# define INTERNAL_SYSCALL_ERRNO(val, err) (val)
|
# 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) \
|
# define LOADARGS_0(name, dummy) \
|
||||||
r0 = name
|
r0 = name
|
||||||
# define LOADARGS_1(name, __arg1) \
|
# define LOADARGS_1(name, __arg1) \
|
||||||
|
@ -61,74 +61,17 @@
|
|||||||
|
|
||||||
#endif /* __ASSEMBLER__ */
|
#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
|
/* This version is for internal uses when there is no desire
|
||||||
to set errno */
|
to set errno */
|
||||||
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \
|
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \
|
||||||
({ \
|
({ \
|
||||||
type sc_ret = ENOSYS; \
|
type sc_ret = ENOSYS; \
|
||||||
\
|
\
|
||||||
if (__vdso_##name != NULL) \
|
__typeof (__vdso_##name) vdsop = __vdso_##name; \
|
||||||
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args); \
|
PTR_DEMANGLE (vdsop); \
|
||||||
|
if (vdsop != NULL) \
|
||||||
|
sc_ret = \
|
||||||
|
INTERNAL_VSYSCALL_CALL_TYPE (vdsop, err, type, nr, ##args); \
|
||||||
else \
|
else \
|
||||||
err = 1 << 28; \
|
err = 1 << 28; \
|
||||||
sc_ret; \
|
sc_ret; \
|
||||||
@ -144,7 +87,7 @@
|
|||||||
gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
|
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. */
|
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 void *r0 __asm__ ("r0"); \
|
||||||
register long int r3 __asm__ ("r3"); \
|
register long int r3 __asm__ ("r3"); \
|
||||||
@ -168,6 +111,9 @@
|
|||||||
rval; \
|
rval; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
|
||||||
|
INTERNAL_VSYSCALL_CALL_TYPE(funcptr, err, long int, nr, args)
|
||||||
|
|
||||||
#undef INLINE_SYSCALL
|
#undef INLINE_SYSCALL
|
||||||
|
|
||||||
/* This version is for kernels that implement system calls that
|
/* This version is for kernels that implement system calls that
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
|
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
#include <libc-vdso.h>
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sched_getcpu (void)
|
sched_getcpu (void)
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <hp-timing.h>
|
#include <hp-timing.h>
|
||||||
|
|
||||||
#include <libc-vdso.h>
|
#define HAVE_VSYSCALL
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
/* Get the current time of day and timezone information,
|
/* Get the current time of day and timezone information,
|
||||||
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
|
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
|
||||||
|
@ -23,15 +23,14 @@
|
|||||||
# undef __clock_getres
|
# undef __clock_getres
|
||||||
# include <libc-vdso.h>
|
# include <libc-vdso.h>
|
||||||
|
|
||||||
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));
|
__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));
|
__attribute__ ((nocommon));
|
||||||
strong_alias (__vdso_clock_getres, __GI___vdso_clock_getres attribute_hidden)
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -39,9 +38,17 @@ _libc_vdso_platform_setup (void)
|
|||||||
{
|
{
|
||||||
PREPARE_VERSION (linux2629, "LINUX_2.6.29", 123718585);
|
PREPARE_VERSION (linux2629, "LINUX_2.6.29", 123718585);
|
||||||
|
|
||||||
__vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2629);
|
void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2629);
|
||||||
__vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2629);
|
PTR_MANGLE (p);
|
||||||
__vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2629);
|
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
|
# define VDSO_SETUP _libc_vdso_platform_setup
|
||||||
|
@ -22,12 +22,14 @@
|
|||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
|
||||||
extern long int (*__vdso_gettimeofday) (struct timeval *, void *)
|
#include <sysdep-vdso.h>
|
||||||
attribute_hidden;
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
@ -282,77 +282,22 @@
|
|||||||
#define HAVE_CLOCK_GETRES_VSYSCALL 1
|
#define HAVE_CLOCK_GETRES_VSYSCALL 1
|
||||||
#define HAVE_CLOCK_GETTIME_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
|
/* This version is for internal uses when there is no desire
|
||||||
to set errno */
|
to set errno */
|
||||||
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
|
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
|
||||||
({ \
|
({ \
|
||||||
long int _ret = ENOSYS; \
|
long int _ret = ENOSYS; \
|
||||||
\
|
\
|
||||||
if (__vdso_##name != NULL) \
|
__typeof (__vdso_##name) vdsop = __vdso_##name; \
|
||||||
_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
|
PTR_DEMANGLE (vdsop); \
|
||||||
|
if (vdsop != NULL) \
|
||||||
|
_ret = INTERNAL_VSYSCALL_CALL (vdsop, err, nr, ##args); \
|
||||||
else \
|
else \
|
||||||
err = 1 << 28; \
|
err = 1 << 28; \
|
||||||
_ret; \
|
_ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define INTERNAL_VSYSCALL_NCS(fn, err, nr, args...) \
|
#define INTERNAL_VSYSCALL_CALL(fn, err, nr, args...) \
|
||||||
({ \
|
({ \
|
||||||
DECLARGS_##nr(args) \
|
DECLARGS_##nr(args) \
|
||||||
register long _ret asm("2"); \
|
register long _ret asm("2"); \
|
||||||
|
@ -288,77 +288,22 @@
|
|||||||
#define HAVE_CLOCK_GETRES_VSYSCALL 1
|
#define HAVE_CLOCK_GETRES_VSYSCALL 1
|
||||||
#define HAVE_CLOCK_GETTIME_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
|
/* This version is for internal uses when there is no desire
|
||||||
to set errno */
|
to set errno */
|
||||||
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
|
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
|
||||||
({ \
|
({ \
|
||||||
long int _ret = ENOSYS; \
|
long int _ret = ENOSYS; \
|
||||||
\
|
\
|
||||||
if (__vdso_##name != NULL) \
|
__typeof (__vdso_##name) vdsop = __vdso_##name; \
|
||||||
_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
|
PTR_DEMANGLE (vdsop); \
|
||||||
|
if (vdsop != NULL) \
|
||||||
|
_ret = INTERNAL_VSYSCALL_CALL (vdsop, err, nr, ##args); \
|
||||||
else \
|
else \
|
||||||
err = 1 << 28; \
|
err = 1 << 28; \
|
||||||
_ret; \
|
_ret; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define INTERNAL_VSYSCALL_NCS(fn, err, nr, args...) \
|
#define INTERNAL_VSYSCALL_CALL(fn, err, nr, args...) \
|
||||||
({ \
|
({ \
|
||||||
DECLARGS_##nr(args) \
|
DECLARGS_##nr(args) \
|
||||||
register long _ret asm("2"); \
|
register long _ret asm("2"); \
|
||||||
|
98
sysdeps/unix/sysv/linux/sysdep-vdso.h
Normal file
98
sysdeps/unix/sysv/linux/sysdep-vdso.h
Normal file
@ -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
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#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 <libc-vdso.h>
|
||||||
|
|
||||||
|
# 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 */
|
@ -19,7 +19,9 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <libc-vdso.h>
|
|
||||||
|
#define HAVE_VSYSCALL
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
__gettimeofday (struct timeval *tv, struct timezone *tz)
|
__gettimeofday (struct timeval *tv, struct timezone *tz)
|
||||||
|
@ -19,21 +19,27 @@
|
|||||||
#include <dl-vdso.h>
|
#include <dl-vdso.h>
|
||||||
#include <libc-vdso.h>
|
#include <libc-vdso.h>
|
||||||
|
|
||||||
struct syscall_return_value (*__vdso_gettimeofday) (struct timeval *, void *)
|
struct syscall_return_value (*VDSO_SYMBOL(gettimeofday)) (struct timeval *,
|
||||||
|
void *)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
struct syscall_return_value (*__vdso_clock_gettime) (clockid_t,
|
struct syscall_return_value (*VDSO_SYMBOL(clock_gettime)) (clockid_t,
|
||||||
struct timespec *)
|
struct timespec *)
|
||||||
__attribute__ ((nocommon));
|
__attribute__ ((nocommon));
|
||||||
strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_libc_vdso_platform_setup (void)
|
_libc_vdso_platform_setup (void)
|
||||||
{
|
{
|
||||||
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
|
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
|
#define VDSO_SETUP _libc_vdso_platform_setup
|
||||||
|
@ -22,19 +22,21 @@
|
|||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
|
|
||||||
struct syscall_return_value
|
struct syscall_return_value
|
||||||
{
|
{
|
||||||
long int value;
|
long int value;
|
||||||
long int error;
|
long int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct syscall_return_value (*__vdso_gettimeofday) (struct timeval *,
|
extern struct syscall_return_value (*VDSO_SYMBOL (gettimeofday)) (struct
|
||||||
void *)
|
timeval *,
|
||||||
|
void *)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
extern struct syscall_return_value (*__vdso_clock_gettime) (clockid_t,
|
extern struct syscall_return_value (*VDSO_SYMBOL (clock_gettime)) (clockid_t,
|
||||||
struct timespec *);
|
struct
|
||||||
|
timespec *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _LIBC_VDSO_H */
|
#endif /* _LIBC_VDSO_H */
|
||||||
|
@ -202,71 +202,19 @@
|
|||||||
"=R02" (_clobber_r2), "=R03" (_clobber_r3), "=R04" (_clobber_r4), \
|
"=R02" (_clobber_r2), "=R03" (_clobber_r3), "=R04" (_clobber_r4), \
|
||||||
"=R05" (_clobber_r5), "=R10" (_clobber_r10)
|
"=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 INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
|
||||||
# define INLINE_VSYSCALL(name, nr, args...) \
|
({ \
|
||||||
INLINE_SYSCALL (name, nr, ##args)
|
struct syscall_return_value rv = funcptr (args); \
|
||||||
# define INTERNAL_VSYSCALL(name, err, nr, args...) \
|
err = rv.error; \
|
||||||
INTERNAL_SYSCALL (name, err, nr, ##args)
|
rv.value; \
|
||||||
# endif
|
})
|
||||||
#endif /* not __ASSEMBLER__ */
|
|
||||||
|
|
||||||
/* List of system calls which are supported as vsyscalls. */
|
/* List of system calls which are supported as vsyscalls. */
|
||||||
#define HAVE_CLOCK_GETTIME_VSYSCALL 1
|
#define HAVE_CLOCK_GETTIME_VSYSCALL 1
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
/* Pointer mangling support. */
|
/* Pointer mangling support. */
|
||||||
#if IS_IN (rtld)
|
#if IS_IN (rtld)
|
||||||
/* We cannot use the thread descriptor because in ld.so we use setjmp
|
/* We cannot use the thread descriptor because in ld.so we use setjmp
|
||||||
|
@ -18,31 +18,21 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
|
|
||||||
#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
|
#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
|
||||||
# undef INTERNAL_VSYSCALL
|
# define HAVE_VSYSCALL
|
||||||
# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
|
|
||||||
#else
|
|
||||||
# include <libc-vdso.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <sysdep-vdso.h>
|
||||||
#ifndef INTERNAL_GETTIME
|
|
||||||
# define INTERNAL_GETTIME(id, tp) \
|
|
||||||
INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Set TS to calendar time based in time base BASE. */
|
/* Set TS to calendar time based in time base BASE. */
|
||||||
int
|
int
|
||||||
timespec_get (ts, base)
|
timespec_get (struct timespec *ts, int base)
|
||||||
struct timespec *ts;
|
|
||||||
int base;
|
|
||||||
{
|
{
|
||||||
switch (base)
|
switch (base)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
INTERNAL_SYSCALL_DECL (err);
|
INTERNAL_SYSCALL_DECL (err);
|
||||||
case TIME_UTC:
|
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))
|
if (INTERNAL_SYSCALL_ERROR_P (res, err))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
|
||||||
extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
|
# include <sysdep-vdso.h>
|
||||||
|
|
||||||
|
extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,9 +22,10 @@
|
|||||||
# include <dl-vdso.h>
|
# include <dl-vdso.h>
|
||||||
# include <libc-vdso.h>
|
# include <libc-vdso.h>
|
||||||
|
|
||||||
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;
|
attribute_hidden;
|
||||||
long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
|
|
||||||
|
|
||||||
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
|
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ __vdso_platform_setup (void)
|
|||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = __syscall_clock_gettime;
|
p = __syscall_clock_gettime;
|
||||||
PTR_MANGLE (p);
|
PTR_MANGLE (p);
|
||||||
__vdso_clock_gettime = p;
|
VDSO_SYMBOL(clock_gettime) = p;
|
||||||
|
|
||||||
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
|
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
|
||||||
/* If the vDSO is not available we fall back on the old vsyscall. */
|
/* If the vDSO is not available we fall back on the old vsyscall. */
|
||||||
@ -46,7 +47,7 @@ __vdso_platform_setup (void)
|
|||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = (void *) VSYSCALL_ADDR_vgetcpu;
|
p = (void *) VSYSCALL_ADDR_vgetcpu;
|
||||||
PTR_MANGLE (p);
|
PTR_MANGLE (p);
|
||||||
__vdso_getcpu = p;
|
VDSO_SYMBOL(getcpu) = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
# define VDSO_SETUP __vdso_platform_setup
|
# define VDSO_SETUP __vdso_platform_setup
|
||||||
|
@ -252,61 +252,6 @@
|
|||||||
# undef INTERNAL_SYSCALL_ERRNO
|
# undef INTERNAL_SYSCALL_ERRNO
|
||||||
# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
|
# 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_ARGS_0()
|
||||||
# define LOAD_REGS_0
|
# define LOAD_REGS_0
|
||||||
# define ASM_ARGS_0
|
# define ASM_ARGS_0
|
||||||
|
Loading…
Reference in New Issue
Block a user