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] non_got_ref after adjust_dynamic_relocs


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

commit 529fe20eeb0030ea5d653d0ebec433f9e3145874
Author: Alan Modra <amodra@gmail.com>
Date:   Sun Nov 12 17:44:15 2017 +1030

    non_got_ref after adjust_dynamic_relocs
    
    This patch was aimed at a FIXME in elf32-hppa.c, the ludicrous and
    confusing fact that non_got_ref after adjust_dynamic_relocs in that
    backend means precisely the inverse of what it means before
    adjust_dynamic_relocs.  Before, when non_got_ref is set it means there
    are dynamic relocs, after, if non_got_ref is clear it means "keep
    dynamic relocs" and later, "has dynamic relocs".  There is a reason
    why it was done that way..  Some symbols that may have dynamic
    relocations pre-allocated in check_relocs turn out to not be dynamic,
    and then are not seen by the backend adjust_dynamic_symbols.  We want
    those symbols to lose their dynamic relocs when non-pic, so it's handy
    that non_got_ref means the opposite after adjust_dynamic_relocs.  But
    it's really confusing.
    
    Most other targets, like ppc32, don't always set non_got_ref on
    non-GOT references that have dynamic relocations.  This is because the
    primary purpose of non_got_ref before adjust_dynamic_relocs is to flag
    symbols that might need to be copied to .dynbss, and there are
    relocation types that may require dyn_relocs but clearly cannot have
    symbols copied into .dynbss, for example, TLS relocations.
    
    Why do we need a flag after adjust_dynamic_relocs to say "keep
    dynamic relocations"?  Well, you can discard most unwanted dyn_relocs
    in the backend adjust_dynamic_relocs, and for those symbols that
    aren't seen by the backend adjust_dynamic_relocs, in
    allocate_dynrelocs based on a flag set by adjust_dynamic relocs,
    dynamic_adjusted.  That doesn't solve all our difficulties though.
    relocate_section needs to know whether a symbol has dyn_relocs, and
    many targets transfer dyn_relocs to a weakdef if the symbol has one.
    The transfer means relocate_section can't test dyn_relocs itself and
    the weakdef field has been overwritten by that time.  So non_got_ref
    is used to flag "this symbol has dynamic relocations" for
    relocate_section.
    
    Confused still?  Well, let's hope the comments I've added help clarify
    things..  The patch also fixes a case where we might wrongly emit
    dynamic relocations in an executable for common and undefined symbols.
    
    	* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Set non_got_ref
    	to keep dyn_relocs, clear to discard.  Comment.
    	(allocate_dynrelocs): Always clear non_got_ref when clearing
    	dyn_relocs in non-pic case.  Invert non_got_ref test.  Also test
    	dynamic_adjusted and ELF_COMMON_DEF_P.  Move code deleting
    	dyn_relocs on undefined syms to handle for non-pic too.
    	(elf32_hppa_relocate_section): Simplify test for non-pic dyn relocs.
    	* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Set non_got_ref
    	to keep dyn_relocs, clear to discard.  Comment.
    	(allocate_dynrelocs): Always clear non_got_ref when clearing
    	dyn_relocs in non-pic case.  Invert non_got_ref test.  Also test
    	dynamic_adjusted and ELF_COMMON_DEF_P.  Move code deleting
    	dyn_relocs on undefined syms to handle for non-pic too.
    	(ppc_elf_relocate_section): Simplify test for non-pic dyn relocs.
    	* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Discard
    	dyn_relocs here.  Don't bother setting non_got_ref.  Comment.
    	(allocate_dynrelocs): Delete special handling of non-pic ELFv2
    	ifuncs.  Move code deleting dyn_relocs on undefined symbols to
    	handle for non-pic too.  Don't test non_got_ref.  Do test
    	dynamic_adjusted and ELF_COMMON_DEF_P.

