PR 21847, Don't default PowerPC64 to --plt-localentry
authorAlan Modra <amodra@gmail.com>
Sat, 29 Jul 2017 03:03:35 +0000 (12:33 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 29 Jul 2017 03:32:27 +0000 (13:02 +0930)
The big comment in ppc64_elf_tls_setup says why.  I've also added some
code to the bfd linker that catches the -lpthread -lc symbol
differences and disable generation of optimized call stubs even when
--plt-localentry is activated.  Gold doesn't yet have that.

PR 21847
bfd/
* elf64-ppc.c (struct ppc_link_hash_entry): Add non_zero_localentry.
(ppc64_elf_merge_symbol): Set non_zero_localentry.
(is_elfv2_localentry0): Test non_zero_localentry.
(ppc64_elf_tls_setup): Default to --no-plt-localentry.
gold/
* powerpc.cc (Target_powerpc::scan_relocs): Default to
--no-plt-localentry.
ld/
* ld.texinfo (plt-localentry): Document.

bfd/ChangeLog
bfd/elf64-ppc.c
gold/ChangeLog
gold/powerpc.cc
ld/ChangeLog
ld/ld.texinfo

index 0f7135861bbdb44e48ecea073c58e47a172d3927..41c935dd0d84431f91b5156828cb3b951749b95c 100644 (file)
@@ -1,3 +1,11 @@
+2017-07-29  Alan Modra  <amodra@gmail.com>
+
+       PR 21847
+       * elf64-ppc.c (struct ppc_link_hash_entry): Add non_zero_localentry.
+       (ppc64_elf_merge_symbol): Set non_zero_localentry.
+       (is_elfv2_localentry0): Test non_zero_localentry.
+       (ppc64_elf_tls_setup): Default to --no-plt-localentry.
+
 2017-07-28  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
         * elf32-s390.c (elf_s390_finish_dynamic_sections): Add NULL
index cc0e8ee996c26b0692c20ef4d3a8a57007e6e796..5f3c79f81118e29b7f27154ecb2f53b5bf9a2c5f 100644 (file)
@@ -4013,6 +4013,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.
@@ -5021,7 +5025,7 @@ ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
 
 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,
@@ -5029,6 +5033,8 @@ ppc64_elf_merge_symbol (struct elf_link_hash_entry *h,
                        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;
 }
 
@@ -6335,6 +6341,7 @@ is_elfv2_localentry0 (struct elf_link_hash_entry *h)
          && 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);
 }
@@ -8349,10 +8356,22 @@ ppc64_elf_tls_setup (struct bfd_link_info *info)
   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;
 
   htab->tls_get_addr = ((struct ppc_link_hash_entry *)
                        elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
index fdac9313c3c3463872784273502741ca2f3e7848..a0193937001cef75c411f2f8e2b47466adc74499 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-29  Alan Modra  <amodra@gmail.com>
+
+       PR 21847
+       * powerpc.cc (Target_powerpc::scan_relocs): Default to
+       --no-plt-localentry.
+
 2017-07-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gold/21857
index a4966b8b3cf6636ff7570e70756e8b1f4567dfbb..e322d6f8836ea85b1ec4bd7e39c5b0061c0dbbab 100644 (file)
@@ -7660,8 +7660,6 @@ Target_powerpc<size, big_endian>::scan_relocs(
        {
          if (parameters->options().user_set_plt_localentry())
            plt_localentry0 = parameters->options().plt_localentry();
-         else
-           plt_localentry0 = symtab->lookup("GLIBC_2.26", NULL) != NULL;
        }
       this->plt_localentry0_ = plt_localentry0;
       this->plt_localentry0_init_ = true;
index 93457854a72e4cdc948bf23af6af9c6e07e1dca9..2a371b9c250096b2480aa5edf5f958dfb9551074 100644 (file)
@@ -1,3 +1,7 @@
+2017-07-29  Alan Modra  <amodra@gmail.com>
+
+       * ld.texinfo (plt-localentry): Document.
+
 2017-07-28  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * ldgram.y (ldgram_had_keep): Make static.
index 987816f33cf29e585b353a8cb557831c690776df..172c1ddd9fad8dbace48fa673274b6a6510ea09e 100644 (file)
@@ -7600,6 +7600,21 @@ barrier in the call stub, or use LD_BIND_NOW=1.  By default, @code{ld}
 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.  Use with care.  @option{--no-plt-localentry}
+is the default.
 @end table
 
 @ifclear GENERIC