[PATCH] X86-64: Allow copy relocs for building PIE

H.J. Lu hongjiu.lu@intel.com
Wed Dec 3 00:53:00 GMT 2014


On Tue, Dec 02, 2014 at 03:20:07PM -0800, H.J. Lu wrote:
> I am checking in this patch to allow copy relocs for non-GOT pc-relative
> relocation in PIE.  It makes bfd linker compatible with gold.
> 
> 
> H.J.
> ----
> bfd/
> 
> 	* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Always
> 	allow copy relocs for building executables.
> 	(elf_x86_64_check_relocs): Allow copy relocs for non-GOT
> 	pc-relative relocation in shared object.
> 	(elf_x86_64_adjust_dynamic_symbol): Allocate copy relocs for
> 	PIE.
> 	(elf_x86_64_relocate_section): Don't copy a pc-relative
> 	relocation into the output file if the symbol needs copy reloc.
> 

This patch reverts the change in elf_x86_64_check_relocs and the partial
change in elf_x86_64_adjust_dynamic_symbol.  Instead, we discard space
in PIE for relocs against symbols which turn out to need copy relocs.

	* elf64-x86-64.c (elf_x86_64_check_relocs): Revert the last
	change.
	(elf_x86_64_adjust_dynamic_symbol): Don't check !info->shared
	with ELIMINATE_COPY_RELOCS.
	(elf_x86_64_allocate_dynrelocs): For PIE, discard space for
	relocs against symbols which turn out to need copy relocs.
---
 bfd/ChangeLog      |  9 +++++++++
 bfd/elf64-x86-64.c | 36 +++++++++++++++++++++---------------
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 434db31..91245b9 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
 2014-12-02  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* elf64-x86-64.c (elf_x86_64_check_relocs): Revert the last
+	change.
+	(elf_x86_64_adjust_dynamic_symbol): Don't check !info->shared
+	with ELIMINATE_COPY_RELOCS.
+	(elf_x86_64_allocate_dynrelocs): For PIE, discard space for
+	relocs against symbols which turn out to need copy relocs.
+
+2014-12-02  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Always
 	allow copy relocs for building executables.
 	(elf_x86_64_check_relocs): Allow copy relocs for non-GOT
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 60d2d59..58db76a 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1955,8 +1955,7 @@ do_size:
 	     storing information in the relocs_copied field of the hash
 	     table entry.  A similar situation occurs when creating
 	     shared libraries and symbol visibility changes render the
-	     symbol local.  We allow copy relocs for non-GOT pc-relative
-	     relocation.
+	     symbol local.
 
 	     If on the other hand, we are creating an executable, we
 	     may need to keep relocations for symbols satisfied by a
@@ -1966,7 +1965,6 @@ do_size:
 	       && (sec->flags & SEC_ALLOC) != 0
 	       && (! IS_X86_64_PCREL_TYPE (r_type)
 		   || (h != NULL
-		       && !h->non_got_ref
 		       && (! SYMBOLIC_BIND (info, h)
 			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))))
@@ -2402,7 +2400,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
-  if (ELIMINATE_COPY_RELOCS && !info->shared)
+  if (ELIMINATE_COPY_RELOCS)
     {
       eh = (struct elf_x86_64_link_hash_entry *) h;
       for (p = eh->dyn_relocs; p != NULL; p = p->next)
@@ -2719,20 +2717,28 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (eh->dyn_relocs != NULL
-	  && h->root.type == bfd_link_hash_undefweak)
+      if (eh->dyn_relocs != NULL)
 	{
-	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	  if (h->root.type == bfd_link_hash_undefweak)
+	    {
+	      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+		eh->dyn_relocs = NULL;
+
+	      /* Make sure undefined weak symbols are output as a dynamic
+		 symbol in PIEs.  */
+	      else if (h->dynindx == -1
+		       && ! h->forced_local
+		       && ! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	  /* For PIE, discard space for relocs against symbols which
+	     turn out to need copy relocs.  */
+	  else if (info->executable
+		   && h->needs_copy
+		   && h->def_dynamic
+		   && !h->def_regular)
 	    eh->dyn_relocs = NULL;
-
-	  /* Make sure undefined weak symbols are output as a dynamic
-	     symbol in PIEs.  */
-	  else if (h->dynindx == -1
-		   && ! h->forced_local
-		   && ! bfd_elf_link_record_dynamic_symbol (info, h))
-	    return FALSE;
 	}
-
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
-- 
1.9.3



More information about the Binutils mailing list