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] Fix hppa-linux pr22269-1 fail


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

commit d336fa6d820f50235c271ea327fadbf4ff6e1edd
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Oct 27 15:04:25 2017 +1030

    Fix hppa-linux pr22269-1 fail
    
    Adds UNDEFWEAK_NO_DYNAMIC_RELOC in the rest of places needed in this
    file, reduces dynamic relocations in a number of cases, and removes
    some bogus code that was attempting to handle dynamic common symbols
    specially.
    
    	PR 22269
    	* elf32-hppa.c (elf32_hppa_check_relocs): Move SEC_ALLOC test to
    	ensure non_got_ref is not set due to debug references.
    	(elf32_hppa_adjust_dynamic_symbol): Tidy plabel handling.  Use
    	SYMBOL_CALLS_LOCAL and UNDEFWEAK_NO_DYNAMIC_RELOC when determining
    	need for a plt entry.
    	(allocate_dynrelocs): Similarly for got entries.  Tidy code discarding
    	dynamic relocs when pic.  Remove bogus code attempting to handle
    	commons.
    	(elf32_hppa_relocate_section): Similarly.  Delete resolved_to_zero
    	and simplify.
    	(elf32_hppa_finish_dynamic_symbol): Use UNDEFWEAK_NO_DYNAMIC_RELOC
    	and SYMBOL_REFERENCES_LOCAL in GOT handling.

Diff:
---
 bfd/ChangeLog    |  16 ++++++
 bfd/elf32-hppa.c | 157 +++++++++++++++++++++++++++----------------------------
 2 files changed, 92 insertions(+), 81 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 07ad2b8..c56e1cf 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,19 @@
+2017-10-30  Alan Modra  <amodra@gmail.com>
+
+	PR 22269
+	* elf32-hppa.c (elf32_hppa_check_relocs): Move SEC_ALLOC test to
+	ensure non_got_ref is not set due to debug references.
+	(elf32_hppa_adjust_dynamic_symbol): Tidy plabel handling.  Use
+	SYMBOL_CALLS_LOCAL and UNDEFWEAK_NO_DYNAMIC_RELOC when determining
+	need for a plt entry.
+	(allocate_dynrelocs): Similarly for got entries.  Tidy code discarding
+	dynamic relocs when pic.  Remove bogus code attempting to handle
+	commons.
+	(elf32_hppa_relocate_section): Similarly.  Delete resolved_to_zero
+	and simplify.
+	(elf32_hppa_finish_dynamic_symbol): Use UNDEFWEAK_NO_DYNAMIC_RELOC
+	and SYMBOL_REFERENCES_LOCAL in GOT handling.
+
 2017-10-28  Alan Modra  <amodra@gmail.com>
 
 	PR 22300
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index 97b6026..be88d87 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -1423,7 +1423,8 @@ elf32_hppa_check_relocs (bfd *abfd,
 	    }
 	}
 
