diff options
| -rw-r--r-- | meta/recipes-core/eglibc/eglibc-2.18/ppc-fix-time-related-syscalls.patch | 227 | ||||
| -rw-r--r-- | meta/recipes-core/eglibc/eglibc_2.18.bb | 1 |
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 @@ | |||
| 1 | Upstream-Status: Backport | ||
| 2 | |||
| 3 | Concatenated fix of PowerPC time related system calls in eglibc 2.18 taken | ||
| 4 | from upstream glibc. Eglibc 2.17 does not have this issue and the patches are | ||
| 5 | already part of 2.19. | ||
| 6 | This compilation includes the following committs: | ||
| 7 | |||
| 8 | |||
| 9 | PowerPC: Fix vDSO missing ODP entries | ||
| 10 | |||
| 11 | author Adhemerval Zanella <azanella@linux.vnet.ibm.com> | ||
| 12 | Thu, 7 Nov 2013 11:34:22 +0000 (05:34 -0600) | ||
| 13 | |||
| 14 | This patch fixes the vDSO symbol used directed in IFUNC resolver where | ||
| 15 | they do not have an associated ODP entry leading to undefined behavior | ||
| 16 | in some cases. It adds an artificial OPD static entry to such cases | ||
| 17 | and set its TOC to non 0 to avoid triggering lazy resolutions. | ||
| 18 | |||
| 19 | |||
| 20 | Update copyright notices with scripts/update-copyrights | ||
| 21 | |||
| 22 | author 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 | |||
| 28 | PowerPC: Fix ftime gettimeofday internal call returning bogus data | ||
| 29 | |||
| 30 | author Adhemerval Zanella <azanella@linux.vnet.ibm.com> | ||
| 31 | Thu, 16 Jan 2014 12:53:18 +0000 (06:53 -0600) | ||
| 32 | |||
| 33 | This patches fixes BZ#16430 by setting a different symbol for internal | ||
| 34 | GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol | ||
| 35 | is defined as hidden (which is the case for gettimeofday and time) the | ||
| 36 | compiler will create local branches (symbol@local) and linker will not | ||
| 37 | create PLT calls (required for IFUNC). This will leads to internal symbol | ||
| 38 | calling the IFUNC resolver instead of the resolved symbol. | ||
| 39 | For PPC64 this behavior does not occur because a call to a function in | ||
| 40 | another translation unit might use a different toc pointer thus requiring | ||
| 41 | a PLT call. | ||
| 42 | |||
| 43 | |||
| 44 | PowerPC: Fix gettimeofday ifunc selection | ||
| 45 | |||
| 46 | author Adhemerval Zanella <azanella@linux.vnet.ibm.com> | ||
| 47 | Mon, 20 Jan 2014 18:29:51 +0000 (12:29 -0600) | ||
| 48 | |||
| 49 | The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where | ||
| 50 | __vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal | ||
| 51 | version used within GLIBC) to use the system call version instead of the vDSO one. | ||
| 52 | This patch changes the check if vDSO is available to get its value directly | ||
| 53 | instead of rely on __vdso_gettimeofday. | ||
| 54 | |||
| 55 | This patch changes it by getting the vDSO value directly. | ||
| 56 | |||
| 57 | It fixes BZ#16431. | ||
| 58 | |||
| 59 | |||
| 60 | --- | ||
| 61 | diff -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 | ||
| 109 | diff -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 | |||
| 167 | diff -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 | " |
| 32 | SRC_URI[md5sum] = "b395b021422a027d89884992e91734fc" | 33 | SRC_URI[md5sum] = "b395b021422a027d89884992e91734fc" |
| 33 | SRC_URI[sha256sum] = "15f564b45dc5dd65faf0875579e3447961ae61e876933384ae05d19328539ad4" | 34 | SRC_URI[sha256sum] = "15f564b45dc5dd65faf0875579e3447961ae61e876933384ae05d19328539ad4" |
