aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch227
-rw-r--r--meta/recipes-core/eglibc/eglibc_2.18.bb1
2 files changed, 228 insertions, 0 deletions
diff --git a/meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch b/meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch
new file mode 100644
index 0000000000..c2373c53cc
--- /dev/null
+++ b/meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch
@@ -0,0 +1,227 @@
+Upstream-Status: Backport
+
+Concatenated fix of PowerPC time related system calls in eglibc 2.18 taken
+from upstream glibc. Eglibc 2.17 does not have this issue and the patches are
+already part of 2.19.
+This compilation includes the following committs:
+
+
+PowerPC: Fix vDSO missing ODP entries
+
+author Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+ Thu, 7 Nov 2013 11:34:22 +0000 (05:34 -0600)
+
+This patch fixes the vDSO symbol used directed in IFUNC resolver where
+they do not have an associated ODP entry leading to undefined behavior
+in some cases. It adds an artificial OPD static entry to such cases
+and set its TOC to non 0 to avoid triggering lazy resolutions.
+
+
+Update copyright notices with scripts/update-copyrights
+
+author Allan McRae <allan@archlinux.org>
+ Wed, 1 Jan 2014 11:03:15 +0000 (21:03 +1000)
+
+((Only for files otherwise touched by this patch))
+
+
+PowerPC: Fix ftime gettimeofday internal call returning bogus data
+
+author Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+ Thu, 16 Jan 2014 12:53:18 +0000 (06:53 -0600)
+
+This patches fixes BZ#16430 by setting a different symbol for internal
+GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol
+is defined as hidden (which is the case for gettimeofday and time) the
+compiler will create local branches (symbol@local) and linker will not
+create PLT calls (required for IFUNC). This will leads to internal symbol
+calling the IFUNC resolver instead of the resolved symbol.
+For PPC64 this behavior does not occur because a call to a function in
+another translation unit might use a different toc pointer thus requiring
+a PLT call.
+
+
+PowerPC: Fix gettimeofday ifunc selection
+
+author Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+ Mon, 20 Jan 2014 18:29:51 +0000 (12:29 -0600)
+
+The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
+__vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
+version used within GLIBC) to use the system call version instead of the vDSO one.
+This patch changes the check if vDSO is available to get its value directly
+instead of rely on __vdso_gettimeofday.
+
+This patch changes it by getting the vDSO value directly.
+
+It fixes BZ#16431.
+
+
+---
+diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+--- libc.orig/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
++++ libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+@@ -1,5 +1,5 @@
+ /* Resolve function pointers to VDSO functions.
+- Copyright (C) 2005-2013 Free Software Foundation, Inc.
++ Copyright (C) 2005-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
+@@ -34,12 +34,32 @@ extern void *__vdso_getcpu;
+
+ extern void *__vdso_time;
+
+-/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO
+- symbol. This works because _dl_vdso_vsym always return the function
+- address, and no vDSO symbols use the TOC or chain pointers from the OPD
+- so we can allow them to be garbage. */
+ #if defined(__PPC64__) || defined(__powerpc64__)
+-#define VDSO_IFUNC_RET(value) ((void *) &(value))
++/* The correct solution is for _dl_vdso_vsym to return the address of the OPD
++ for the kernel VDSO function. That address would then be stored in the
++ __vdso_* variables and returned as the result of the IFUNC resolver function.
++ Yet, the kernel does not contain any OPD entries for the VDSO functions
++ (incomplete implementation). However, PLT relocations for IFUNCs still expect
++ the address of an OPD to be returned from the IFUNC resolver function (since
++ PLT entries on PPC64 are just copies of OPDs). The solution for now is to
++ create an artificial static OPD for each VDSO function returned by a resolver
++ function. The TOC value is set to a non-zero value to avoid triggering lazy
++ symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
++ sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None
++ of the kernel VDSO routines use the TOC or AUX values so any non-zero value
++ will work. Note that function pointer comparisons will not use this artificial
++ static OPD since those are resolved via ADDR64 relocations and will point at
++ the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations
++ are processed immediately at startup the resolver functions and this code need
++ not be thread-safe, but if the caller writes to a PLT slot it must do so in a
++ thread-safe manner with all the required barriers. */
++#define VDSO_IFUNC_RET(value) \
++ ({ \
++ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
++ vdso_opd.fd_func = (Elf64_Addr)value; \
++ &vdso_opd; \
++ })
++
+ #else
+ #define VDSO_IFUNC_RET(value) ((void *) (value))
+ #endif
+diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+--- libc.orig/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
++++ libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
++/* Copyright (C) 2005-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
+@@ -22,6 +22,7 @@
+
+ # include <dl-vdso.h>
+ # include <bits/libc-vdso.h>
++# include <dl-machine.h>
+
+ void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+@@ -34,17 +35,36 @@ __gettimeofday_syscall (struct timeval *
+ void *
+ gettimeofday_ifunc (void)
+ {
++ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
++
+ /* If the vDSO is not available we fall back syscall. */
+- return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday)
+- : __gettimeofday_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\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 -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/time.c libc/sysdeps/unix/sysv/linux/powerpc/time.c
+--- libc.orig/sysdeps/unix/sysv/linux/powerpc/time.c
++++ libc/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
+@@ -20,7 +20,9 @@
+
+ # include <time.h>
+ # include <sysdep.h>
++# include <dl-vdso.h>
+ # include <bits/libc-vdso.h>
++# include <dl-machine.h>
+
+ void *time_ifunc (void) asm ("time");
+
+@@ -43,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
+
diff --git a/meta/recipes-core/eglibc/eglibc_2.18.bb b/meta/recipes-core/eglibc/eglibc_2.18.bb
index 15e5eed3ff..43f43ae2b0 100644
--- a/meta/recipes-core/eglibc/eglibc_2.18.bb
+++ b/meta/recipes-core/eglibc/eglibc_2.18.bb
@@ -28,6 +28,7 @@ SRC_URI = "http://downloads.yoctoproject.org/releases/eglibc/eglibc-${PV}-svnr23
file://fix-tibetian-locales.patch \
file://0001-ARM-Pass-dl_hwcap-to-IFUNC-resolver.patch \
file://make-4.patch \
+ file://ppc-fix-time-related-syscalls.patch \
"
SRC_URI[md5sum] = "b395b021422a027d89884992e91734fc"
SRC_URI[sha256sum] = "15f564b45dc5dd65faf0875579e3447961ae61e876933384ae05d19328539ad4"