-      if (need_entry & NEED_DYNREL)
+      if ((need_entry & NEED_DYNREL) != 0
+	  && (sec->flags & SEC_ALLOC) != 0)
 	{
 	  /* Flag this symbol as having a non-got, non-plt reference
 	     so that we generate copy relocs if it turns out to be
@@ -1460,7 +1461,6 @@ elf32_hppa_check_relocs (bfd *abfd,
 	     dynamic library if we manage to avoid copy relocs for the
 	     symbol.  */
 	  if ((bfd_link_pic (info)
-	       && (sec->flags & SEC_ALLOC) != 0
 	       && (IS_ABSOLUTE_RELOC (r_type)
 		   || (hh != NULL
 		       && (!SYMBOLIC_BIND (info, &hh->eh)
@@ -1468,7 +1468,6 @@ elf32_hppa_check_relocs (bfd *abfd,
 			   || !hh->eh.def_regular))))
 	      || (ELIMINATE_COPY_RELOCS
 		  && !bfd_link_pic (info)
-		  && (sec->flags & SEC_ALLOC) != 0
 		  && hh != NULL
 		  && (hh->eh.root.type == bfd_link_hash_defweak
 		      || !hh->eh.def_regular)))
@@ -1680,15 +1679,12 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
       /* 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
 	 hide_symbol can be called before the plabel flag is set.  */
-      if (hppa_elf_hash_entry (eh)->plabel
-	  && eh->plt.refcount <= 0)
+      if (hppa_elf_hash_entry (eh)->plabel)
 	eh->plt.refcount = 1;
 
-      if (eh->plt.refcount <= 0
-	  || (eh->def_regular
-	      && eh->root.type != bfd_link_hash_defweak
-	      && ! hppa_elf_hash_entry (eh)->plabel
-	      && (!bfd_link_pic (info) || SYMBOLIC_BIND (info, eh))))
+      else if (eh->plt.refcount <= 0
+	       || SYMBOL_CALLS_LOCAL (info, eh)
+	       || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
 	{
 	  /* The .plt entry is not needed when:
 	     a) Garbage collection has removed all references to the
@@ -1929,7 +1925,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
       if (htab->etab.dynamic_sections_created
 	  && (bfd_link_pic (info)
 	      || (eh->dynindx != -1
-		  && !eh->forced_local)))
+		  && !SYMBOL_REFERENCES_LOCAL (info, eh)))
+	  && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
 	{
 	  htab->etab.srelgot->size += sizeof (Elf32_External_Rela);
 	  if ((hh->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
@@ -1941,6 +1938,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
   else
     eh->got.offset = (bfd_vma) -1;
 
+  /* If no dynamic sections we can't have dynamic relocs.  */
+  if (!htab->etab.dynamic_sections_created)
+    hh->dyn_relocs = NULL;
+
   if (hh->dyn_relocs == NULL)
     return TRUE;
 
@@ -1953,9 +1954,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
     {
       /* 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
-	      || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh)))
+	   && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+	  || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
 	hh->dyn_relocs = NULL;
 
 #if RELATIVE_DYNRELOCS
@@ -1981,19 +1981,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 	    return FALSE;
 	}
     }
-  else
+  else if (ELIMINATE_COPY_RELOCS)
     {
       /* For the non-shared case, discard space for relocs against
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
 
       if (!eh->non_got_ref
-	  && ((ELIMINATE_COPY_RELOCS
-	       && eh->def_dynamic
-	       && !eh->def_regular)
-	       || (htab->etab.dynamic_sections_created
-		   && (eh->root.type == bfd_link_hash_undefweak
-		       || eh->root.type == bfd_link_hash_undefined))))
+	  && !eh->def_regular)
 	{
 	  if (!ensure_undef_dynamic (info, eh))
 	    return FALSE;
@@ -3550,7 +3545,6 @@ elf32_hppa_relocate_section (bfd *output_bfd,
       const char *sym_name;
       bfd_boolean plabel;
       bfd_boolean warned_undef;
-      bfd_boolean resolved_to_zero;
 
       r_type = ELF32_R_TYPE (rela->r_info);
       if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
@@ -3614,9 +3608,6 @@ elf32_hppa_relocate_section (bfd *output_bfd,
       if (bfd_link_relocatable (info))
 	continue;
 
-      resolved_to_zero = (hh != NULL
-			  && UNDEFWEAK_NO_DYNAMIC_RELOC (info, &hh->eh));
-
       /* Do any required modifications to the relocation value, and
 	 determine what types of dynamic info we need to output, if
 	 any.  */
@@ -3628,7 +3619,8 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 	case R_PARISC_DLTIND21L:
 	  {
 	    bfd_vma off;
-	    bfd_boolean do_got = 0;
+	    bfd_boolean do_got = FALSE;
+	    bfd_boolean reloc = bfd_link_pic (info);
 
 	    /* Relocation is to the entry for this symbol in the
 	       global offset table.  */
@@ -3638,9 +3630,14 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 
 		off = hh->eh.got.offset;
 		dyn = htab->etab.dynamic_sections_created;
-		if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
-						       bfd_link_pic (info),
-						       &hh->eh))
+		reloc = (!UNDEFWEAK_NO_DYNAMIC_RELOC (info, &hh->eh)
+			 && (reloc
+			     || (hh->eh.dynindx != -1
+				 && !SYMBOL_REFERENCES_LOCAL (info, &hh->eh))));
+		if (!reloc
+		    || !WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+							 bfd_link_pic (info),
+							 &hh->eh))
 		  {
 		    /* If we aren't going to call finish_dynamic_symbol,
 		       then we need to handle initialisation of the .got
@@ -3653,7 +3650,7 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 		    else
 		      {
 			hh->eh.got.offset |= 1;
-			do_got = 1;
+			do_got = TRUE;
 		      }
 		  }
 	      }
@@ -3673,13 +3670,13 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 		else
 		  {
 		    local_got_offsets[r_symndx] |= 1;
-		    do_got = 1;
+		    do_got = TRUE;
 		  }
 	      }
 
 	    if (do_got)
 	      {
-		if (bfd_link_pic (info))
+		if (reloc)
 		  {
 		    /* Output a dynamic relocation for this GOT entry.
 		       In this case it is relative to the base of the
@@ -3838,29 +3835,20 @@ elf32_hppa_relocate_section (bfd *output_bfd,
 	     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 you squint, the non-shared test
-	     here does indeed match the one in ..check_relocs, the
-	     difference being that here we test DEF_DYNAMIC as well as
-	     !DEF_REGULAR.  All common syms end up with !DEF_REGULAR,
-	     which is why we can't use just that test here.
-	     Conversely, DEF_DYNAMIC can't be used in check_relocs as
-	     there all files have not been loaded.  */
+	     allocate_dynrelocs.  */
 	  if ((bfd_link_pic (info)
-	       && (hh == NULL
-		   || (ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT
-		       && !resolved_to_zero)
-		   || hh->eh.root.type != bfd_link_hash_undefweak)
+	       && !(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)))
-	      || (!bfd_link_pic (info)
+	      || (ELIMINATE_COPY_RELOCS
+		  && !bfd_link_pic (info)
 		  && hh != NULL
 		  && hh->eh.dynindx != -1
 		  && !hh->eh.non_got_ref
-		  && ((ELIMINATE_COPY_RELOCS
-		       && hh->eh.def_dynamic
-		       && !hh->eh.def_regular)
-		      || hh->eh.root.type == bfd_link_hash_undefweak
-		      || hh->eh.root.type == bfd_link_hash_undefined)))
+		  && !hh->eh.def_regular))
 	    {
 	      Elf_Internal_Rela outrel;
 	      bfd_boolean skip;
@@ -4258,42 +4246,49 @@ elf32_hppa_finish_dynamic_symbol (bfd *output_bfd,
 
   if (eh->got.offset != (bfd_vma) -1
       && (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_GD) == 0
-      && (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_IE) == 0)
+      && (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_IE) == 0
+      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh))
     {
-      /* This symbol has an entry in the global offset table.  Set it
-	 up.  */
-
-      rela.r_offset = ((eh->got.offset &~ (bfd_vma) 1)
-		      + htab->etab.sgot->output_offset
-		      + htab->etab.sgot->output_section->vma);
-
-      /* If this is a -Bsymbolic link and the symbol is defined
-	 locally or was forced to be local because of a version file,
-	 we just want to emit a RELATIVE reloc.  The entry in the
-	 global offset table will already have been initialized in the
-	 relocate_section function.  */
-      if (bfd_link_pic (info)
-	  && (SYMBOLIC_BIND (info, eh) || eh->dynindx == -1)
-	  && eh->def_regular)
-	{
-	  rela.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
-	  rela.r_addend = (eh->root.u.def.value
-			  + eh->root.u.def.section->output_offset
-			  + eh->root.u.def.section->output_section->vma);
-	}
-      else
+      bfd_boolean is_dyn = (eh->dynindx != -1
+			    && !SYMBOL_REFERENCES_LOCAL (info, eh));
+
+      if (is_dyn || bfd_link_pic (info))
 	{
-	  if ((eh->got.offset & 1) != 0)
-	    abort ();
+	  /* This symbol has an entry in the global offset table.  Set
+	     it up.  */
+
+	  rela.r_offset = ((eh->got.offset &~ (bfd_vma) 1)
+			   + htab->etab.sgot->output_offset
+			   + htab->etab.sgot->output_section->vma);
+
+	  /* If this is a -Bsymbolic link and the symbol is defined
+	     locally or was forced to be local because of a version
+	     file, we just want to emit a RELATIVE reloc.  The entry
+	     in the global offset table will already have been
+	     initialized in the relocate_section function.  */
+	  if (!is_dyn)
+	    {
+	      rela.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
+	      rela.r_addend = (eh->root.u.def.value
+			       + eh->root.u.def.section->output_offset
+			       + eh->root.u.def.section->output_section->vma);
+	    }
+	  else
+	    {
+	      if ((eh->got.offset & 1) != 0)
+		abort ();
 
-	  bfd_put_32 (output_bfd, 0, htab->etab.sgot->contents + (eh->got.offset & ~1));
-	  rela.r_info = ELF32_R_INFO (eh->dynindx, R_PARISC_DIR32);
-	  rela.r_addend = 0;
-	}
+	      bfd_put_32 (output_bfd, 0,
+			  htab->etab.sgot->contents + (eh->got.offset & ~1));
+	      rela.r_info = ELF32_R_INFO (eh->dynindx, R_PARISC_DIR32);
+	      rela.r_addend = 0;
+	    }
 
-      loc = htab->etab.srelgot->contents;
-      loc += htab->etab.srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
-      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+	  loc = htab->etab.srelgot->contents;
+	  loc += (htab->etab.srelgot->reloc_count++
+		  * sizeof (Elf32_External_Rela));
+	  bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+	}
     }
 
   if (eh->needs_copy)


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