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]

Don't move weak alias dyn_relocs to weakdef


I did this for powerpc64 a while ago.  Not moving weak symbol
dyn_relocs to the strong alias makes for a much simpler test for
dynamic relocs in relocate_section.

This patch implements the change for powerpc and hppa.  Other targets
could benefit from similar changes.

	* elf32-hppa.c (pc_dynrelocs): Define.
	(elf32_hppa_copy_indirect_symbol): Don't copy dyn_relocs to weakdefs.
	(alias_readonly_dynrelocs): New function.
	(elf32_hppa_adjust_dynamic_symbol): Don't clear non_got_ref to
	indicate dyn_relocs should be discarded, discard them here.
	Use alias_readonly_dynrelocs.
	(allocate_dynrelocs): Don't test or clear non_got_ref.
	(elf32_hppa_relocate_section): Simplify test for dynamic relocs.
	* elf32-ppc.c (ppc_elf_copy_indirect_symbol): Don't copy dyn_relocs
	to weakdefs.
	(alias_readonly_dynrelocs, pc_dynrelocs): New functions.
	(ppc_elf_adjust_dynamic_symbol): Don't clear non_got_ref to
	indicate dyn_relocs should be discarded, discard them here.
	Use alias_readonly_dynrelocs.
	(allocate_dynrelocs): Don't test or clear non_got_ref.
	(ppc_elf_relocate_section): Simplify test for dynamic relocs.

diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index 01060db..a0f7060 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -162,6 +162,7 @@ static const bfd_byte plt_stub[] =
 #ifndef RELATIVE_DYNRELOCS
 #define RELATIVE_DYNRELOCS 0
 #define IS_ABSOLUTE_RELOC(r_type) 1
+#define pc_dynrelocs(hh) 0
 #endif
 
 /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
@@ -1020,7 +1021,8 @@ elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info,
   hh_dir = hppa_elf_hash_entry (eh_dir);
   hh_ind = hppa_elf_hash_entry (eh_ind);
 
-  if (hh_ind->dyn_relocs != NULL)
+  if (hh_ind->dyn_relocs != NULL
+      && eh_ind->root.type == bfd_link_hash_indirect)
     {
       if (hh_dir->dyn_relocs != NULL)
 	{
@@ -1674,6 +1676,24 @@ readonly_dynrelocs (struct elf_link_hash_entry *eh)
   return NULL;
 }
 
+/* Return true if we have dynamic relocs against H or any of its weak
+   aliases, that apply to read-only sections.  Cannot be used after
+   size_dynamic_sections.  */
+
+static bfd_boolean
+alias_readonly_dynrelocs (struct elf_link_hash_entry *eh)
+{
+  struct elf32_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+  do
+    {
+      if (readonly_dynrelocs (&hh->eh))
+	return TRUE;
+      hh = hppa_elf_hash_entry (hh->eh.u.alias);
+    } while (hh != NULL && &hh->eh != eh);
+
+  return FALSE;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -1692,23 +1712,12 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (eh->type == STT_FUNC
       || eh->needs_plt)
     {
-      /* 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
-	 definition" for non-function symbols may be due to creating a
-	 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.  */
       bfd_boolean local = (SYMBOL_CALLS_LOCAL (info, eh)
 			   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh));
-      /* Arrange to discard dyn_relocs if we've decided that a
+      /* Discard dyn_relocs when non-pic if we've decided that a
 	 function symbol is local.  */
-      if (local)
-	eh->non_got_ref = 0;
+      if (!bfd_link_pic (info) && local)
+	hppa_elf_hash_entry (eh)->dyn_relocs = NULL;
 
       /* 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
@@ -1732,6 +1741,11 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
 	  eh->needs_plt = 0;
 	}
 
+      /* 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.  ie. dyn_relocs can't
+	 be discarded.  */
+
       /* Function symbols can't have copy relocs.  */
       return TRUE;
     }
@@ -1772,7 +1786,7 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
     return TRUE;
 
   if (ELIMINATE_COPY_RELOCS
-      && !readonly_dynrelocs (eh))
+      && !alias_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.  */
@@ -1813,7 +1827,7 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
     }
 
   /* We no longer want dyn_relocs.  */
