From 3edb85c58c21246800abf86e5212e42f791933b8 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 31 Jul 2017 11:32:14 +0100 Subject: [PATCH] Update ppc64 localentry0 patch with changes made by Alan Modra to the FSF binutils sources. Resolves: #1475636 --- ...s-2.29-ppc64-plt-localentry0-disable.patch | 109 +++++++++++++++++- binutils.spec | 6 +- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/binutils-2.29-ppc64-plt-localentry0-disable.patch b/binutils-2.29-ppc64-plt-localentry0-disable.patch index 020f974..789d19a 100644 --- a/binutils-2.29-ppc64-plt-localentry0-disable.patch +++ b/binutils-2.29-ppc64-plt-localentry0-disable.patch @@ -1,13 +1,116 @@ ---- binutils.orig/bfd/elf64-ppc.c 2017-07-28 14:39:40.690343665 +0100 -+++ binutils-2.29/bfd/elf64-ppc.c 2017-07-28 14:40:08.685021561 +0100 -@@ -8347,9 +8347,7 @@ ppc64_elf_tls_setup (struct bfd_link_inf +diff -rup binutils.orig/bfd/elf64-ppc.c binutils-2.29/bfd/elf64-ppc.c +--- binutils.orig/bfd/elf64-ppc.c 2017-07-31 10:48:13.642980052 +0100 ++++ binutils-2.29/bfd/elf64-ppc.c 2017-07-31 10:48:37.386711582 +0100 +@@ -4010,6 +4010,10 @@ struct ppc_link_hash_entry + with non-standard calling convention. */ + unsigned int save_res:1; + ++ /* Set if a duplicate symbol with non-zero localentry is detected, ++ even when the duplicate symbol does not provide a definition. */ ++ unsigned int non_zero_localentry:1; ++ + /* Contexts in which symbol is used in the GOT (or TOC). + TLS_GD .. TLS_EXPLICIT bits are or'd into the mask as the + corresponding relocs are encountered during check_relocs. +@@ -5018,7 +5022,7 @@ ppc64_elf_merge_symbol_attribute (struct + + static bfd_boolean + ppc64_elf_merge_symbol (struct elf_link_hash_entry *h, +- const Elf_Internal_Sym *isym ATTRIBUTE_UNUSED, ++ const Elf_Internal_Sym *isym, + asection **psec ATTRIBUTE_UNUSED, + bfd_boolean newdef ATTRIBUTE_UNUSED, + bfd_boolean olddef ATTRIBUTE_UNUSED, +@@ -5026,6 +5030,8 @@ ppc64_elf_merge_symbol (struct elf_link_ + const asection *oldsec ATTRIBUTE_UNUSED) + { + ((struct ppc_link_hash_entry *) h)->fake = 0; ++ if ((STO_PPC64_LOCAL_MASK & isym->st_other) != 0) ++ ((struct ppc_link_hash_entry *) h)->non_zero_localentry = 1; + return TRUE; + } + +@@ -6332,6 +6338,7 @@ is_elfv2_localentry0 (struct elf_link_ha + && h->type == STT_FUNC + && h->root.type == bfd_link_hash_defined + && (STO_PPC64_LOCAL_MASK & h->other) == 0 ++ && !((struct ppc_link_hash_entry *) h)->non_zero_localentry + && is_ppc64_elf (h->root.u.def.section->owner) + && abiversion (h->root.u.def.section->owner) >= 2); + } +@@ -8346,10 +8353,28 @@ ppc64_elf_tls_setup (struct bfd_link_inf + else if (!htab->do_multi_toc) htab->params->no_multi_toc = 1; ++ /* Default to --no-plt-localentry, as this option can cause problems ++ with symbol interposition. For example, glibc libpthread.so and ++ libc.so duplicate many pthread symbols, with a fallback ++ implementation in libc.so. In some cases the fallback does more ++ work than the pthread implementation. __pthread_condattr_destroy ++ is one such symbol: the libpthread.so implementation is ++ localentry:0 while the libc.so implementation is localentry:8. ++ An app that "cleverly" uses dlopen to only load necessary ++ libraries at runtime may omit loading libpthread.so when not ++ running multi-threaded, which then results in the libc.so ++ fallback symbols being used and ld.so complaining. Now there ++ are workarounds in ld (see non_zero_localentry) to detect the ++ pthread situation, but that may not be the only case where ++ --plt-localentry can cause trouble. */ if (htab->params->plt_localentry0 < 0) - htab->params->plt_localentry0 - = elf_link_hash_lookup (&htab->elf, "GLIBC_2.26", - FALSE, FALSE, FALSE) != NULL; + htab->params->plt_localentry0 = 0; ++ if (htab->params->plt_localentry0 ++ && elf_link_hash_lookup (&htab->elf, "GLIBC_2.26", ++ FALSE, FALSE, FALSE) == NULL) ++ info->callbacks->einfo ++ (_("%P: warning: --plt-localentry is especially dangerous without " ++ "ld.so support to detect ABI violations.\n")); htab->tls_get_addr = ((struct ppc_link_hash_entry *) elf_link_hash_lookup (&htab->elf, ".__tls_get_addr", +diff -rup binutils.orig/gold/powerpc.cc binutils-2.29/gold/powerpc.cc +--- binutils.orig/gold/powerpc.cc 2017-07-31 10:48:13.621980289 +0100 ++++ binutils-2.29/gold/powerpc.cc 2017-07-31 10:48:37.387711571 +0100 +@@ -7660,8 +7660,10 @@ Target_powerpc::scan_r + { + if (parameters->options().user_set_plt_localentry()) + plt_localentry0 = parameters->options().plt_localentry(); +- else +- plt_localentry0 = symtab->lookup("GLIBC_2.26", NULL) != NULL; ++ if (plt_localentry0 ++ && symtab->lookup("GLIBC_2.26", NULL) == NULL) ++ gold_warning(_("--plt-localentry is especially dangerous without " ++ "ld.so support to detect ABI violations")); + } + this->plt_localentry0_ = plt_localentry0; + this->plt_localentry0_init_ = true; +diff -rup binutils.orig/ld/ld.texinfo binutils-2.29/ld/ld.texinfo +--- binutils.orig/ld/ld.texinfo 2017-07-31 10:48:13.601980515 +0100 ++++ binutils-2.29/ld/ld.texinfo 2017-07-31 10:48:37.388711559 +0100 +@@ -7600,6 +7600,24 @@ barrier in the call stub, or use LD_BIND + looks for calls to commonly used functions that create threads, and if + seen, adds the necessary barriers. Use these options to change the + default behaviour. ++ ++@cindex PowerPC64 ELFv2 PLT localentry optimization ++@kindex --plt-localentry ++@kindex --no-plt-localentry ++@item --plt-localentry ++@itemx --no-localentry ++ELFv2 functions with localentry:0 are those with a single entry point, ++ie. global entry == local entry, and that have no requirement on r2 ++(the TOC/GOT pointer) or r12, and guarantee r2 is unchanged on return. ++Such an external function can be called via the PLT without saving r2 ++or restoring it on return, avoiding a common load-hit-store for small ++functions. The optimization is attractive, with up to 40% reduction ++in execution time for a small function, but can result in symbol ++interposition failures. Also, minor changes in a shared library, ++including system libraries, can cause a function that was localentry:0 ++to become localentry:8. This will result in a dynamic loader ++complaint and failure to run. The option is experimental, use with ++care. @option{--no-plt-localentry} is the default. + @end table + + @ifclear GENERIC diff --git a/binutils.spec b/binutils.spec index 6f27597..3f32933 100644 --- a/binutils.spec +++ b/binutils.spec @@ -43,7 +43,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.29 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -580,6 +580,10 @@ exit 0 %endif # %{isnative} %changelog +* Mon Jul 31 2017 Nick Clifton 2.29-5 +- Update ppc64 localentry0 patch with changes made by Alan Modra to the FSF binutils sources. + (#1475636) + * Sun Jul 30 2017 Florian Weimer - 2.29-4 - Rebuild with binutils fix for ppc64le, bootstrapping (#1475636)