diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/time.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/time.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c index 2d77ecec9b..9f54d97246 100644 --- a/sysdeps/unix/sysv/linux/powerpc/time.c +++ b/sysdeps/unix/sysv/linux/powerpc/time.c @@ -1,5 +1,5 @@ /* time system call for Linux/PowerPC. - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013-2014 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 @@ -45,17 +45,36 @@ time_syscall (time_t *t) void * time_ifunc (void) { + PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565); + /* If the vDSO is not available we fall back to the syscall. */ - return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time) - : time_syscall); + void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615); + return (vdso_time ? VDSO_IFUNC_RET (vdso_time) + : (void*)time_syscall); } asm (".type time, %gnu_indirect_function"); /* This is doing "libc_hidden_def (time)" but the compiler won't * let us do it in C because it doesn't know we're defining time * here in this file. */ -asm (".globl __GI_time\n" - "__GI_time = time"); +asm (".globl __GI_time"); + +/* __GI_time is defined as hidden and for ppc32 it enables the + compiler make a local call (symbol@local) for internal GLIBC usage. It + means the PLT won't be used and the ifunc resolver will be called directly. + For ppc64 a call to a function in another translation unit might use a + different toc pointer thus disallowing direct branchess and making internal + ifuncs calls safe. */ +#ifdef __powerpc64__ +asm ("__GI_time = time"); +#else +time_t +__time_vsyscall (time_t *t) +{ + return INLINE_VSYSCALL (time, 1, t); +} +asm ("__GI_time = __time_vsyscall"); +#endif #else |