-  eh->non_got_ref = 0;
+  hppa_elf_hash_entry (eh)->dyn_relocs = NULL;
   return _bfd_elf_adjust_dynamic_copy (info, eh, sec);
 }
 
@@ -2005,10 +2019,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
     hh->dyn_relocs = NULL;
 
   if (hh->dyn_relocs == NULL)
-    {
-      eh->non_got_ref = 0;
-      return TRUE;
-    }
+    return TRUE;
 
   /* If this is a -Bsymbolic shared link, then we need to discard all
      space allocated for dynamic pc-relative relocs against symbols
@@ -2047,7 +2058,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 	 dynamic.  */
 
       if (eh->dynamic_adjusted
-	  && eh->non_got_ref
 	  && !eh->def_regular
 	  && !ELF_COMMON_DEF_P (eh))
 	{
@@ -2055,16 +2065,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 	    return FALSE;
 
 	  if (eh->dynindx == -1)
-	    {
-	      eh->non_got_ref = 0;
-	      hh->dyn_relocs = NULL;
-	    }
+	    hh->dyn_relocs = NULL;
 	}
       else
-	{
-	  eh->non_got_ref = 0;
-	  hh->dyn_relocs = NULL;
-	}
+	hh->dyn_relocs = NULL;
     }
 
   /* Finally, allocate space.  */
@@ -3895,23 +3899,13 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
-	  /* The reloc types handled here and this conditional
-	     expression must match the code in ..check_relocs and
-	     allocate_dynrelocs.  ie. We need exactly the same condition
-	     as in ..check_relocs, with some extra conditions (dynindx
-	     test in this case) to cater for relocs removed by
-	     allocate_dynrelocs.  */
-	  if ((bfd_link_pic (info)
-	       && !(hh != NULL
-		    && ((hh->eh.root.type == bfd_link_hash_undefined
-			 && ELF_ST_VISIBILITY (hh->eh.other) != STV_DEFAULT)
-			|| UNDEFWEAK_NO_DYNAMIC_RELOC (info, &hh->eh)))
-	       && (IS_ABSOLUTE_RELOC (r_type)
-		   || !SYMBOL_CALLS_LOCAL (info, &hh->eh)))
-	      || (ELIMINATE_COPY_RELOCS
-		  && !bfd_link_pic (info)
-		  && hh != NULL
-		  && hh->eh.non_got_ref))
+	  if (bfd_link_pic (info)
+	      ? ((hh == NULL
+		  || hh->dyn_relocs != NULL)
+		 && ((hh != NULL && pc_dynrelocs (hh))
+		     || IS_ABSOLUTE_RELOC (r_type)))
+	      : (hh != NULL
+		 && hh->dyn_relocs != NULL))
 	    {
 	      Elf_Internal_Rela outrel;
 	      bfd_boolean skip;
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 756523b..81e5315 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -3594,6 +3594,10 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
   edir->elf.needs_plt |= eind->elf.needs_plt;
   edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
 
+  /* If we were called to copy over info for a weak sym, that's all.  */
+  if (eind->elf.root.type != bfd_link_hash_indirect)
+    return;
+
   if (eind->dyn_relocs != NULL)
     {
       if (edir->dyn_relocs != NULL)
@@ -3625,16 +3629,6 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
       eind->dyn_relocs = NULL;
     }
 
-  /* If we were called to copy over info for a weak sym, that's all.
-     You might think dyn_relocs need not be copied over;  After all,
-     both syms will be dynamic or both non-dynamic so we're just
-     moving reloc accounting around.  However, ELIMINATE_COPY_RELOCS
-     code in ppc_elf_adjust_dynamic_symbol needs to check for
-     dyn_relocs in read-only sections, and it does so on what is the
-     DIR sym here.  */
-  if (eind->elf.root.type != bfd_link_hash_indirect)
-    return;
-
   /* Copy over the GOT refcount entries that we may have already seen to
      the symbol which just became indirect.  */
   edir->elf.got.refcount += eind->elf.got.refcount;
@@ -5441,6 +5435,37 @@ readonly_dynrelocs (struct elf_link_hash_entry *h)
   return NULL;
 }
 
