This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR22374, PowerPC unnecessary PLT entries


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.

diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index afd233f..bd62c42 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -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
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 8c98fd5..5cf862b 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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;
 	}
     }
diff --git a/ld/testsuite/ld-powerpc/ambiguousv2.d b/ld/testsuite/ld-powerpc/ambiguousv2.d
index fec3a2c..7afdfe1 100644
--- a/ld/testsuite/ld-powerpc/ambiguousv2.d
+++ b/ld/testsuite/ld-powerpc/ambiguousv2.d
@@ -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: .*

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]