Diff:
---
 bfd/ChangeLog    |  23 ++++++++++++
 bfd/elf32-hppa.c |  75 ++++++++++++++++++--------------------
 bfd/elf32-ppc.c  | 109 ++++++++++++++++++++++++++++++++-----------------------
 bfd/elf64-ppc.c  |  97 ++++++++++++++++++++++---------------------------
 4 files changed, 165 insertions(+), 139 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8e61929..735136d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,26 @@
+2017-11-12  Alan Modra  <amodra@gmail.com>
+
+	* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Set non_got_ref
+	to keep dyn_relocs, clear to discard.  Comment.
+	(allocate_dynrelocs): Always clear non_got_ref when clearing
+	dyn_relocs in non-pic case.  Invert non_got_ref test.  Also test
+	dynamic_adjusted and ELF_COMMON_DEF_P.  Move code deleting
+	dyn_relocs on undefined syms to handle for non-pic too.
+	(elf32_hppa_relocate_section): Simplify test for non-pic dyn relocs.
+	* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Set non_got_ref
+	to keep dyn_relocs, clear to discard.  Comment.
+	(allocate_dynrelocs): Always clear non_got_ref when clearing
+	dyn_relocs in non-pic case.  Invert non_got_ref test.  Also test
+	dynamic_adjusted and ELF_COMMON_DEF_P.  Move code deleting
+	dyn_relocs on undefined syms to handle for non-pic too.
+	(ppc_elf_relocate_section): Simplify test for non-pic dyn relocs.
+	* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Discard
+	dyn_relocs here.  Don't bother setting non_got_ref.  Comment.
+	(allocate_dynrelocs): Delete special handling of non-pic ELFv2
+	ifuncs.  Move code deleting dyn_relocs on undefined symbols to
+	handle for non-pic too.  Don't test non_got_ref.  Do test
+	dynamic_adjusted and ELF_COMMON_DEF_P.
+
 2017-11-08  Djordje Todorovic  <djordje.todorovic@rt-rk.com>
 
 	* elf32-mips.c (elf32_mips_grok_psinfo): Extract core->pid.
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index f9629e4..7fc447e 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -1692,7 +1692,9 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (eh->type == STT_FUNC
       || eh->needs_plt)
     {
-      /* After adjust_dynamic_symbol, non_got_ref set in the non-pic
+      /* Prior to adjust_dynamic_symbol, non_got_ref set means that
+	 check_relocs generated dyn_relocs for this symbol.
+	 After adjust_dynamic_symbol, non_got_ref clear 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
@@ -1700,22 +1702,13 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
 	 local definition in .dynbss.
 	 Unlike other targets, elf32-hppa.c does not define a function
 	 symbol in a non-pic executable on PLT stub code, so we don't
-	 have a local definition in that case.  dyn_relocs therefore
-	 should not be discarded for function symbols, generally.
-	 However we should discard dyn_relocs if we've decided that an
-	 undefined function symbol is local, for example due to
-	 non-default visibility, or UNDEFWEAK_NO_DYNAMIC_RELOC is
-	 true for an undefined weak symbol.  */
+	 have a local definition in that case.  */
       bfd_boolean local = (SYMBOL_CALLS_LOCAL (info, eh)
 			   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh));
-      /* Prior to adjust_dynamic_symbol, non_got_ref set means that
-	 check_relocs set up some dyn_relocs for this symbol.
-	 The !non_got_ref term here is saying that if we didn't have
-	 any dyn_relocs set up by check_relocs, then we don't want
-	 relocate_section looking for them.
-	 FIXME: Get rid of the inversion, so non_got_ref set after
-	 dyn_relocs means we do have dyn_relocs.  */
-      eh->non_got_ref = local || !eh->non_got_ref;
+      /* Arrange to discard dyn_relocs if we've decided that a
+	 function symbol is local.  */
+      if (local)
+	eh->non_got_ref = 0;
 
       /* If the symbol is used by a plabel, we must allocate a PLT slot.
 	 The refcounts are not reliable when it has been hidden since
@@ -1773,24 +1766,17 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If there are no references to this symbol that do not use the
      GOT, we don't need to generate a copy reloc.  */
   if (!eh->non_got_ref)