+/* Return true if we have dynamic relocs against H or any of its weak
+   aliases, that apply to read-only sections.  Cannot be used after
+   size_dynamic_sections.  */
+
+static bfd_boolean
+alias_readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct ppc_elf_link_hash_entry *eh = ppc_elf_hash_entry (h);
+  do
+    {
+      if (readonly_dynrelocs (&eh->elf))
+	return TRUE;
+      eh = ppc_elf_hash_entry (eh->elf.u.alias);
+    } while (eh != NULL && &eh->elf != h);
+
+  return FALSE;
+}
+
+/* Return whether H has pc-relative dynamic relocs.  */
+
+static bfd_boolean
+pc_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = ppc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    if (p->pc_count != 0)
+      return TRUE;
+  return FALSE;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -5474,35 +5499,12 @@ 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->is_weakalias
-			? weakdef (h)->non_got_ref
-			: !local && (((struct ppc_elf_link_hash_entry *) h)
-				     ->dyn_relocs != NULL));
+      /* Discard dyn_relocs when non-pic if we've decided that a
+	 function symbol is local.  */
+      if (!bfd_link_pic (info) && local)
+	ppc_elf_hash_entry (h)->dyn_relocs = NULL;
 
       /* Clear procedure linkage table information for any symbol that
 	 won't need a .plt entry.  */
@@ -5552,10 +5554,10 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	      if (!h->needs_plt)
 		h->plt.plist = NULL;
 	    }
-	  else
+	  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.  */
-	    h->non_got_ref = 0;
+	    ppc_elf_hash_entry (h)->dyn_relocs = NULL;
 	}
       h->protected_def = 0;
       /* Function symbols can't have copy relocs.  */
@@ -5628,7 +5630,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       && !ppc_elf_hash_entry (h)->has_sda_refs
       && !htab->is_vxworks
       && !h->def_regular
-      && !readonly_dynrelocs (h))
+      && !alias_readonly_dynrelocs (h))
     return TRUE;
 
   /* We must allocate the symbol in our .dynbss section, which will
@@ -5672,7 +5674,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
     }
 
   /* We no longer want dyn_relocs.  */
-  h->non_got_ref = 0;
+  ppc_elf_hash_entry (h)->dyn_relocs = NULL;
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -5912,7 +5914,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     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
@@ -5968,7 +5970,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
       if (h->dynamic_adjusted
-	  && h->non_got_ref
 	  && !h->def_regular
 	  && !ELF_COMMON_DEF_P (h)
 	  && !(h->protected_def
@@ -5981,16 +5982,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	    return FALSE;
 
 	  if (h->dynindx == -1)
-	    {
-	      h->non_got_ref = 0;
-	      eh->dyn_relocs = NULL;
-	    }
+	    eh->dyn_relocs = NULL;
 	}
       else
-	{
-	  h->non_got_ref = 0;
-	  eh->dyn_relocs = NULL;
-	}
+	eh->dyn_relocs = NULL;
     }
 
   /* Allocate space.  */
@@ -8756,17 +8751,13 @@ ppc_elf_relocate_section (bfd *output_bfd,
 	      || is_vxworks_tls)
 	    break;
 
-	  if ((bfd_link_pic (info)
-	       && !(h != NULL
-		    && ((h->root.type == bfd_link_hash_undefined
-			 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-			|| UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))
-	       && (must_be_dyn_reloc (info, r_type)
-		   || !SYMBOL_CALLS_LOCAL (info, h)))
-	      || (ELIMINATE_COPY_RELOCS
-		  && !bfd_link_pic (info)
-		  && h != NULL
-		  && h->non_got_ref))
+	  if (bfd_link_pic (info)
+	      ? ((h == NULL
+		  || ppc_elf_hash_entry (h)->dyn_relocs != NULL)
+		 && ((h != NULL && pc_dynrelocs (h))
+		     || must_be_dyn_reloc (info, r_type)))
+	      : (h != NULL
+		 && ppc_elf_hash_entry (h)->dyn_relocs != NULL))
 	    {
 	      int skip;
 	      bfd_byte *loc;

-- 
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]