1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-07 06:43:00 +03:00

ppc: Use libc_ifunc macro for time, gettimeofday.

This patch uses the libc_ifunc_hidden macro to create already existing ifunc functions
time and gettimeofday on power. This way, the libc_hidden_def macro can be used
instead of inline assemblies.
On ppc32, the __GI_* symbols do not target the ifunc symbol and thus the
redirection construct has to be applied here.

ChangeLog:

	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (__gettimeofday):
	Use libc_ifunc_hidden and libc_hidden_def macro. Redirect ifunced function
	in header for using it as type for ifunc function because __GI_* symbols
	for ppc32 do not target the ifunc symbols.
	* sysdeps/unix/sysv/linux/powerpc/time.c (time): Likewise.
This commit is contained in:
Stefan Liebler
2016-10-07 09:56:47 +02:00
parent e23faea6ae
commit a4d7fe35cd
3 changed files with 73 additions and 62 deletions

View File

@@ -1,3 +1,11 @@
2016-10-07 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (__gettimeofday):
Use libc_ifunc_hidden and libc_hidden_def macro. Redirect ifunced function
in header for using it as type for ifunc function because __GI_* symbols
for ppc32 do not target the ifunc symbols.
* sysdeps/unix/sysv/linux/powerpc/time.c (time): Likewise.
2016-10-07 Stefan Liebler <stli@linux.vnet.ibm.com> 2016-10-07 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/x86/gettimeofday.c (__gettimeofday): * sysdeps/unix/sysv/linux/x86/gettimeofday.c (__gettimeofday):

View File

@@ -15,6 +15,11 @@
License along with the GNU C Library; if not, see License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#if defined SHARED && !defined __powerpc64__
# define __gettimeofday __redirect___gettimeofday
#else
# define __redirect___gettimeofday __gettimeofday
#endif
#include <sys/time.h> #include <sys/time.h>
@@ -24,47 +29,44 @@
# include <libc-vdso.h> # include <libc-vdso.h>
# include <dl-machine.h> # include <dl-machine.h>
void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday"); # ifndef __powerpc64__
# undef __gettimeofday
static int int
__gettimeofday_syscall (struct timeval *tv, struct timezone *tz) __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
{ {
return INLINE_SYSCALL (gettimeofday, 2, tv, tz); return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
} }
void *
gettimeofday_ifunc (void)
{
PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
/* If the vDSO is not available we fall back syscall. */
void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
: (void*)__gettimeofday_syscall);
}
asm (".type __gettimeofday, %gnu_indirect_function");
/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
let us do it in C because it doesn't know we're defining __gettimeofday
here in this file. */
asm (".globl __GI___gettimeofday");
/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the /* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
compiler make a local call (symbol@local) for internal GLIBC usage. It 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. 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 For ppc64 a call to a function in another translation unit might use a
different toc pointer thus disallowing direct branchess and making internal different toc pointer thus disallowing direct branchess and making internal
ifuncs calls safe. */ ifuncs calls safe. */
#ifdef __powerpc64__ # undef libc_hidden_def
asm ("__GI___gettimeofday = __gettimeofday"); # define libc_hidden_def(name) \
#else __hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday, \
int __gettimeofday_vsyscall);
__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
# endif /* !__powerpc64__ */
static int
__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
{ {
return INLINE_VSYSCALL (gettimeofday, 2, tv, tz); return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
} }
asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
#endif # define INIT_ARCH() \
PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565); \
void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
/* If the vDSO is not available we fall back syscall. */
libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
vdso_gettimeofday
? VDSO_IFUNC_RET (vdso_gettimeofday)
: (void *) __gettimeofday_syscall);
libc_hidden_def (__gettimeofday)
#else #else

View File

@@ -17,6 +17,11 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#ifdef SHARED #ifdef SHARED
# ifndef __powerpc64__
# define time __redirect_time
# else
# define __redirect_time time
# endif
# include <time.h> # include <time.h>
# include <sysdep.h> # include <sysdep.h>
@@ -24,7 +29,26 @@
# include <libc-vdso.h> # include <libc-vdso.h>
# include <dl-machine.h> # include <dl-machine.h>
void *time_ifunc (void) asm ("time"); # ifndef __powerpc64__
# undef time
time_t
__time_vsyscall (time_t *t)
{
return INLINE_VSYSCALL (time, 1, t);
}
/* __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. */
# undef libc_hidden_def
# define libc_hidden_def(name) \
__hidden_ver1 (__time_vsyscall, __GI_time, __time_vsyscall);
# endif /* !__powerpc64__ */
static time_t static time_t
time_syscall (time_t *t) time_syscall (time_t *t)
@@ -42,42 +66,19 @@ time_syscall (time_t *t)
return result; return result;
} }
void * # define INIT_ARCH() \
time_ifunc (void) PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565); \
{
PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
/* If the vDSO is not available we fall back to the syscall. */
void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615); 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 /* If the vDSO is not available we fall back to the syscall. */
* let us do it in C because it doesn't know we're defining time libc_ifunc_hidden (__redirect_time, time,
* here in this file. */ vdso_time
asm (".globl __GI_time"); ? VDSO_IFUNC_RET (vdso_time)
: (void *) time_syscall);
/* __GI_time is defined as hidden and for ppc32 it enables the libc_hidden_def (time)
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 #else
#include <sysdeps/posix/time.c> #include <sysdeps/posix/time.c>
#endif #endif /* !SHARED */