From 32049f182fa8a353e9c3d7ca6d8ca081e7298723 Mon Sep 17 00:00:00 2001 From: Carlos O'Donell Date: Wed, 12 Jul 2017 19:40:05 -0400 Subject: [PATCH] Add temporary workaround for Bug 1467518. Fix IFUNC crash in early startup for ppc64le static binaries (#1467518). Enable building with BIND_NOW on ppc64le (#1467518). --- glibc-rh1467518.patch | 254 ++++++++++++++++++++++++++++++++++++++++++ glibc.spec | 24 +++- 2 files changed, 275 insertions(+), 3 deletions(-) create mode 100644 glibc-rh1467518.patch diff --git a/glibc-rh1467518.patch b/glibc-rh1467518.patch new file mode 100644 index 0000000..d9709d6 --- /dev/null +++ b/glibc-rh1467518.patch @@ -0,0 +1,254 @@ +This fix is not correct and cannot be applied generally to x86_64 +because Intel wishes to use IFUNC earlier in the dynamic loader +specifically to speedup TLS initialization, and as such that means +we cannot in glibc use TLS in IFUNC resolvers. In ppc64le though we +can use this patch to fix the sln (static application) problems until +upstream has a better solution. + +https://www.sourceware.org/ml/libc-alpha/2017-07/msg00336.html + +Changes since version 1: + + - Added a testcase. This is now validating both statically and + dynamically linked executables. + - Fixed an issue in the $(foreach ..) in sysdeps/powerpc/powerpc64le/Makefile. + - Added a comment to csu/libc-start.c + - Added a comment to csu/libc-tls.c + +-- 8< -- + +The patch proposed by Peter Bergner [1] to libgc in order to fix +[BZ #21707] adds a dependency on a symbol provided by the loader, +forcing the loader to be linked to tests after libgcc was linked. + +It also requires to read the thread pointer during IRELA relocations. + +Tested on powerpc, powerpc64, powerpc64le, s390x and x86_64. + +[1] https://sourceware.org/ml/libc-alpha/2017-06/msg01383.html + +2017-07-08 Tulio Magno Quites Machado Filho + + [BZ #21707] + * csu/libc-start.c (LIBC_START_MAIN): Perform IREL{,A} + relocations after initializing the TCB on statically linked + executables.. + * csu/libc-tls.c (__libc_setup_tls): Add a comment about + IREL{,A} relocations. + * elf/Makefile (tests-static-normal): Add tst-tlsifunc-static. + (tests): Add tst-tlsifunc. + * elf/tst-tlsifunc.c: New file. + * elf/tst-tlsifunc-static.c: Likewise. + * sysdeps/powerpc/powerpc64le/Makefile (f128-loader-link): New + variable. + [$(subdir) = math] (test-float128% test-ifloat128%): Force + linking to the loader after linking to libgcc. + [$(subdir) = wcsmbs stdlib] (bug-strtod bug-strtod2 bug-strtod2) + (tst-strtod-round tst-wcstod-round tst-strtod6 tst-strrom) + (tst-strfrom-locale strfrom-skeleton): Likewise. +--- + csu/libc-start.c | 11 +++--- + csu/libc-tls.c | 2 ++ + elf/Makefile | 5 +-- + elf/tst-tlsifunc-static.c | 19 +++++++++++ + elf/tst-tlsifunc.c | 66 ++++++++++++++++++++++++++++++++++++ + sysdeps/powerpc/powerpc64le/Makefile | 10 ++++++ + 6 files changed, 107 insertions(+), 6 deletions(-) + create mode 100644 elf/tst-tlsifunc-static.c + create mode 100644 elf/tst-tlsifunc.c + +Index: glibc-2.25-717-g3020042/csu/libc-start.c +=================================================================== +--- glibc-2.25-717-g3020042.orig/csu/libc-start.c ++++ glibc-2.25-717-g3020042/csu/libc-start.c +@@ -188,12 +188,15 @@ LIBC_START_MAIN (int (*main) (int, char + + ARCH_INIT_CPU_FEATURES (); + +- /* Perform IREL{,A} relocations. */ +- apply_irel (); +- + /* The stack guard goes into the TCB, so initialize it early. */ + __libc_setup_tls (); + ++ /* Perform IREL{,A} relocations. ++ Note: the relocations must happen after TLS initialization so that ++ IFUNC resolvers can benefit from thread-local storage, e.g. powerpc's ++ hwcap and platform fields available in the TCB. */ ++ apply_irel (); ++ + /* Set up the stack checker's canary. */ + uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); + # ifdef THREAD_SET_STACK_GUARD +@@ -224,7 +227,7 @@ LIBC_START_MAIN (int (*main) (int, char + __pointer_chk_guard_local = pointer_chk_guard; + # endif + +-#endif ++#endif /* !SHARED */ + + /* Register the destructor of the dynamic linker if there is any. */ + if (__glibc_likely (rtld_fini != NULL)) +Index: glibc-2.25-717-g3020042/csu/libc-tls.c +=================================================================== +--- glibc-2.25-717-g3020042.orig/csu/libc-tls.c ++++ glibc-2.25-717-g3020042/csu/libc-tls.c +@@ -101,6 +101,8 @@ init_static_tls (size_t memsz, size_t al + GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx); + } + ++/* Note: IREL{,A} relocations happen after TLS setup. __libc_setup_tls has ++ to guarantee that it won't use STT_GNU_IFUNC. */ + void + __libc_setup_tls (void) + { +Index: glibc-2.25-717-g3020042/elf/Makefile +=================================================================== +--- glibc-2.25-717-g3020042.orig/elf/Makefile ++++ glibc-2.25-717-g3020042/elf/Makefile +@@ -151,12 +151,13 @@ tests-static-normal := tst-leaks1-static + tst-tlsalign-static tst-tlsalign-extern-static \ + tst-linkall-static tst-env-setuid tst-env-setuid-tunables + tests-static-internal := tst-tls1-static tst-tls2-static \ +- tst-ptrguard1-static tst-stackguard1-static ++ tst-ptrguard1-static tst-stackguard1-static \ ++ tst-tlsifunc-static + + tests := tst-tls9 tst-leaks1 \ + tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ + tst-auxv +-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal) ++tests-internal := tst-tls1 tst-tls2 tst-tlsifunc $(tests-static-internal) + tests-static := $(tests-static-normal) $(tests-static-internal) + + ifeq (yes,$(build-shared)) +Index: glibc-2.25-717-g3020042/elf/tst-tlsifunc-static.c +=================================================================== +--- /dev/null ++++ glibc-2.25-717-g3020042/elf/tst-tlsifunc-static.c +@@ -0,0 +1,19 @@ ++/* Test if an executable can read from the TLS from an STT_GNU_IFUNC resolver. ++ Copyright (C) 2017 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 ++ 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, see ++ . */ ++ ++#include "tst-tlsifunc.c" +Index: glibc-2.25-717-g3020042/elf/tst-tlsifunc.c +=================================================================== +--- /dev/null ++++ glibc-2.25-717-g3020042/elf/tst-tlsifunc.c +@@ -0,0 +1,66 @@ ++/* Test if an executable can read from the TLS from an STT_GNU_IFUNC resolver. ++ Copyright (C) 2017 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 ++ 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, see ++ . */ ++ ++#include ++#include ++#include ++#include "tls-macros.h" ++ ++__thread int bar; ++static int * bar_ptr = NULL; ++ ++int foo (void); ++ ++void ++init_foo (void) ++{ ++ bar_ptr = TLS_GD (bar); ++} ++ ++int ++my_foo (void) ++{ ++ printf ("&bar = %p and bar_ptr = %p.\n", &bar, bar_ptr); ++ return bar_ptr != NULL; ++} ++ ++__ifunc (foo, foo, my_foo, void, init_foo); ++ ++static int ++do_test (void) ++{ ++ int ret = 0; ++ ++ if (foo ()) ++ printf ("PASS: IFUNC resolver called once.\n"); ++ else { ++ printf ("FAIL: IFUNC resolver not called once.\n"); ++ ret = 1; ++ } ++ ++ if (&bar == bar_ptr) ++ printf ("PASS: Address read from IFUNC resolver is correct.\n"); ++ else { ++ printf ("FAIL: Address read from IFUNC resolver is incorrect.\n"); ++ ret = 1; ++ } ++ ++ return ret; ++} ++ ++#include +Index: glibc-2.25-717-g3020042/sysdeps/powerpc/powerpc64le/Makefile +=================================================================== +--- glibc-2.25-717-g3020042.orig/sysdeps/powerpc/powerpc64le/Makefile ++++ glibc-2.25-717-g3020042/sysdeps/powerpc/powerpc64le/Makefile +@@ -1,6 +1,11 @@ + # When building float128 we need to ensure -mfloat128 is + # passed to all such object files. + ++# libgcc requires __tcb_parse_hwcap_and_convert_at_platform when built with ++# a binary128 type. That symbol is provided by the loader on dynamically ++# linked executables, forcing to link the loader after libgcc link. ++f128-loader-link = $(as-needed) $(elf-objpfx)ld.so $(no-as-needed) ++ + ifeq ($(subdir),math) + # sqrtf128 requires emulation before POWER9. + CPPFLAGS += -I../soft-fp +@@ -11,6 +16,8 @@ $(foreach suf,$(all-object-suffixes),%f1 + $(foreach suf,$(all-object-suffixes),$(objpfx)test-float128%$(suf)): CFLAGS += -mfloat128 + $(foreach suf,$(all-object-suffixes),$(objpfx)test-ifloat128%$(suf)): CFLAGS += -mfloat128 + CFLAGS-libm-test-support-float128.c += -mfloat128 ++$(objpfx)test-float128% $(objpfx)test-ifloat128%: \ ++ gnulib-tests += $(f128-loader-link) + endif + + # Append flags to string <-> _Float128 routines. +@@ -28,6 +35,9 @@ CFLAGS-tst-strtod6.c += -mfloat128 + CFLAGS-tst-strfrom.c += -mfloat128 + CFLAGS-tst-strfrom-locale.c += -mfloat128 + CFLAGS-strfrom-skeleton.c += -mfloat128 ++$(foreach test,bug-strtod bug-strtod2 bug-strtod2 tst-strtod-round \ ++tst-wcstod-round tst-strtod6 tst-strrom tst-strfrom-locale \ ++strfrom-skeleton,$(objpfx)$(test)): gnulib-tests += $(f128-loader-link) + + # When building glibc with support for _Float128, the powers of ten tables in + # fpioconst.c and in the string conversion functions must be extended. Some diff --git a/glibc.spec b/glibc.spec index 28ad069..b2bfef0 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.25-717-g3020042 %define glibcversion 2.25.90 -%define glibcrelease 23%{?dist} +%define glibcrelease 24%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -255,6 +255,11 @@ Patch0060: glibc-rh1324623.patch # Fix -Wstrict-overflow issues with gcc 7.0. Patch0061: glibc-gcc-strict-overflow.patch +# TODO: This must be removed before F27 release and is a workaround for the +# upstream issue which will be fixed for glibc 2.26. +# Bug 1467518 - glibc: Invalid IFUNC resolver from libgcc calls getauxval... +Patch0062: glibc-rh1467518.patch + ############################################################################## # # Patches from upstream @@ -293,6 +298,9 @@ Patch2112: glibc-rh1315476-2.patch Patch2113: glibc-rh1469536.patch Patch2114: glibc-rh1470060.patch +# upstream arm7hl fix for the dynamic linker not yet committed. +Patch2115: glibc-fix-arm32.patch + ############################################################################## # End of glibc patches. ############################################################################## @@ -855,6 +863,14 @@ microbenchmark tests on the system. %patch2113 -p1 %patch2114 -p1 %patch0061 -p1 +# TODO: Remove before F27 release. +# We *never* want per-arch conditional patches, but in this case +# we are working around a ppc64le issue and apply it only there +# because the complete solution is not upstream yet. +%ifarch ppc64le +%patch0062 -p1 +%endif +%patch2115 -p1 ############################################################################## # %%prep - Additional prep required... @@ -1019,9 +1035,7 @@ build() --prefix=%{_prefix} \ --enable-add-ons=$AddOns \ --with-headers=%{_prefix}/include $EnableKernel \ -%ifnarch ppc64le --enable-bind-now \ -%endif --build=%{target} \ %ifarch %{multiarcharches} --enable-multi-arch \ @@ -2269,6 +2283,10 @@ rm -f *.filelist* %endif %changelog +* Wed Jul 12 2017 Carlos O'Donell - 2.25.90-24 +- Fix IFUNC crash in early startup for ppc64le static binaries (#1467518). +- Enable building with BIND_NOW on ppc64le (#1467518). + * Wed Jul 12 2017 Florian Weimer - 2.25.90-23 - malloc: Tell GCC optimizers about MAX_FAST_SIZE in _int_malloc (#1470060) - Auto-sync with upstream master,