aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/gettimeofday.c20
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/time.c20
3 files changed, 44 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 69d8974..9f766c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-01-16 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+
+ [BZ#16430]
+ * sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+ (__GI___gettimeofday): Alias for a different internal symbol to avoid
+ local calls issues by not having a PLT stub required for IFUNC calls.
+ * sysdeps/unix/sysv/linux/powerpc/time.c (__GI_time): Likewise.
+
2014-01-16 Joseph Myers <joseph@codesourcery.com>
* math/test-fpucw-ieee.c: Use <> in #include of test-fpucw.c.
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 29a5e08..2085b68 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -44,8 +44,24 @@ 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\n"
- "__GI___gettimeofday = __gettimeofday");
+asm (".globl __GI___gettimeofday");
+
+/* __GI___gettimeofday 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___gettimeofday = __gettimeofday");
+#else
+int
+__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+}
+asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
+#endif
#else
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index 089d0b6..023bc02 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -54,8 +54,24 @@ 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