From b2a0b276126db632b9cc7565867291cffcdec73f4fdfee0868d1478f1f26213d Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Tue, 31 Jan 2012 10:21:58 +0000 Subject: [PATCH] Accepting request 102160 from home:a_jaeger:my-factory-packages Fix relocation ordering to fix ifunc crash (bnc#740109) OBS-URL: https://build.opensuse.org/request/show/102160 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=159 --- check-build.sh | 8 +- glibc-2.15-math64crash.patch | 187 ----------------------- glibc-ifunc-2.16.patch | 278 +++++++++++++++++++++++++++++++++++ glibc.changes | 13 +- glibc.spec | 13 +- 5 files changed, 305 insertions(+), 194 deletions(-) delete mode 100644 glibc-2.15-math64crash.patch create mode 100644 glibc-ifunc-2.16.patch diff --git a/check-build.sh b/check-build.sh index fed8e7f..3f33595 100644 --- a/check-build.sh +++ b/check-build.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2003, 2004, 2011 SUSE Linux Products GmbH, Germany. All rights reserved. +# Copyright (c) 2003, 2004, 2011,2012 SUSE Linux Products GmbH, Germany. All rights reserved. # # Authors: Thorsten Kukuk # @@ -13,12 +13,18 @@ fi # get kernel version OFS="$IFS" ; IFS=".-" ; version=(`uname -r`) ; IFS="$OIFS" +ARCH=(`uname -m`) if test ${version[0]} -gt 2 ; then : # okay elif test ${version[0]} -lt 2 -o ${version[1]} -lt 6 -o ${version[2]} -lt 16 ; then echo "FATAL: kernel too old, need kernel >= 2.6.16 for this package" 1>&2 exit 1 +elif $ARCH -eq 'x86_64' ; then + if test ${version[0]} -lt 2 -o ${version[1]} -lt 6 -o ${version[2]} -lt 32 ; then + echo "FATAL: kernel too old, need kernel >= 2.6.32 for this package" 1>&2 + exit 1 + fi fi diff --git a/glibc-2.15-math64crash.patch b/glibc-2.15-math64crash.patch deleted file mode 100644 index 5bcfe5e..0000000 --- a/glibc-2.15-math64crash.patch +++ /dev/null @@ -1,187 +0,0 @@ -The following patch comes from Arch Linux - and is just a workaround -until the real problem is fixed. - -diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile -index be68903..a032da8 100644 ---- a/sysdeps/x86_64/fpu/multiarch/Makefile -+++ b/sysdeps/x86_64/fpu/multiarch/Makefile -@@ -1,5 +1,5 @@ - ifeq ($(subdir),math) --libm-sysdep_routines += s_floor-c s_ceil-c s_floorf-c s_ceilf-c \ -+libm-sysdep_routines += s_floorf-c s_ceilf-c \ - s_rint-c s_rintf-c s_nearbyint-c s_nearbyintf-c - - ifeq ($(have-mfma4),yes) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c b/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c -deleted file mode 100644 -index 6a5ea3f..0000000 ---- a/sysdeps/x86_64/fpu/multiarch/s_ceil-c.c -+++ /dev/null -@@ -1,2 +0,0 @@ --#define __ceil __ceil_c --#include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil.S b/sysdeps/x86_64/fpu/multiarch/s_ceil.S -deleted file mode 100644 -index d0f8da3..0000000 ---- a/sysdeps/x86_64/fpu/multiarch/s_ceil.S -+++ /dev/null -@@ -1,40 +0,0 @@ --/* Copyright (C) 2011 Free Software Foundation, Inc. -- This file is part of the GNU C Library. -- Contributed by Ulrich Drepper , 2011. -- -- The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, write to the Free -- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -- 02111-1307 USA. */ -- --#include --#include -- -- --ENTRY(__ceil) -- .type __ceil, @gnu_indirect_function -- call __get_cpu_features@plt -- movq %rax, %rdx -- leaq __ceil_sse41(%rip), %rax -- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) -- jnz 2f -- leaq __ceil_c(%rip), %rax --2: ret --END(__ceil) --weak_alias (__ceil, ceil) -- -- --ENTRY(__ceil_sse41) -- roundsd $2, %xmm0, %xmm0 -- ret --END(__ceil_sse41) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c b/sysdeps/x86_64/fpu/multiarch/s_floor-c.c -deleted file mode 100644 -index 68733b6..0000000 ---- a/sysdeps/x86_64/fpu/multiarch/s_floor-c.c -+++ /dev/null -@@ -1,3 +0,0 @@ --#undef __floor --#define __floor __floor_c --#include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor.S b/sysdeps/x86_64/fpu/multiarch/s_floor.S -deleted file mode 100644 -index 514ea95..0000000 ---- a/sysdeps/x86_64/fpu/multiarch/s_floor.S -+++ /dev/null -@@ -1,40 +0,0 @@ --/* Copyright (C) 2011 Free Software Foundation, Inc. -- This file is part of the GNU C Library. -- Contributed by Ulrich Drepper , 2011. -- -- The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, write to the Free -- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -- 02111-1307 USA. */ -- --#include --#include -- -- --ENTRY(__floor) -- .type __floor, @gnu_indirect_function -- call __get_cpu_features@plt -- movq %rax, %rdx -- leaq __floor_sse41(%rip), %rax -- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) -- jnz 2f -- leaq __floor_c(%rip), %rax --2: ret --END(__floor) --weak_alias (__floor, floor) -- -- --ENTRY(__floor_sse41) -- roundsd $1, %xmm0, %xmm0 -- ret --END(__floor_sse41) -diff --git a/sysdeps/x86_64/fpu/multiarch/s_sin.c b/sysdeps/x86_64/fpu/multiarch/s_sin.c -deleted file mode 100644 -index 1ba9dbc..0000000 ---- a/sysdeps/x86_64/fpu/multiarch/s_sin.c -+++ /dev/null -@@ -1,31 +0,0 @@ --#if defined HAVE_FMA4_SUPPORT || defined HAVE_AVX_SUPPORT --# include --# include --# undef NAN -- --extern double __cos_sse2 (double); --extern double __sin_sse2 (double); --extern double __cos_avx (double); --extern double __sin_avx (double); --# ifdef HAVE_FMA4_SUPPORT --extern double __cos_fma4 (double); --extern double __sin_fma4 (double); --# else --# undef HAS_FMA4 --# define HAS_FMA4 0 --# define __cos_fma4 ((void *) 0) --# define __sin_fma4 ((void *) 0) --# endif -- --libm_ifunc (__cos, HAS_FMA4 ? __cos_fma4 : HAS_AVX ? __cos_avx : __cos_sse2); --weak_alias (__cos, cos) -- --libm_ifunc (__sin, HAS_FMA4 ? __sin_fma4 : HAS_AVX ? __sin_avx : __sin_sse2); --weak_alias (__sin, sin) -- --# define __cos __cos_sse2 --# define __sin __sin_sse2 --#endif -- -- --#include -diff --git a/sysdeps/x86_64/fpu/multiarch/s_tan.c b/sysdeps/x86_64/fpu/multiarch/s_tan.c -deleted file mode 100644 -index 8f6601e..0000000 ---- a/sysdeps/x86_64/fpu/multiarch/s_tan.c -+++ /dev/null -@@ -1,21 +0,0 @@ --#if defined HAVE_FMA4_SUPPORT || defined HAVE_AVX_SUPPORT --# include --# include -- --extern double __tan_sse2 (double); --extern double __tan_avx (double); --# ifdef HAVE_FMA4_SUPPORT --extern double __tan_fma4 (double); --# else --# undef HAS_FMA4 --# define HAS_FMA4 0 --# define __tan_fma4 ((void *) 0) --# endif -- --libm_ifunc (tan, HAS_FMA4 ? __tan_fma4 : HAS_AVX ? __tan_avx : __tan_sse2); -- --# define tan __tan_sse2 --#endif -- -- --#include diff --git a/glibc-ifunc-2.16.patch b/glibc-ifunc-2.16.patch new file mode 100644 index 0000000..b565dbf --- /dev/null +++ b/glibc-ifunc-2.16.patch @@ -0,0 +1,278 @@ +commit 6ee65ed6ddbf04402fad0bec6aa9c73b9d982ae4 +Author: Ulrich Drepper +Date: Fri Jan 27 15:05:19 2012 -0500 + + Sort objects before relocations + +2012-01-27 Ulrich Drepper + + [BZ #13618] + * elf/dl-open.c (dl_open_worker): Sort objects by dependency before + relocation. + * Makeconfig (libm): Define. + * elf/Makefile: Add rules to build and run tst-relsort1. + * elf/tst-relsort1.c: New file. + * elf/tst-relsort1mod1.c: New file. + * elf/tst-relsort1mod2.c: New file. + +diff --git a/Makeconfig b/Makeconfig +index 8195245..185afbb 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -950,6 +950,12 @@ libdl = + endif + endif + ++ifeq ($(build-shared),yes) ++libm = $(common-objpfx)math/libm.so$(libm.so-version) ++else ++libm = $(common-objpfx)math/libm.a ++endif ++ + # These are the subdirectories containing the library source. The order + # is more or less arbitrary. The sorting step will take care of the + # dependencies. +diff --git a/elf/Makefile b/elf/Makefile +index 052e763..3f1772a 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -124,7 +124,8 @@ distribute := rtld-Rules \ + tst-initordera1.c tst-initordera2.c tst-initorderb1.c \ + tst-initorderb2.c tst-initordera3.c tst-initordera4.c \ + tst-initorder.c \ +- tst-initorder2.c ++ tst-initorder2.c \ ++ tst-relsort1.c tst-relsort1mod1.c tst-relsort1mod2.c + + CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables + CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables +@@ -227,7 +228,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-audit1 tst-audit2 \ + tst-stackguard1 tst-addr1 tst-thrlock \ + tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ +- tst-initorder tst-initorder2 ++ tst-initorder tst-initorder2 tst-relsort1 + # reldep9 + test-srcs = tst-pathopt + selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) +@@ -290,7 +291,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-initordera1 tst-initorderb1 \ + tst-initordera2 tst-initorderb2 \ + tst-initordera3 tst-initordera4 \ +- tst-initorder2a tst-initorder2b tst-initorder2c tst-initorder2d ++ tst-initorder2a tst-initorder2b tst-initorder2c \ ++ tst-initorder2d \ ++ tst-relsort1mod1 tst-relsort1mod2 + ifeq (yes,$(have-initfini-array)) + modules-names += tst-array2dep tst-array5dep + endif +@@ -1195,3 +1198,9 @@ CFLAGS-tst-auditmod6b.c += $(AVX-CFLAGS) + CFLAGS-tst-auditmod6c.c += $(AVX-CFLAGS) + CFLAGS-tst-auditmod7b.c += $(AVX-CFLAGS) + endif ++ ++$(objpfx)tst-relsort1: $(libdl) ++$(objpfx)tst-relsort1mod1.so: $(libm) $(objpfx)tst-relsort1mod2.so ++$(objpfx)tst-relsort1mod2.so: $(libm) ++$(objpfx)tst-relsort1.out: $(objpfx)tst-relsort1mod1.so \ ++ $(objpfx)tst-relsort1mod2.so +diff --git a/elf/dl-open.c b/elf/dl-open.c +index a0b5c50..a56bdc1 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -1,5 +1,5 @@ + /* Load a shared object at runtime, relocate it, and run its initializer. +- Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc. ++ Copyright (C) 1996-2007, 2009, 2010, 2011, 2012 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 +@@ -302,45 +302,109 @@ dl_open_worker (void *a) + if (GLRO(dl_lazy)) + reloc_mode |= mode & RTLD_LAZY; + +- /* Relocate the objects loaded. We do this in reverse order so that copy +- relocs of earlier objects overwrite the data written by later objects. */ +- ++ /* Sort the objects by dependency for the relocation process. This ++ allows IFUNC relocations to work and it also means copy ++ relocation of dependencies are if necessary overwritten. */ ++ size_t nmaps = 0; + struct link_map *l = new; +- while (l->l_next) +- l = l->l_next; +- while (1) ++ do ++ { ++ if (! l->l_real->l_relocated) ++ ++nmaps; ++ l = l->l_next; ++ } ++ while (l != NULL); ++ struct link_map *maps[nmaps]; ++ nmaps = 0; ++ l = new; ++ do + { + if (! l->l_real->l_relocated) ++ maps[nmaps++] = l; ++ l = l->l_next; ++ } ++ while (l != NULL); ++ if (nmaps > 1) ++ { ++ char seen[nmaps]; ++ memset (seen, '\0', nmaps); ++ size_t i = 0; ++ while (1) + { +-#ifdef SHARED +- if (__builtin_expect (GLRO(dl_profile) != NULL, 0)) ++ ++seen[i]; ++ struct link_map *thisp = maps[i]; ++ ++ /* Find the last object in the list for which the current one is ++ a dependency and move the current object behind the object ++ with the dependency. */ ++ size_t k = nmaps - 1; ++ while (k > i) + { +- /* If this here is the shared object which we want to profile +- make sure the profile is started. We can find out whether +- this is necessary or not by observing the `_dl_profile_map' +- variable. If was NULL but is not NULL afterwars we must +- start the profiling. */ +- struct link_map *old_profile_map = GL(dl_profile_map); ++ struct link_map **runp = maps[k]->l_initfini; ++ if (runp != NULL) ++ /* Look through the dependencies of the object. */ ++ while (*runp != NULL) ++ if (__builtin_expect (*runp++ == thisp, 0)) ++ { ++ /* Move the current object to the back past the last ++ object with it as the dependency. */ ++ memmove (&maps[i], &maps[i + 1], ++ (k - i) * sizeof (maps[0])); ++ maps[k] = thisp; + +- _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1); ++ if (seen[i + 1] > 1) ++ { ++ ++i; ++ goto next_clear; ++ } + +- if (old_profile_map == NULL && GL(dl_profile_map) != NULL) +- { +- /* We must prepare the profiling. */ +- _dl_start_profile (); ++ char this_seen = seen[i]; ++ memmove (&seen[i], &seen[i + 1], ++ (k - i) * sizeof (seen[0])); ++ seen[k] = this_seen; + +- /* Prevent unloading the object. */ +- GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE; +- } ++ goto next; ++ } ++ ++ --k; + } +- else +-#endif +- _dl_relocate_object (l, l->l_scope, reloc_mode, 0); ++ ++ if (++i == nmaps) ++ break; ++ next_clear: ++ memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0])); ++ next:; + } ++ } ++ ++ for (size_t i = nmaps; i-- > 0; ) ++ { ++ l = maps[i]; ++ ++#ifdef SHARED ++ if (__builtin_expect (GLRO(dl_profile) != NULL, 0)) ++ { ++ /* If this here is the shared object which we want to profile ++ make sure the profile is started. We can find out whether ++ this is necessary or not by observing the `_dl_profile_map' ++ variable. If it was NULL but is not NULL afterwars we must ++ start the profiling. */ ++ struct link_map *old_profile_map = GL(dl_profile_map); ++ ++ _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1); + +- if (l == new) +- break; +- l = l->l_prev; ++ if (old_profile_map == NULL && GL(dl_profile_map) != NULL) ++ { ++ /* We must prepare the profiling. */ ++ _dl_start_profile (); ++ ++ /* Prevent unloading the object. */ ++ GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE; ++ } ++ } ++ else ++#endif ++ _dl_relocate_object (l, l->l_scope, reloc_mode, 0); + } + + /* If the file is not loaded now as a dependency, add the search +diff --git a/elf/tst-relsort1.c b/elf/tst-relsort1.c +new file mode 100644 +index 0000000..972100c +--- /dev/null ++++ b/elf/tst-relsort1.c +@@ -0,0 +1,19 @@ ++#include ++#include ++ ++ ++static int ++do_test () ++{ ++ const char lib[] = "$ORIGIN/tst-relsort1mod1.so"; ++ void *h = dlopen (lib, RTLD_NOW); ++ if (h == NULL) ++ { ++ puts (dlerror ()); ++ return 1; ++ } ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-relsort1mod1.c b/elf/tst-relsort1mod1.c +new file mode 100644 +index 0000000..9e4a943 +--- /dev/null ++++ b/elf/tst-relsort1mod1.c +@@ -0,0 +1,7 @@ ++extern int foo (double); ++ ++int ++bar (void) ++{ ++ return foo (1.2); ++} +diff --git a/elf/tst-relsort1mod2.c b/elf/tst-relsort1mod2.c +new file mode 100644 +index 0000000..a2c3e55 +--- /dev/null ++++ b/elf/tst-relsort1mod2.c +@@ -0,0 +1,7 @@ ++#include ++ ++int ++foo (double d) ++{ ++ return floor (d) != 0.0; ++} diff --git a/glibc.changes b/glibc.changes index 9cebbea..007d2b8 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Tue Jan 31 09:44:07 UTC 2012 - aj@suse.de + +- Use Linux 2.6.32 on x86_64 as oldest supported kernel + +------------------------------------------------------------------- +Tue Jan 31 08:57:15 UTC 2012 - aj@suse.de + +- Fix relocation ordering to fix ifunc crash (bnc#740109). + ------------------------------------------------------------------- Sun Jan 29 22:47:18 CET 2012 - dmueller@suse.de @@ -49,7 +59,8 @@ Mon Jan 9 08:17:08 UTC 2012 - aj@suse.de Wed Jan 4 09:34:28 UTC 2012 - aj@suse.de - Remove patch glibc-2.3.4-gb18030-big5hkscs.diff.bz2 and - replace it by gb18030.patch.bz2 (synced with Fedora 16). + replace it by gb18030.patch.bz2 (synced with Fedora 16) + (bnc#743617). ------------------------------------------------------------------- Tue Jan 3 19:42:17 UTC 2012 - aj@suse.de diff --git a/glibc.spec b/glibc.spec index f013731..8405e6a 100644 --- a/glibc.spec +++ b/glibc.spec @@ -53,8 +53,14 @@ BuildRequires: libstdc++-devel %define powerpc_optimize_cpu_power7 0 %define powerpc_optimize_cpu_cell 0 %endif # ppc, ppc64 +%ifarch x86_64 +# 2.6.32 is the SLES 11 SP1 kernel +# 2.6.34 is the openSUSE 11.3 kernel +%define enablekernel 2.6.32 +%else # 2.6.16 is the SLES 10 kernel, use this as oldest supported kernel %define enablekernel 2.6.16 +%endif # ngpt was used in 8.1 and SLES8 Obsoletes: ngpt < 2.2.2 Obsoletes: ngpt-devel < 2.2.2 @@ -194,8 +200,8 @@ Patch88: pthread-cond-wait-revert.patch Patch89: glibc-2.16-scanf.patch # PATCH-FIX-UPSTREAM Fix getcontext on 32-bit powerpc - aj@suse.de Patch90: glibc-ppc-getcontext.patch -# PATCH-FIX-OPENSUSE Revert some math ifuncs (bnc#740109) - aj@suse.de -Patch91: glibc-2.15-math64crash.patch +# PATCH-FIX-UPSTREAM Fix ifunc relocations (bnc#740109) - aj@suse.de +Patch91: glibc-ifunc-2.16.patch # PATCH-FIX-OPENSUSE Remove netlink optimization (bnc#741021) - aj@suse.de Patch92: glibc-revert-netlink-cache.patch @@ -539,9 +545,6 @@ PARALLEL="%{?_smp_mflags}" # fails to build otherwise - need to recheck and fix %define enable_stackguard_randomization 0 %endif -# Remove completely, these give some strange crashes with dlopen -# See bnc#740109 -rm -rf sysdeps/x86_64/fpu/multiarch configure_and_build_glibc() { local dirname="$1"; shift