From 58e75db47160bc7bcac2ae98a7a8660b8fce35c9 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 16 Apr 2014 02:33:29 -0400 Subject: add working vdso clock_gettime support, including static linking the vdso symbol lookup code is based on the original 2011 patch by Nicholas J. Kain, with some streamlining, pointer arithmetic fixes, and one symbol version matching fix. on the consumer side (clock_gettime), per-arch macros for the particular symbol name and version to lookup are added in syscall_arch.h, and no vdso code is pulled in on archs which do not define these macros. at this time, vdso is enabled only on x86_64. the vdso support at the dynamic linker level is no longer useful to libc, but is left in place for the sake of debuggers (which may need the vdso in the link map to find its functions) and possibly use with dlsym. --- src/time/clock_gettime.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/time') diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c index ce9f2209..799251d8 100644 --- a/src/time/clock_gettime.c +++ b/src/time/clock_gettime.c @@ -3,6 +3,7 @@ #include #include "syscall.h" #include "libc.h" +#include "atomic.h" static int sc_clock_gettime(clockid_t clk, struct timespec *ts) { @@ -20,14 +21,21 @@ static int sc_clock_gettime(clockid_t clk, struct timespec *ts) return -1; } -weak_alias(sc_clock_gettime, __vdso_clock_gettime); - -int (*__cgt)(clockid_t, struct timespec *) = __vdso_clock_gettime; +void *__vdsosym(const char *, const char *); int __clock_gettime(clockid_t clk, struct timespec *ts) { - /* Conditional is to make this work prior to dynamic linking */ - return __cgt ? __cgt(clk, ts) : sc_clock_gettime(clk, ts); +#ifdef VDSO_CGT_SYM + static int (*cgt)(clockid_t, struct timespec *); + if (!cgt) { + void *f = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM); + if (!f) f = (void *)sc_clock_gettime; + a_cas_p(&cgt, 0, f); + } + return cgt(clk, ts); +#else + return sc_clock_gettime(clk, ts); +#endif } weak_alias(__clock_gettime, clock_gettime); -- cgit v1.2.1