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/binutils-2_29-branch] Make undefined symbols in allocate_dynrelocs dynamic


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

commit 3c08b8dcc22a1b7a7fcbce7a6d8f863ff1a3a83e
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Aug 23 08:58:08 2017 +0930

    Make undefined symbols in allocate_dynrelocs dynamic
    
    ..if they have dynamic relocs.  An undefined symbol in a PIC object
    that finds no definition ought to become dynamic in order to support
    --allow-shlib-undefined, but there is nothing in the generic ELF
    linker code to do this if the reference isn't via the GOT or PLT.  (An
    initialized function pointer is an example.)  So it falls to backend
    code to ensure the symbol is made dynamic.
    
    	PR 21988
    	* elf64-ppc.c (ensure_undef_dynamic): Rename from
    	ensure_undefweak_dynamic.  Handle undefined too.
    	* elf32-ppc.c (ensure_undef_dynamic): Likewise.
    	* elf32-hppa.c (ensure_undef_dynamic): Likewise.
    	(allocate_dynrelocs): Discard undefined non-default visibility
    	relocs first.  Make undefined syms dynamic.  Tidy goto.

Diff:
---
 bfd/ChangeLog    | 10 ++++++++++
 bfd/elf32-hppa.c | 51 +++++++++++++++++++++++++--------------------------
 bfd/elf32-ppc.c  | 26 ++++++++++++--------------
 bfd/elf64-ppc.c  | 26 ++++++++++++--------------
 4 files changed, 59 insertions(+), 54 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index aaec44d..c5739ae 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2017-08-23  Alan Modra  <amodra@gmail.com>
+
+	PR 21988
+	* elf64-ppc.c (ensure_undef_dynamic): Rename from
+	ensure_undefweak_dynamic.  Handle undefined too.
+	* elf32-ppc.c (ensure_undef_dynamic): Likewise.
+	* elf32-hppa.c (ensure_undef_dynamic): Likewise.
+	(allocate_dynrelocs): Discard undefined non-default visibility
+	relocs first.  Make undefined syms dynamic.  Tidy goto.
+
 2017-08-21  Alan Modra  <amodra@gmail.com>
 	    H.J. Lu  <hongjiu.lu@intel.com>
 
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index 0b7f434..548d656 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -1919,16 +1919,20 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   return _bfd_elf_adjust_dynamic_copy (info, eh, sec);
 }
 
-/* Make an undefined weak symbol dynamic.  */
+/* If EH is undefined, make it dynamic if that makes sense.  */
 
 static bfd_boolean
-ensure_undef_weak_dynamic (struct bfd_link_info *info,
-			   struct elf_link_hash_entry *eh)
+ensure_undef_dynamic (struct bfd_link_info *info,
+		      struct elf_link_hash_entry *eh)
 {
-  if (eh->dynindx == -1
+  struct elf_link_hash_table *htab = elf_hash_table (info);
+
+  if (htab->dynamic_sections_created
+      && (eh->root.type == bfd_link_hash_undefweak
+	  || eh->root.type == bfd_link_hash_undefined)
+      && eh->dynindx == -1
       && !eh->forced_local
       && eh->type != STT_PARISC_MILLI
-      && eh->root.type == bfd_link_hash_undefweak
       && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT)
     return bfd_elf_link_record_dynamic_symbol (info, eh);
   return TRUE;
@@ -1957,7 +1961,7 @@ allocate_plt_static (struct elf_link_hash_entry *eh, void *inf)
   if (htab->etab.dynamic_sections_created
       && eh->plt.refcount > 0)
     {
-      if (!ensure_undef_weak_dynamic (info, eh))
+      if (!ensure_undef_dynamic (info, eh))
 	return FALSE;
 
       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), eh))
@@ -2034,7 +2038,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 
   if (eh->got.refcount > 0)
     {
-      if (!ensure_undef_weak_dynamic (info, eh))
+      if (!ensure_undef_dynamic (info, eh))
 	return FALSE;
 
       sec = htab->etab.sgot;
@@ -2070,8 +2074,14 @@ 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
+	   || eh->root.type == bfd_link_hash_undefweak)
+	  && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+	hh->dyn_relocs = NULL;
+
 #if RELATIVE_DYNRELOCS
-      if (SYMBOL_CALLS_LOCAL (info, eh))
+      else if (SYMBOL_CALLS_LOCAL (info, eh))
 	{
 	  struct elf32_hppa_dyn_reloc_entry **hdh_pp;
 
@@ -2087,15 +2097,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 	}
 #endif
 
-      /* Also discard relocs on undefined weak syms with non-default
-	 visibility.  */
-      if (hh->dyn_relocs != NULL
-	  && eh->root.type == bfd_link_hash_undefweak)
+      if (hh->dyn_relocs != NULL)
 	{
-	  if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
-	    hh->dyn_relocs = NULL;
-
-	  else if (!ensure_undef_weak_dynamic (info, eh))
+	  if (!ensure_undef_dynamic (info, eh))
 	    return FALSE;
 	}
     }
@@ -2113,19 +2117,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 		   && (eh->root.type == bfd_link_hash_undefweak
 		       || eh->root.type == bfd_link_hash_undefined))))
 	{
-	  if (!ensure_undef_weak_dynamic (info, eh))
+	  if (!ensure_undef_dynamic (info, eh))
 	    return FALSE;
 
-	  /* If that succeeded, we know we'll be keeping all the
-	     relocs.  */
-	  if (eh->dynindx != -1)
-	    goto keep;
+	  if (eh->dynindx == -1)
+	    hh->dyn_relocs = NULL;
 	}
