PR22374, PowerPC unnecessary PLT entries
authorAlan Modra <amodra@gmail.com>
Tue, 31 Oct 2017 11:43:21 +0000 (22:13 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 1 Nov 2017 08:16:34 +0000 (18:46 +1030)
We don't need a PLT entry when function pointer initialization in a
read/write section is the only reference to a given function symbol.
This patch prevents the unnecessary PLT entry, and ensures no dynamic
relocs are emitted when UNDEFWEAK_NO_DYNAMIC_RELOC says so.

bfd/
PR 22374
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Don't create a plt
entry when just a dynamic reloc can serve.  Ensure no dynamic
relocations when UNDEFWEAK_NO_DYNAMIC_RELOC by setting non_got_ref.
Expand and move the non_got_ref comment.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
ld/
* testsuite/ld-powerpc/ambiguousv2.d: Remove FIXME.

bfd/ChangeLog
bfd/elf32-ppc.c
bfd/elf64-ppc.c
ld/ChangeLog
ld/testsuite/ld-powerpc/ambiguousv2.d

index a28769a..fca37c0 100644 (file)
@@ -1,3 +1,12 @@
+2017-11-01  Alan Modra  <amodra@gmail.com>
+
+       PR 22374
+       * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Don't create a plt
+       entry when just a dynamic reloc can serve.  Ensure no dynamic
+       relocations when UNDEFWEAK_NO_DYNAMIC_RELOC by setting non_got_ref.
+       Expand and move the non_got_ref comment.
+       * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+
 2017-10-31  Nick Clifton  <nickc@redhat.com>
 
        PR 22373
index afd233f..bd62c42 100644 (file)
@@ -5507,6 +5507,16 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
          h->plt.plist = NULL;
          h->needs_plt = 0;
          h->pointer_equality_needed = 0;
+         /* After adjust_dynamic_symbol, non_got_ref set in the
+            non-pic case means that dyn_relocs for this symbol should
+            be discarded.  We either want the symbol to remain
+            undefined, or we have a local definition of some sort.
+            The "local definition" for non-function symbols may be
+            due to creating a local definition in .dynbss, and for
+            function symbols, defining the symbol on the PLT call
+            stub code.  Set non_got_ref here to ensure undef weaks
+            stay undefined.  */
+         h->non_got_ref = 1;
        }
       else
        {
@@ -5520,19 +5530,24 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
             resolution of the symbol to be set at load time rather
             than link time.  */
          if ((h->pointer_equality_needed
-              || (!h->ref_regular_nonweak && h->non_got_ref))
+              || (h->non_got_ref
+                  && !h->ref_regular_nonweak
+                  && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))
              && !htab->is_vxworks
              && !ppc_elf_hash_entry (h)->has_sda_refs
              && !readonly_dynrelocs (h, NULL))
            {
              h->pointer_equality_needed = 0;
-             /* After adjust_dynamic_symbol, non_got_ref set in the
-                non-pic case means that dyn_relocs for this symbol
-                should be discarded.  */
+             /* Say that we do want dynamic relocs.  */
              h->non_got_ref = 0;
+             /* If we haven't seen a branch reloc then we don't need
+                a plt entry.  */
+             if (!h->needs_plt)
+               h->plt.plist = NULL;
            }
        }
       h->protected_def = 0;
+      /* Function symbols can't have copy relocs.  */
       return TRUE;
     }
   else
index 8c98fd5..5cf862b 100644 (file)
@@ -7193,6 +7193,16 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
          h->plt.plist = NULL;
          h->needs_plt = 0;
          h->pointer_equality_needed = 0;
+         /* After adjust_dynamic_symbol, non_got_ref set in the
+            non-pic case means that dyn_relocs for this symbol should
+            be discarded.  We either want the symbol to remain
+            undefined, or we have a local definition of some sort.
+            The "local definition" for non-function symbols may be
+            due to creating a local definition in .dynbss, and for
+            ELFv2 function symbols, defining the symbol on the PLT
+            call stub code.  Set non_got_ref here to ensure undef
+            weaks stay undefined.  */
+         h->non_got_ref = 1;
        }
       else if (abiversion (info->output_bfd) >= 2)
        {
@@ -7207,13 +7217,25 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
              && !alias_readonly_dynrelocs (h))
            {
              h->pointer_equality_needed = 0;
-             /* After adjust_dynamic_symbol, non_got_ref set in
-                the non-pic case means that dyn_relocs for this
-                symbol should be discarded.  */
+             /* Say that we do want dynamic relocs.  */
              h->non_got_ref = 0;
+             /* If we haven't seen a branch reloc then we don't need
+                a plt entry.  */
+             if (!h->needs_plt)
+               h->plt.plist = NULL;
            }
 
-         /* If making a plt entry, then we don't need copy relocs.  */
+         /* ELFv2 function symbols can't have copy relocs.  */
+         return TRUE;
+       }
+      else if (!h->needs_plt
+              && !alias_readonly_dynrelocs (h))
+       {
+         /* If we haven't seen a branch reloc then we don't need a
+            plt entry.  */
+         h->plt.plist = NULL;
+         h->pointer_equality_needed = 0;
+         h->non_got_ref = 0;
          return TRUE;
        }
     }
index 84bebb3..bdc98d6 100644 (file)
@@ -1,5 +1,9 @@
 2017-11-01  Alan Modra  <amodra@gmail.com>
 
+       * testsuite/ld-powerpc/ambiguousv2.d: Remove FIXME.
+
+2017-11-01  Alan Modra  <amodra@gmail.com>
+
        PR 22374
        * testsuite/ld-elf/pr22374a.s,
        * testsuite/ld-elf/pr22374b.s,
index fec3a2c..7afdfe1 100644 (file)
@@ -8,16 +8,11 @@
 # anything to mark it as ELFv1 or ELFv2.  We should get a dynamic
 # reloc on the function address, not have a global entry stub, and
 # my_func should be undefined dynamic with value zero.
-# FIXME someday: No need for a plt entry.
 
 Relocation section .* contains 1 entries:
 .*
 .* R_PPC64_ADDR64 .* my_func \+ 0
 
-Relocation section .* contains 1 entries:
-.*
-.* R_PPC64_JMP_SLOT .* my_func \+ 0
-
 Symbol table '\.dynsym' contains 5 entries:
 .*
      0: .*