]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/glibc/glibc-rh1028285.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh1028285.patch
CommitLineData
bb330e25
AF
1From a5675717e35a02a3eba7e13701c6f9c0d7222e13 Mon Sep 17 00:00:00 2001
2From: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
3Date: Fri, 7 Jun 2013 14:50:23 -0500
4Subject: [PATCH 2/2] PowerPC: gettimeofday optimization by using IFUNC
5
6Backport of ef26eece6331a1f6d959818e37c438cc7ce68e53 from master.
7---
8 sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 10 ++++
9 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 49 +++++++++++++++-------
10 2 files changed, 44 insertions(+), 15 deletions(-)
11
12commit 76a9b9986141b1a7d9fd290c349d27fcee780c7a
13Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
14Date: Thu Nov 7 05:34:22 2013 -0600
15
16 PowerPC: Fix vDSO missing ODP entries
17
18 This patch fixes the vDSO symbol used directed in IFUNC resolver where
19 they do not have an associated ODP entry leading to undefined behavior
20 in some cases. It adds an artificial OPD static entry to such cases
21 and set its TOC to non 0 to avoid triggering lazy resolutions.
22
23commit d98720e07f67fbeec00f9e1347840404240d3c48
24Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
25Date: Mon Jan 20 12:29:51 2014 -0600
26
27 PowerPC: Fix gettimeofday ifunc selection
28
29 The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
30 __vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
31 version used within GLIBC) to use the system call version instead of the vDSO one.
32 This patch changes the check if vDSO is available to get its value directly
33 instead of rely on __vdso_gettimeofday.
34
35 This patch changes it by getting the vDSO value directly.
36
37 It fixes BZ#16431.
38
39diff -pruN a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
40--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2014-05-20 14:46:51.026871920 +0530
41+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2014-05-20 14:44:39.294877321 +0530
42@@ -33,6 +33,36 @@ extern void *__vdso_get_tbfreq;
43
44 extern void *__vdso_getcpu;
45
46+#if defined(__PPC64__) || defined(__powerpc64__)
47+/* The correct solution is for _dl_vdso_vsym to return the address of the OPD
48+ for the kernel VDSO function. That address would then be stored in the
49+ __vdso_* variables and returned as the result of the IFUNC resolver function.
50+ Yet, the kernel does not contain any OPD entries for the VDSO functions
51+ (incomplete implementation). However, PLT relocations for IFUNCs still expect
52+ the address of an OPD to be returned from the IFUNC resolver function (since
53+ PLT entries on PPC64 are just copies of OPDs). The solution for now is to
54+ create an artificial static OPD for each VDSO function returned by a resolver
55+ function. The TOC value is set to a non-zero value to avoid triggering lazy
56+ symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
57+ sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None
58+ of the kernel VDSO routines use the TOC or AUX values so any non-zero value
59+ will work. Note that function pointer comparisons will not use this artificial
60+ static OPD since those are resolved via ADDR64 relocations and will point at
61+ the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations
62+ are processed immediately at startup the resolver functions and this code need
63+ not be thread-safe, but if the caller writes to a PLT slot it must do so in a
64+ thread-safe manner with all the required barriers. */
65+#define VDSO_IFUNC_RET(value) \
66+ ({ \
67+ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
68+ vdso_opd.fd_func = (Elf64_Addr)value; \
69+ &vdso_opd; \
70+ })
71+
72+#else
73+#define VDSO_IFUNC_RET(value) ((void *) (value))
74+#endif
75+
76 #endif
77
78 #endif /* _LIBC_VDSO_H */
79diff -pruN a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
80--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2010-05-04 16:57:23.000000000 +0530
81+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2014-05-20 14:44:39.298877321 +0530
82@@ -16,27 +16,51 @@
83 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
84 02111-1307 USA. */
85
86-#include <sysdep.h>
87-#include <bp-checks.h>
88-#include <stddef.h>
89 #include <sys/time.h>
90-#include <time.h>
91-#include <hp-timing.h>
92
93-#undef __gettimeofday
94-#include <bits/libc-vdso.h>
95+#ifdef SHARED
96
97-/* Get the current time of day and timezone information,
98- putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
99- Returns 0 on success, -1 on errors. */
100-
101-int
102-__gettimeofday (tv, tz)
103- struct timeval *tv;
104- struct timezone *tz;
105+# include <dl-vdso.h>
106+# include <bits/libc-vdso.h>
107+# include <dl-machine.h>
108+
109+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
110+
111+static int
112+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
113+{
114+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
115+}
116+
117+void *
118+gettimeofday_ifunc (void)
119+{
120+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
121+
122+ /* If the vDSO is not available we fall back syscall. */
123+ void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
124+ return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
125+ : (void*)__gettimeofday_syscall);
126+}
127+asm (".type __gettimeofday, %gnu_indirect_function");
128+
129+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
130+ let us do it in C because it doesn't know we're defining __gettimeofday
131+ here in this file. */
132+asm (".globl __GI___gettimeofday\n"
133+ "__GI___gettimeofday = __gettimeofday");
134+
135+#else
136+
137+# include <sysdep.h>
138+# include <errno.h>
139+
140+int
141+__gettimeofday (struct timeval *tv, struct timezone *tz)
142 {
143- return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
144+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
145 }
146
147+#endif
148 INTDEF (__gettimeofday)
149 weak_alias (__gettimeofday, gettimeofday)