-
-      hh->dyn_relocs = NULL;
-      return TRUE;
-
-    keep: ;
+      else
+	hh->dyn_relocs = NULL;
     }
 
   /* Finally, allocate space.  */
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 8a00fb4..f9a32c2 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5942,17 +5942,18 @@ allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need)
   return where;
 }
 
-/* If H is undefined weak, make it dynamic if that makes sense.  */
+/* If H is undefined, make it dynamic if that makes sense.  */
 
 static bfd_boolean
-ensure_undefweak_dynamic (struct bfd_link_info *info,
-			  struct elf_link_hash_entry *h)
+ensure_undef_dynamic (struct bfd_link_info *info,
+		      struct elf_link_hash_entry *h)
 {
   struct elf_link_hash_table *htab = elf_hash_table (info);
 
   if (htab->dynamic_sections_created
-      && info->dynamic_undefined_weak != 0
-      && h->root.type == bfd_link_hash_undefweak
+      && ((info->dynamic_undefined_weak != 0
+	   && h->root.type == bfd_link_hash_undefweak)
+	  || h->root.type == bfd_link_hash_undefined)
       && h->dynindx == -1
       && !h->forced_local
       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
@@ -5986,9 +5987,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     {
       unsigned int need;
 
-      /* Make sure this symbol is output as a dynamic symbol.
-	 Undefined weak syms won't yet be marked as dynamic.  */
-      if (!ensure_undefweak_dynamic (info, &eh->elf))
+      /* Make sure this symbol is output as a dynamic symbol.  */
+      if (!ensure_undef_dynamic (info, &eh->elf))
 	return FALSE;
 
       need = 0;
@@ -6102,9 +6102,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
       if (eh->dyn_relocs != NULL)
 	{
-	  /* Make sure undefined weak symbols are output as a dynamic
-	     symbol in PIEs.  */
-	  if (!ensure_undefweak_dynamic (info, h))
+	  /* Make sure this symbol is output as a dynamic symbol.  */
+	  if (!ensure_undef_dynamic (info, h))
 	    return FALSE;
 	}
     }
@@ -6120,9 +6119,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	       && eh->has_addr16_lo
 	       && htab->params->pic_fixup > 0))
 	{
-	  /* Make sure this symbol is output as a dynamic symbol.
-	     Undefined weak syms won't yet be marked as dynamic.  */
-	  if (!ensure_undefweak_dynamic (info, h))
+	  /* Make sure this symbol is output as a dynamic symbol.  */
+	  if (!ensure_undef_dynamic (info, h))
 	    return FALSE;
 
 	  if (h->dynindx == -1)
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 55a6728..4ff3f06 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -9743,17 +9743,18 @@ merge_got_entries (struct got_entry **pent)
 	  }
 }
 
-/* If H is undefined weak, make it dynamic if that makes sense.  */
+/* If H is undefined, make it dynamic if that makes sense.  */
 
 static bfd_boolean
-ensure_undefweak_dynamic (struct bfd_link_info *info,
-			  struct elf_link_hash_entry *h)
+ensure_undef_dynamic (struct bfd_link_info *info,
+		      struct elf_link_hash_entry *h)
 {
   struct elf_link_hash_table *htab = elf_hash_table (info);
 
   if (htab->dynamic_sections_created
-      && info->dynamic_undefined_weak != 0
-      && h->root.type == bfd_link_hash_undefweak
+      && ((info->dynamic_undefined_weak != 0
+	   && h->root.type == bfd_link_hash_undefweak)
+	  || h->root.type == bfd_link_hash_undefined)
       && h->dynindx == -1
       && !h->forced_local
       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
@@ -9832,9 +9833,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   for (gent = h->got.glist; gent != NULL; gent = gent->next)
     if (!gent->is_indirect)
       {
-	/* Make sure this symbol is output as a dynamic symbol.
-	   Undefined weak syms won't yet be marked as dynamic.  */
-	if (!ensure_undefweak_dynamic (info, h))
+	/* Make sure this symbol is output as a dynamic symbol.  */
+	if (!ensure_undef_dynamic (info, h))
 	  return FALSE;
 
 	if (!is_ppc64_elf (gent->owner))
@@ -9888,9 +9888,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
 	  if (eh->dyn_relocs != NULL)
 	    {
-	      /* Make sure this symbol is output as a dynamic symbol.
-		 Undefined weak syms won't yet be marked as dynamic.  */
-	      if (!ensure_undefweak_dynamic (info, h))
+	      /* Make sure this symbol is output as a dynamic symbol.  */
+	      if (!ensure_undef_dynamic (info, h))
 		return FALSE;
 	    }
 	}
@@ -9925,9 +9924,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  if (!h->non_got_ref
 	      && !h->def_regular)
 	    {
-	      /* Make sure this symbol is output as a dynamic symbol.
-		 Undefined weak syms won't yet be marked as dynamic.  */
-	      if (!ensure_undefweak_dynamic (info, h))
+	      /* Make sure this symbol is output as a dynamic symbol.  */
+	      if (!ensure_undef_dynamic (info, h))
 		return FALSE;
 
 	      if (h->dynindx == -1)


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