-    {
-      eh->non_got_ref = 1;
-      return TRUE;
-    }
+    return TRUE;
 
   /* If -z nocopyreloc was given, we won't generate them either.  */
   if (info->nocopyreloc)
-    {
-      eh->non_got_ref = 0;
-      return TRUE;
-    }
+    return TRUE;
 
   if (ELIMINATE_COPY_RELOCS
       && !readonly_dynrelocs (eh))
     {
       /* If we didn't find any dynamic relocs in read-only sections, then
 	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
-      eh->non_got_ref = 0;
       return TRUE;
     }
 
@@ -1827,6 +1813,8 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
       eh->needs_copy = 1;
     }
 
+  /* We no longer want dyn_relocs.  */
+  eh->non_got_ref = 0;
   return _bfd_elf_adjust_dynamic_copy (info, eh, sec);
 }
 
@@ -2011,8 +1999,17 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
   if (!htab->etab.dynamic_sections_created)
     hh->dyn_relocs = NULL;
 
+  /* Discard relocs on undefined syms with non-default visibility.  */
+  else if ((eh->root.type == bfd_link_hash_undefined
+	    && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+	   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
+    hh->dyn_relocs = NULL;
+
   if (hh->dyn_relocs == NULL)
-    return TRUE;
+    {
+      eh->non_got_ref = 0;
+      return TRUE;
+    }
 
   /* If this is a -Bsymbolic shared link, then we need to discard all
      space allocated for dynamic pc-relative relocs against symbols
@@ -2021,14 +2018,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
      changes.  */
   if (bfd_link_pic (info))
     {
-      /* Discard relocs on undefined syms with non-default visibility.  */
-      if ((eh->root.type == bfd_link_hash_undefined
-	   && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
-	  || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
-	hh->dyn_relocs = NULL;
-
 #if RELATIVE_DYNRELOCS
-      else if (SYMBOL_CALLS_LOCAL (info, eh))
+      if (SYMBOL_CALLS_LOCAL (info, eh))
 	{
 	  struct elf32_hppa_dyn_reloc_entry **hdh_pp;
 
@@ -2056,17 +2047,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
 
-      if (!eh->non_got_ref
-	  && !eh->def_regular)
+      if (eh->dynamic_adjusted
+	  && eh->non_got_ref
+	  && !eh->def_regular
+	  && !ELF_COMMON_DEF_P (eh))
 	{
 	  if (!ensure_undef_dynamic (info, eh))
 	    return FALSE;
 
 	  if (eh->dynindx == -1)
-	    hh->dyn_relocs = NULL;
+	    {
+	      eh->non_got_ref = 0;
+	      hh->dyn_relocs = NULL;
+	    }
 	}
       else
-	hh->dyn_relocs = NULL;
+	{
+	  eh->non_got_ref = 0;
+	  hh->dyn_relocs = NULL;
+	}
     }
 
   /* Finally, allocate space.  */
@@ -3913,9 +3912,7 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 	      || (ELIMINATE_COPY_RELOCS
 		  && !bfd_link_pic (info)
 		  && hh != NULL
-		  && hh->eh.dynindx != -1
-		  && !hh->eh.non_got_ref
-		  && !hh->eh.def_regular))
+		  && hh->eh.non_got_ref))
 	    {
 	      Elf_Internal_Rela outrel;
 	      bfd_boolean skip;
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 40fc1fc..f68a7a4 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5474,6 +5474,36 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       || h->type == STT_GNU_IFUNC
       || h->needs_plt)
     {
+      /* Prior to adjust_dynamic_symbol, non_got_ref set means that
+	 we might need to generate a copy reloc for this symbol.
+	 After adjust_dynamic_symbol, non_got_ref is only relevant for
+	 non-pic and means that the symbol might have dynamic
+	 relocations.  If it is clear then 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.  */
+      bfd_boolean local = (SYMBOL_CALLS_LOCAL (info, h)
+			   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+      /* Arrange to discard dyn_relocs if we've decided that a
+	 function symbol is local.  It might be possible to discard
+	 dyn_relocs here, but when a symbol has a weakdef they have
+	 been transferred to the weakdef symbol for the benefit of
+	 readonly_dynrelocs.  (See ppc_elf_copy_indirect_symbol.)
+	 Not only would we need to handle weakdefs here, but also in
+	 allocate_dynrelocs and relocate_section.  The latter is
+	 impossible since the weakdef field has been overwritten by
+	 that time.  In relocate_section we need a proxy for
+	 dyn_relocs and non_got_ref is that proxy.
+	 Note that function symbols are not supposed to have weakdefs,
+	 but since symbols may not be correctly typed we handle them
+	 here.  */
+      h->non_got_ref = (h->u.weakdef != NULL
+			? h->u.weakdef->non_got_ref
+			: !local && (((struct ppc_elf_link_hash_entry *) h)
+				     ->dyn_relocs != NULL));
+
       /* Clear procedure linkage table information for any symbol that
 	 won't need a .plt entry.  */
       struct plt_entry *ent;
@@ -5481,9 +5511,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	if (ent->plt.refcount > 0)
 	  break;
       if (ent == NULL
-	  || (h->type != STT_GNU_IFUNC
-	      && (SYMBOL_CALLS_LOCAL (info, h)
-		  || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))))
+	  || (h->type != STT_GNU_IFUNC && local))
 	{
 	  /* A PLT entry is not required/allowed when:
 
@@ -5498,16 +5526,6 @@ 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
 	{
@@ -5529,13 +5547,15 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	      && !readonly_dynrelocs (h))
 	    {
 	      h->pointer_equality_needed = 0;
-	      /* 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;
 	    }
+	  else
+	    /* We are going to be defining the function symbol on the
+	       plt stub, so no dyn_relocs needed when non-pic.  */
+	    h->non_got_ref = 0;
 	}
       h->protected_def = 0;
       /* Function symbols can't have copy relocs.  */
@@ -5591,16 +5611,12 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	  && htab->params->pic_fixup == 0
 	  && info->disable_target_specific_optimizations <= 1)
 	htab->params->pic_fixup = 1;
-      h->non_got_ref = 0;
       return TRUE;
     }
 
   /* If -z nocopyreloc was given, we won't generate them either.  */
   if (info->nocopyreloc)
