summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMats Kärrman <Mats.Karrman@tritech.se>2014-04-03 23:21:46 -0400
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-04-04 11:54:34 +0100
commit75c9f43129da2cabb65659782d5ef30922fa9618 (patch)
treef50d751ca142d26c11e0ca25710ab67a126c7527
parentd04d0c07355b40dc2f2f71548526d9bb74147fbb (diff)
downloadpoky-75c9f43129da2cabb65659782d5ef30922fa9618.tar.gz
eglibc 2.18: powerpc: Fix time related syscalls
Concatenated fix of PowerPC time related system calls in eglibc 2.18 taken from upstream glibc. See credits in patch header. The effect is that some time related system calls returns nothing or garbage. Fix tested on PowerPC e300c3. Eglibc 2.17 does not have this issue and the patches are already part of 2.19. (From OE-Core rev: fae2f635e795d496228dd5d302e99d9ab7706900) Signed-off-by: Mats Karrman <mats.karrman@tritech.se> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-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 @@
1Upstream-Status: Backport
2
3Concatenated fix of PowerPC time related system calls in eglibc 2.18 taken
4from upstream glibc. Eglibc 2.17 does not have this issue and the patches are
5already part of 2.19.
6This compilation includes the following committs:
7
8
9PowerPC: Fix vDSO missing ODP entries
10
11author Adhemerval Zanella <azanella@linux.vnet.ibm.com>
12 Thu, 7 Nov 2013 11:34:22 +0000 (05:34 -0600)
13
14This patch fixes the vDSO symbol used directed in IFUNC resolver where
15they do not have an associated ODP entry leading to undefined behavior
16in some cases. It adds an artificial OPD static entry to such cases
17and set its TOC to non 0 to avoid triggering lazy resolutions.
18
19
20Update copyright notices with scripts/update-copyrights
21
22author Allan McRae <allan@archlinux.org>
23 Wed, 1 Jan 2014 11:03:15 +0000 (21:03 +1000)
24
25((Only for files otherwise touched by this patch))
26
27
28PowerPC: Fix ftime gettimeofday internal call returning bogus data
29
30author Adhemerval Zanella <azanella@linux.vnet.ibm.com>
31 Thu, 16 Jan 2014 12:53:18 +0000 (06:53 -0600)
32
33This patches fixes BZ#16430 by setting a different symbol for internal
34GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol
35is defined as hidden (which is the case for gettimeofday and time) the
36compiler will create local branches (symbol@local) and linker will not
37create PLT calls (required for IFUNC). This will leads to internal symbol
38calling the IFUNC resolver instead of the resolved symbol.
39For PPC64 this behavior does not occur because a call to a function in
40another translation unit might use a different toc pointer thus requiring
41a PLT call.
42
43
44PowerPC: Fix gettimeofday ifunc selection
45
46author Adhemerval Zanella <azanella@linux.vnet.ibm.com>
47 Mon, 20 Jan 2014 18:29:51 +0000 (12:29 -0600)
48
49The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
50__vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
51version used within GLIBC) to use the system call version instead of the vDSO one.
52This patch changes the check if vDSO is available to get its value directly
53instead of rely on __vdso_gettimeofday.
54
55This patch changes it by getting the vDSO value directly.
56
57It fixes BZ#16431.
58
59
60---
61diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
62--- libc.orig/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
63+++ libc/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
64@@ -1,5 +1,5 @@
65 /* Resolve function pointers to VDSO functions.
66- Copyright (C) 2005-2013 Free Software Foundation, Inc.
67+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
68 This file is part of the GNU C Library.
69
70 The GNU C Library is free software; you can redistribute it and/or
71@@ -34,12 +34,32 @@ extern void *__vdso_getcpu;
72
73 extern void *__vdso_time;
74
75-/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO
76- symbol. This works because _dl_vdso_vsym always return the function
77- address, and no vDSO symbols use the TOC or chain pointers from the OPD
78- so we can allow them to be garbage. */
79 #if defined(__PPC64__) || defined(__powerpc64__)
80-#define VDSO_IFUNC_RET(value) ((void *) &(value))
81+/* The correct solution is for _dl_vdso_vsym to return the address of the OPD
82+ for the kernel VDSO function. That address would then be stored in the
83+ __vdso_* variables and returned as the result of the IFUNC resolver function.
84+ Yet, the kernel does not contain any OPD entries for the VDSO functions
85+ (incomplete implementation). However, PLT relocations for IFUNCs still expect
86+ the address of an OPD to be returned from the IFUNC resolver function (since
87+ PLT entries on PPC64 are just copies of OPDs). The solution for now is to
88+ create an artificial static OPD for each VDSO function returned by a resolver
89+ function. The TOC value is set to a non-zero value to avoid triggering lazy
90+ symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
91+ sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None
92+ of the kernel VDSO routines use the TOC or AUX values so any non-zero value
93+ will work. Note that function pointer comparisons will not use this artificial
94+ static OPD since those are resolved via ADDR64 relocations and will point at
95+ the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations
96+ are processed immediately at startup the resolver functions and this code need
97+ not be thread-safe, but if the caller writes to a PLT slot it must do so in a
98+ thread-safe manner with all the required barriers. */
99+#define VDSO_IFUNC_RET(value) \
100+ ({ \
101+ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
102+ vdso_opd.fd_func = (Elf64_Addr)value; \
103+ &vdso_opd; \
104+ })
105+
106 #else
107 #define VDSO_IFUNC_RET(value) ((void *) (value))
108 #endif
109diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
110--- libc.orig/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
111+++ libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
112@@ -1,4 +1,4 @@
113-/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
114+/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
115 This file is part of the GNU C Library.
116
117 The GNU C Library is free software; you can redistribute it and/or
118@@ -22,6 +22,7 @@
119
120 # include <dl-vdso.h>
121 # include <bits/libc-vdso.h>
122+# include <dl-machine.h>
123
124 void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
125
126@@ -34,17 +35,36 @@ __gettimeofday_syscall (struct timeval *
127 void *
128 gettimeofday_ifunc (void)
129 {
130+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
131+
132 /* If the vDSO is not available we fall back syscall. */
133- return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday)
134- : __gettimeofday_syscall);
135+ void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
136+ return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
137+ : (void*)__gettimeofday_syscall);
138 }
139 asm (".type __gettimeofday, %gnu_indirect_function");
140
141 /* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
142 let us do it in C because it doesn't know we're defining __gettimeofday
143 here in this file. */
144-asm (".globl __GI___gettimeofday\n"
145- "__GI___gettimeofday = __gettimeofday");
146+asm (".globl __GI___gettimeofday");
147+
148+/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
149+ compiler make a local call (symbol@local) for internal GLIBC usage. It
150+ means the PLT won't be used and the ifunc resolver will be called directly.
151+ For ppc64 a call to a function in another translation unit might use a
152+ different toc pointer thus disallowing direct branchess and making internal
153+ ifuncs calls safe. */
154+#ifdef __powerpc64__
155+asm ("__GI___gettimeofday = __gettimeofday");
156+#else
157+int
158+__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
159+{
160+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
161+}
162+asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
163+#endif
164
165 #else
166
167diff -pruN libc.orig/sysdeps/unix/sysv/linux/powerpc/time.c libc/sysdeps/unix/sysv/linux/powerpc/time.c
168--- libc.orig/sysdeps/unix/sysv/linux/powerpc/time.c
169+++ libc/sysdeps/unix/sysv/linux/powerpc/time.c
170@@ -1,5 +1,5 @@
171 /* time system call for Linux/PowerPC.
172- Copyright (C) 2013 Free Software Foundation, Inc.
173+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
174 This file is part of the GNU C Library.
175
176 The GNU C Library is free software; you can redistribute it and/or
177@@ -20,7 +20,9 @@
178
179 # include <time.h>
180 # include <sysdep.h>
181+# include <dl-vdso.h>
182 # include <bits/libc-vdso.h>
183+# include <dl-machine.h>
184
185 void *time_ifunc (void) asm ("time");
186
187@@ -43,17 +45,36 @@ time_syscall (time_t *t)
188 void *
189 time_ifunc (void)
190 {
191+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
192+
193 /* If the vDSO is not available we fall back to the syscall. */
194- return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time)
195- : time_syscall);
196+ void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
197+ return (vdso_time ? VDSO_IFUNC_RET (vdso_time)
198+ : (void*)time_syscall);
199 }
200 asm (".type time, %gnu_indirect_function");
201
202 /* This is doing "libc_hidden_def (time)" but the compiler won't
203 * let us do it in C because it doesn't know we're defining time
204 * here in this file. */
205-asm (".globl __GI_time\n"
206- "__GI_time = time");
207+asm (".globl __GI_time");
208+
209+/* __GI_time is defined as hidden and for ppc32 it enables the
210+ compiler make a local call (symbol@local) for internal GLIBC usage. It
211+ means the PLT won't be used and the ifunc resolver will be called directly.
212+ For ppc64 a call to a function in another translation unit might use a
213+ different toc pointer thus disallowing direct branchess and making internal
214+ ifuncs calls safe. */
215+#ifdef __powerpc64__
216+asm ("__GI_time = time");
217+#else
218+time_t
219+__time_vsyscall (time_t *t)
220+{
221+ return INLINE_VSYSCALL (time, 1, t);
222+}
223+asm ("__GI_time = __time_vsyscall");
224+#endif
225
226 #else
227
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
28 file://fix-tibetian-locales.patch \ 28 file://fix-tibetian-locales.patch \
29 file://0001-ARM-Pass-dl_hwcap-to-IFUNC-resolver.patch \ 29 file://0001-ARM-Pass-dl_hwcap-to-IFUNC-resolver.patch \
30 file://make-4.patch \ 30 file://make-4.patch \
31 file://ppc-fix-time-related-syscalls.patch \
31 " 32 "
32SRC_URI[md5sum] = "b395b021422a027d89884992e91734fc" 33SRC_URI[md5sum] = "b395b021422a027d89884992e91734fc"
33SRC_URI[sha256sum] = "15f564b45dc5dd65faf0875579e3447961ae61e876933384ae05d19328539ad4" 34SRC_URI[sha256sum] = "15f564b45dc5dd65faf0875579e3447961ae61e876933384ae05d19328539ad4"