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).
This commit is contained in:
parent
4e3d1d3a47
commit
32049f182f
|
@ -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 <tuliom@linux.vnet.ibm.com>
|
||||
|
||||
[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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <libc-symbols.h>
|
||||
+#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 <support/test-driver.c>
|
||||
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
|
24
glibc.spec
24
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 <carlos@redhat.com> - 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 <fweimer@redhat.com> - 2.25.90-23
|
||||
- malloc: Tell GCC optimizers about MAX_FAST_SIZE in _int_malloc (#1470060)
|
||||
- Auto-sync with upstream master,
|
||||
|
|
Loading…
Reference in New Issue