This is the mail archive of the binutils-cvs@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]

[binutils-gdb] PR22374, PowerPC unnecessary PLT entries


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3988aed54acce3c682a877b51b0e09cce1079e81

commit 3988aed54acce3c682a877b51b0e09cce1079e81
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Oct 31 22:13:21 2017 +1030

    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:
---
 bfd/ChangeLog                         |  9 +++++++++
 bfd/elf32-ppc.c                       | 23 +++++++++++++++++++----
 bfd/elf64-ppc.c                       | 30 ++++++++++++++++++++++++++----
 ld/ChangeLog                          |  4 ++++
 ld/testsuite/ld-powerpc/ambiguousv2.d |  5 -----
 5 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a28769a..fca37c0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
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/ChangeLog b/ld/ChangeLog
index 84bebb3..bdc98d6 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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,
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: .*


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