-    {
-      h->non_got_ref = 0;
-      return TRUE;
-    }
+    return TRUE;
 
    /* If we didn't find any dynamic relocs in read-only sections, then
       we'll be keeping the dynamic relocs and avoiding the copy reloc.
@@ -5613,10 +5629,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       && !htab->is_vxworks
       && !h->def_regular
       && !readonly_dynrelocs (h))
-    {
-      h->non_got_ref = 0;
-      return TRUE;
-    }
+    return TRUE;
 
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
@@ -5658,6 +5671,8 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
+  /* We no longer want dyn_relocs.  */
+  h->non_got_ref = 0;
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -5886,8 +5901,18 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       && h->type != STT_GNU_IFUNC)
     eh->dyn_relocs = NULL;
 
+  /* Discard relocs on undefined symbols that must be local.  */
+  else if (h->root.type == bfd_link_hash_undefined
+	   && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+    eh->dyn_relocs = NULL;
+
+  /* Also discard relocs on undefined weak syms with non-default
+     visibility, or when dynamic_undefined_weak says so.  */
+  else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+    eh->dyn_relocs = NULL;
+
   if (eh->dyn_relocs == NULL)
-    ;
+    h->non_got_ref = 0;
 
   /* In the shared -Bsymbolic case, discard space allocated for
      dynamic pc-relative relocs against symbols which turn out to be
@@ -5896,23 +5921,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
      changes.  */
   else if (bfd_link_pic (info))
     {
-      /* Discard relocs on undefined symbols that must be local.  */
-      if (h->root.type == bfd_link_hash_undefined
-	  && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-	eh->dyn_relocs = NULL;
-
-      /* Also discard relocs on undefined weak syms with non-default
-	 visibility, or when dynamic_undefined_weak says so.  */
-      else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
-	eh->dyn_relocs = NULL;
-
       /* Relocs that use pc_count are those that appear on a call insn,
 	 or certain REL relocs (see must_be_dyn_reloc) that can be
 	 generated via assembly.  We want calls to protected symbols to
 	 resolve directly to the function rather than going via the plt.
 	 If people want function pointer comparisons to work as expected
 	 then they should avoid writing weird assembly.  */
-      else if (SYMBOL_CALLS_LOCAL (info, h))
+      if (SYMBOL_CALLS_LOCAL (info, h))
 	{
 	  struct elf_dyn_relocs **pp;
 
@@ -5952,8 +5967,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       /* For the non-pic case, discard space for relocs against
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
-      if (!h->non_got_ref
+      if (h->dynamic_adjusted
+	  && h->non_got_ref
 	  && !h->def_regular
+	  && !ELF_COMMON_DEF_P (h)
 	  && !(h->protected_def
 	       && eh->has_addr16_ha
 	       && eh->has_addr16_lo
@@ -5964,10 +5981,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	    return FALSE;
 
 	  if (h->dynindx == -1)
-	    eh->dyn_relocs = NULL;
+	    {
+	      h->non_got_ref = 0;
+	      eh->dyn_relocs = NULL;
+	    }
 	}
       else
-	eh->dyn_relocs = NULL;
+	{
+	  h->non_got_ref = 0;
+	  eh->dyn_relocs = NULL;
+	}
     }
 
   /* Allocate space.  */
@@ -8743,13 +8766,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
 	      || (ELIMINATE_COPY_RELOCS
 		  && !bfd_link_pic (info)
 		  && h != NULL
-		  && h->dynindx != -1
-		  && !h->non_got_ref
-		  && !h->def_regular
-		  && !(h->protected_def
-		       && ppc_elf_hash_entry (h)->has_addr16_ha
-		       && ppc_elf_hash_entry (h)->has_addr16_lo
-		       && htab->params->pic_fixup > 0)))
+		  && h->non_got_ref))
 	    {
 	      int skip;
 	      bfd_byte *loc;
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 1cf7964..181bbdc 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -7177,6 +7177,23 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       || h->type == STT_GNU_IFUNC
       || h->needs_plt)
     {
+      bfd_boolean local = (((struct ppc_link_hash_entry *) h)->save_res
+			   || SYMBOL_CALLS_LOCAL (info, h)
+			   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+      /* Discard dyn_relocs when non-pic if we've decided that a
+	 function symbol is local and not an ifunc.  We keep dynamic
+	 relocs for ifuncs when local rather than always emitting a
+	 plt call stub for them and defining the symbol on the call
+	 stub.  We can't do that for ELFv1 anyway (a function symbol
+	 is defined on a descriptor, not code) and it can be faster at
+	 run-time due to not needing to bounce through a stub.  The
+	 dyn_relocs for ifuncs will be applied even in a static
+	 executable.  */
+      if (!bfd_link_pic (info)
+	  && h->type != STT_GNU_IFUNC
+	  && local)
+	((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL;
+
       /* Clear procedure linkage table information for any symbol that
 	 won't need a .plt entry.  */
       struct plt_entry *ent;
@@ -7184,24 +7201,11 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	if (ent->plt.refcount > 0)
 	  break;
       if (ent == NULL
-	  || (h->type != STT_GNU_IFUNC
-	      && (SYMBOL_CALLS_LOCAL (info, h)
-		  || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))
-	  || ((struct ppc_link_hash_entry *) h)->save_res)
+	  || (h->type != STT_GNU_IFUNC && local))
 	{
 	  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)
 	{
@@ -7212,16 +7216,20 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	     relocs is that calling via a global entry stub costs a
 	     few more instructions, and pointer_equality_needed causes
 	     extra work in ld.so when resolving these symbols.  */
-	  if (global_entry_stub (h)
-	      && !alias_readonly_dynrelocs (h))
+	  if (global_entry_stub (h))
 	    {
-	      h->pointer_equality_needed = 0;
-	      /* 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 (!alias_readonly_dynrelocs (h))
+		{
+		  h->pointer_equality_needed = 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;
+		}
+	      else if (!bfd_link_pic (info))
+		/* We are going to be defining the function symbol on the
+		   plt stub, so no dyn_relocs needed when non-pic.  */
+		((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL;
 	    }
 
 	  /* ELFv2 function symbols can't have copy relocs.  */
@@ -7234,7 +7242,6 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	     plt entry.  */
 	  h->plt.plist = NULL;
 	  h->pointer_equality_needed = 0;
-	  h->non_got_ref = 0;
 	  return TRUE;
 	}
     }
@@ -7282,10 +7289,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	 definition for the variable.  Text relocations are preferable
 	 to an incorrect program.  */
       || h->protected_def)
-    {
-      h->non_got_ref = 0;
-      return TRUE;
-    }
+    return TRUE;
 
   if (h->plt.plist != NULL)
     {
@@ -7333,6 +7337,8 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
+  /* We no longer want dyn_relocs.  */
+  ((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL;
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -9724,6 +9730,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       && h->type != STT_GNU_IFUNC)
     eh->dyn_relocs = NULL;
 
+  /* Discard relocs on undefined symbols that must be local.  */
+  else if (h->root.type == bfd_link_hash_undefined
+	   && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+    eh->dyn_relocs = NULL;
+
   /* Also discard relocs on undefined weak syms with non-default
      visibility, or when dynamic_undefined_weak says so.  */
   else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
@@ -9768,36 +9779,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 		return FALSE;
 	    }
 	}
-      else if (h->type == STT_GNU_IFUNC)
-	{
-	  /* A plt entry is always created when making direct calls to
-	     an ifunc, even when building a static executable, but
-	     that doesn't cover all cases.  We may have only an ifunc
-	     initialised function pointer for a given ifunc symbol.
-
-	     For ELFv2, dynamic relocations are not required when
-	     generating a global entry PLT stub.  */
-	  if (abiversion (info->output_bfd) >= 2)
-	    {
-	      if (global_entry_stub (h))
-		eh->dyn_relocs = NULL;
-	    }
-
-	  /* For ELFv1 we have function descriptors.  Descriptors need
-	     to be treated like PLT entries and thus have dynamic
-	     relocations.  One exception is when the function
-	     descriptor is copied into .dynbss (which should only
-	     happen with ancient versions of gcc).  */
-	  else if (h->needs_copy)
-	    eh->dyn_relocs = NULL;
-	}
-      else if (ELIMINATE_COPY_RELOCS)
+      else if (ELIMINATE_COPY_RELOCS && h->type != STT_GNU_IFUNC)
 	{
 	  /* For the non-pic case, discard space for relocs against
 	     symbols which turn out to need copy relocs or are not
 	     dynamic.  */
-	  if (!h->non_got_ref
-	      && !h->def_regular)
+	  if (h->dynamic_adjusted
+	      && !h->def_regular
+	      && !ELF_COMMON_DEF_P (h))
 	    {
 	      /* Make sure this symbol is output as a dynamic symbol.  */
 	      if (!ensure_undef_dynamic (info, h))


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