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]

[committed, PATCH] x86: Add _bfd_x86_elf_adjust_dynamic_symbol


Share _bfd_x86_elf_adjust_dynamic_symbol in elf32-i386.c and
elf64-x86-64.c.

	* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Removed.
	(elf_backend_adjust_dynamic_symbol): Likewise.
	* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
	(elf_backend_adjust_dynamic_symbol): Likewise.
	* elfxx-x86.c (_bfd_x86_elf_adjust_dynamic_symbol): New function.
	(_bfd_x86_elf_link_setup_gnu_properties): Copy is_vxworks.
	* elfxx-x86.h (elf_x86_link_hash_table): Add is_vxworks.
	(_bfd_x86_elf_adjust_dynamic_symbol): New.
	(elf_backend_adjust_dynamic_symbol): Likewise.
---
 bfd/ChangeLog      |  12 +++
 bfd/elf32-i386.c   | 194 -------------------------------------------------
 bfd/elf64-x86-64.c | 194 -------------------------------------------------
 bfd/elfxx-x86.c    | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 bfd/elfxx-x86.h    |   8 ++
 5 files changed, 228 insertions(+), 389 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 37f336c705..9220235781 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,17 @@
 2017-09-01  H.J. Lu  <hongjiu.lu@intel.com>
 
+	* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Removed.
+	(elf_backend_adjust_dynamic_symbol): Likewise.
+	* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
+	(elf_backend_adjust_dynamic_symbol): Likewise.
+	* elfxx-x86.c (_bfd_x86_elf_adjust_dynamic_symbol): New function.
+	(_bfd_x86_elf_link_setup_gnu_properties): Copy is_vxworks.
+	* elfxx-x86.h (elf_x86_link_hash_table): Add is_vxworks.
+	(_bfd_x86_elf_adjust_dynamic_symbol): New.
+	(elf_backend_adjust_dynamic_symbol): Likewise.
+
+2017-09-01  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* elfxx-x86.h (elf_x86_plt_layout_table): Fix a typo in
 	comments.
 
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 4efc066cde..c934f28a4b 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1995,199 +1995,6 @@ elf_i386_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
-/* 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
-   change the definition to something the rest of the link can
-   understand.  */
-
-static bfd_boolean
-elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
-				struct elf_link_hash_entry *h)
-{
-  struct elf_x86_link_hash_table *htab;
-  asection *s, *srel;
-  struct elf_x86_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
-
-  /* STT_GNU_IFUNC symbol must go through PLT. */
-  if (h->type == STT_GNU_IFUNC)
-    {
-      /* All local STT_GNU_IFUNC references must be treate as local
-	 calls via local PLT.  */
-      if (h->ref_regular
-	  && SYMBOL_CALLS_LOCAL (info, h))
-	{
-	  bfd_size_type pc_count = 0, count = 0;
-	  struct elf_dyn_relocs **pp;
-
-	  eh = (struct elf_x86_link_hash_entry *) h;
-	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
-	    {
-	      pc_count += p->pc_count;
-	      p->count -= p->pc_count;
-	      p->pc_count = 0;
-	      count += p->count;
-	      if (p->count == 0)
-		*pp = p->next;
-	      else
-		pp = &p->next;
-	    }
-
-	  if (pc_count || count)
-	    {
-	      h->non_got_ref = 1;
-	      if (pc_count)
-		{
-		  /* Increment PLT reference count only for PC-relative
-		     references.  */
-		  h->needs_plt = 1;
-		  if (h->plt.refcount <= 0)
-		    h->plt.refcount = 1;
-		  else
-		    h->plt.refcount += 1;
-		}
-	    }
-	}
-
-      if (h->plt.refcount <= 0)
-	{
-	  h->plt.offset = (bfd_vma) -1;
-	  h->needs_plt = 0;
-	}
-      return TRUE;
-    }
-
-  /* If this is a function, put it in the procedure linkage table.  We
-     will fill in the contents of the procedure linkage table later,
-     when we know the address of the .got section.  */
-  if (h->type == STT_FUNC
-      || h->needs_plt)
-    {
-      if (h->plt.refcount <= 0
-	  || SYMBOL_CALLS_LOCAL (info, h)
-	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
-	      && h->root.type == bfd_link_hash_undefweak))
-	{
-	  /* This case can occur if we saw a PLT32 reloc in an input
-	     file, but the symbol was never referred to by a dynamic
-	     object, or if all references were garbage collected.  In
-	     such a case, we don't actually need to build a procedure
-	     linkage table, and we can just do a PC32 reloc instead.  */
-	  h->plt.offset = (bfd_vma) -1;
-	  h->needs_plt = 0;
-	}
-
-      return TRUE;
-    }
-  else
-    /* It's possible that we incorrectly decided a .plt reloc was
-       needed for an R_386_PC32 reloc to a non-function sym in
-       check_relocs.  We can't decide accurately between function and
-       non-function syms in check-relocs;  Objects loaded later in
-       the link may change h->type.  So fix it now.  */
-    h->plt.offset = (bfd_vma) -1;
-
-  eh = (struct elf_x86_link_hash_entry *) h;
-
-  /* If this is a weak symbol, and there is a real definition, the
-     processor independent code will have arranged for us to see the
-     real definition first, and we can just use the same value.  */
-  if (h->u.weakdef != NULL)
-    {
-      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
-		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->u.weakdef->root.u.def.section;
-      h->root.u.def.value = h->u.weakdef->root.u.def.value;
-      if (ELIMINATE_COPY_RELOCS
-	  || info->nocopyreloc
-	  || SYMBOL_NO_COPYRELOC (info, eh))
-	h->non_got_ref = h->u.weakdef->non_got_ref;
-      return TRUE;
-    }
-
-  /* This is a reference to a symbol defined by a dynamic object which
-     is not a function.  */
-
-  /* If we are creating a shared library, we must presume that the
-     only references to the symbol are via the global offset table.
-     For such cases we need not do anything here; the relocations will
-     be handled correctly by relocate_section.  */
-  if (!bfd_link_executable (info))
-    return TRUE;
-
-  /* If there are no references to this symbol that do not use the
-     GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
-     reloc.  */
-  if (!h->non_got_ref && !eh->gotoff_ref)
-    return TRUE;
-
-  /* If -z nocopyreloc was given, we won't generate them either.  */
-  if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
-    {
-      h->non_got_ref = 0;
-      return TRUE;
-    }
-
-  htab = elf_x86_hash_table (info, I386_ELF_DATA);
-  if (htab == NULL)
-    return FALSE;
-
-  /* If there aren't any dynamic relocs in read-only sections nor
-     R_386_GOTOFF relocation, then we can keep the dynamic relocs and
-     avoid the copy reloc.  This doesn't work on VxWorks, where we can
-     not have dynamic relocations (other than copy and jump slot
-     relocations) in an executable.  */
-  if (ELIMINATE_COPY_RELOCS
-      && !eh->gotoff_ref
-      && get_elf_i386_backend_data (info->output_bfd)->os != is_vxworks)
-    {
-      for (p = eh->dyn_relocs; p != NULL; p = p->next)
-	{
-	  s = p->sec->output_section;
-	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	    break;
-	}
-
-      if (p == NULL)
-	{
-	  h->non_got_ref = 0;
-	  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
-     an entry for this symbol in the .dynsym section.  The dynamic
-     object will contain position independent code, so all references
-     from the dynamic object to this symbol will go through the global
-     offset table.  The dynamic linker will use the .dynsym entry to
-     determine the address it must put in the global offset table, so
-     both the dynamic object and the regular object will refer to the
-     same memory location for the variable.  */
-
-  /* We must generate a R_386_COPY reloc to tell the dynamic linker to
-     copy the initial value out of the dynamic object and into the
-     runtime process image.  */
-  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
-    {
-      s = htab->elf.sdynrelro;
-      srel = htab->elf.sreldynrelro;
-    }
-  else
-    {
-      s = htab->elf.sdynbss;
-      srel = htab->elf.srelbss;
-    }
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
-    {
-      srel->size += sizeof (Elf32_External_Rel);
-      h->needs_copy = 1;
-    }
-
-  return _bfd_elf_adjust_dynamic_copy (info, h, s);
-}
-
 /* Allocate space in .plt, .got and associated reloc sections for
    dynamic relocs.  */
 
@@ -5876,7 +5683,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
 #define bfd_elf32_bfd_reloc_name_lookup	      elf_i386_reloc_name_lookup
 #define bfd_elf32_get_synthetic_symtab	      elf_i386_get_synthetic_symtab
 
-#define elf_backend_adjust_dynamic_symbol     elf_i386_adjust_dynamic_symbol
 #define elf_backend_relocs_compatible	      _bfd_elf_relocs_compatible
 #define elf_backend_check_relocs	      elf_i386_check_relocs
 #define elf_backend_create_dynamic_sections   _bfd_elf_create_dynamic_sections
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index bc08f647c4..ef8ca1a565 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2435,199 +2435,6 @@ elf_x86_64_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
-/* 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
-   change the definition to something the rest of the link can
-   understand.	*/
-
-static bfd_boolean
-elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
-				  struct elf_link_hash_entry *h)
-{
-  struct elf_x86_link_hash_table *htab;
-  asection *s, *srel;
-  struct elf_x86_link_hash_entry *eh;
-  struct elf_dyn_relocs *p;
-
-  /* STT_GNU_IFUNC symbol must go through PLT. */
-  if (h->type == STT_GNU_IFUNC)
-    {
-      /* All local STT_GNU_IFUNC references must be treate as local
-	 calls via local PLT.  */
-      if (h->ref_regular
-	  && SYMBOL_CALLS_LOCAL (info, h))
-	{
-	  bfd_size_type pc_count = 0, count = 0;
-	  struct elf_dyn_relocs **pp;
-
-	  eh = (struct elf_x86_link_hash_entry *) h;
-	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
-	    {
-	      pc_count += p->pc_count;
-	      p->count -= p->pc_count;
-	      p->pc_count = 0;
-	      count += p->count;
-	      if (p->count == 0)
-		*pp = p->next;
-	      else
-		pp = &p->next;
-	    }
-
-	  if (pc_count || count)
-	    {
-	      h->non_got_ref = 1;
-	      if (pc_count)
-		{
-		  /* Increment PLT reference count only for PC-relative
-		     references.  */
-		  h->needs_plt = 1;
-		  if (h->plt.refcount <= 0)
-		    h->plt.refcount = 1;
-		  else
-		    h->plt.refcount += 1;
-		}
-	    }
-	}
-
-      if (h->plt.refcount <= 0)
-	{
-	  h->plt.offset = (bfd_vma) -1;
-	  h->needs_plt = 0;
-	}
-      return TRUE;
-    }
-
-  /* If this is a function, put it in the procedure linkage table.  We
-     will fill in the contents of the procedure linkage table later,
-     when we know the address of the .got section.  */
-  if (h->type == STT_FUNC
-      || h->needs_plt)
-    {
-      if (h->plt.refcount <= 0
-	  || SYMBOL_CALLS_LOCAL (info, h)
-	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
-	      && h->root.type == bfd_link_hash_undefweak))
-	{
-	  /* This case can occur if we saw a PLT32 reloc in an input
-	     file, but the symbol was never referred to by a dynamic
-	     object, or if all references were garbage collected.  In
-	     such a case, we don't actually need to build a procedure
-	     linkage table, and we can just do a PC32 reloc instead.  */
-	  h->plt.offset = (bfd_vma) -1;
-	  h->needs_plt = 0;
-	}
-
-      return TRUE;
-    }
-  else
-    /* It's possible that we incorrectly decided a .plt reloc was
-       needed for an R_X86_64_PC32 reloc to a non-function sym in
-       check_relocs.  We can't decide accurately between function and
-       non-function syms in check-relocs;  Objects loaded later in
-       the link may change h->type.  So fix it now.  */
-    h->plt.offset = (bfd_vma) -1;
-
-  eh = (struct elf_x86_link_hash_entry *) h;
-
-  /* If this is a weak symbol, and there is a real definition, the
-     processor independent code will have arranged for us to see the
-     real definition first, and we can just use the same value.	 */
-  if (h->u.weakdef != NULL)
-    {
-      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
-		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->u.weakdef->root.u.def.section;
-      h->root.u.def.value = h->u.weakdef->root.u.def.value;
-      if (ELIMINATE_COPY_RELOCS
-	  || info->nocopyreloc
-	  || SYMBOL_NO_COPYRELOC (info, eh))
-	{
-	  h->non_got_ref = h->u.weakdef->non_got_ref;
-	  eh->needs_copy = h->u.weakdef->needs_copy;
-	}
-      return TRUE;
-    }
-
-  /* This is a reference to a symbol defined by a dynamic object which
-     is not a function.	 */
-
-  /* If we are creating a shared library, we must presume that the
-     only references to the symbol are via the global offset table.
-     For such cases we need not do anything here; the relocations will
-     be handled correctly by relocate_section.	*/
-  if (!bfd_link_executable (info))
-    return TRUE;
-
-  /* If there are no references to this symbol that do not use the
-     GOT, we don't need to generate a copy reloc.  */
-  if (!h->non_got_ref)
-    return TRUE;
-
-  /* If -z nocopyreloc was given, we won't generate them either.  */
-  if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
-    {
-      h->non_got_ref = 0;
-      return TRUE;
-    }
-
-  if (ELIMINATE_COPY_RELOCS)
-    {
-      eh = (struct elf_x86_link_hash_entry *) h;
-      for (p = eh->dyn_relocs; p != NULL; p = p->next)
-	{
-	  s = p->sec->output_section;
-	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
-	    break;
-	}
-
-      /* 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.  */
-      if (p == NULL)
-	{
-	  h->non_got_ref = 0;
-	  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
-     an entry for this symbol in the .dynsym section.  The dynamic
-     object will contain position independent code, so all references
-     from the dynamic object to this symbol will go through the global
-     offset table.  The dynamic linker will use the .dynsym entry to
-     determine the address it must put in the global offset table, so
-     both the dynamic object and the regular object will refer to the
-     same memory location for the variable.  */
-
-  htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
-  if (htab == NULL)
-    return FALSE;
-
-  /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
-     to copy the initial value out of the dynamic object and into the
-     runtime process image.  */
-  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
-    {
-      s = htab->elf.sdynrelro;
-      srel = htab->elf.sreldynrelro;
-    }
-  else
-    {
-      s = htab->elf.sdynbss;
-      srel = htab->elf.srelbss;
-    }
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
-    {
-      const struct elf_backend_data *bed;
-      bed = get_elf_backend_data (info->output_bfd);
-      srel->size += bed->s->sizeof_rela;
-      h->needs_copy = 1;
-    }
-
-  return _bfd_elf_adjust_dynamic_copy (info, h, s);
-}
-
 /* Allocate space in .plt, .got and associated reloc sections for
    dynamic relocs.  */
 
@@ -6453,7 +6260,6 @@ elf_x86_64_special_sections[]=
 #define bfd_elf64_bfd_reloc_name_lookup \
   elf_x86_64_reloc_name_lookup
 
-#define elf_backend_adjust_dynamic_symbol   elf_x86_64_adjust_dynamic_symbol
 #define elf_backend_relocs_compatible	    elf_x86_64_relocs_compatible
 #define elf_backend_check_relocs	    elf_x86_64_check_relocs
 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 91bd61557e..cb5f6142c3 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -539,6 +539,211 @@ _bfd_x86_elf_hash_symbol (struct elf_link_hash_entry *h)
   return _bfd_elf_hash_symbol (h);
 }
 
+/* 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
+   change the definition to something the rest of the link can
+   understand.  */
+
+bfd_boolean
+_bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+				    struct elf_link_hash_entry *h)
+{
+  struct elf_x86_link_hash_table *htab;
+  asection *s, *srel;
+  struct elf_x86_link_hash_entry *eh;
+  struct elf_dyn_relocs *p;
+  const struct elf_backend_data *bed
+    = get_elf_backend_data (info->output_bfd);
+
+  /* STT_GNU_IFUNC symbol must go through PLT. */
+  if (h->type == STT_GNU_IFUNC)
+    {
+      /* All local STT_GNU_IFUNC references must be treate as local
+	 calls via local PLT.  */
+      if (h->ref_regular
+	  && SYMBOL_CALLS_LOCAL (info, h))
+	{
+	  bfd_size_type pc_count = 0, count = 0;
+	  struct elf_dyn_relocs **pp;
+
+	  eh = (struct elf_x86_link_hash_entry *) h;
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+	    {
+	      pc_count += p->pc_count;
+	      p->count -= p->pc_count;
+	      p->pc_count = 0;
+	      count += p->count;
+	      if (p->count == 0)
+		*pp = p->next;
+	      else
+		pp = &p->next;
+	    }
+
+	  if (pc_count || count)
+	    {
+	      h->non_got_ref = 1;
+	      if (pc_count)
+		{
+		  /* Increment PLT reference count only for PC-relative
+		     references.  */
+		  h->needs_plt = 1;
+		  if (h->plt.refcount <= 0)
+		    h->plt.refcount = 1;
+		  else
+		    h->plt.refcount += 1;
+		}
+	    }
+	}
+
+      if (h->plt.refcount <= 0)
+	{
+	  h->plt.offset = (bfd_vma) -1;
+	  h->needs_plt = 0;
+	}
+      return TRUE;
+    }
+
+  /* If this is a function, put it in the procedure linkage table.  We
+     will fill in the contents of the procedure linkage table later,
+     when we know the address of the .got section.  */
+  if (h->type == STT_FUNC
+      || h->needs_plt)
+    {
+      if (h->plt.refcount <= 0
+	  || SYMBOL_CALLS_LOCAL (info, h)
+	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+	      && h->root.type == bfd_link_hash_undefweak))
+	{
+	  /* This case can occur if we saw a PLT32 reloc in an input
+	     file, but the symbol was never referred to by a dynamic
+	     object, or if all references were garbage collected.  In
+	     such a case, we don't actually need to build a procedure
+	     linkage table, and we can just do a PC32 reloc instead.  */
+	  h->plt.offset = (bfd_vma) -1;
+	  h->needs_plt = 0;
+	}
+
+      return TRUE;
+    }
+  else
+    /* It's possible that we incorrectly decided a .plt reloc was needed
+     * for an R_386_PC32/R_X86_64_PC32 reloc to a non-function sym in
+       check_relocs.  We can't decide accurately between function and
+       non-function syms in check-relocs;  Objects loaded later in
+       the link may change h->type.  So fix it now.  */
+    h->plt.offset = (bfd_vma) -1;
+
+  eh = (struct elf_x86_link_hash_entry *) h;
+
+  /* If this is a weak symbol, and there is a real definition, the
+     processor independent code will have arranged for us to see the
+     real definition first, and we can just use the same value.  */
+  if (h->u.weakdef != NULL)
+    {
+      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
+      if (ELIMINATE_COPY_RELOCS
+	  || info->nocopyreloc
+	  || SYMBOL_NO_COPYRELOC (info, eh))
+	{
+	  /* NB: needs_copy is always 0 for i386.  */
+	  h->non_got_ref = h->u.weakdef->non_got_ref;
+	  eh->needs_copy = h->u.weakdef->needs_copy;
+	}
+      return TRUE;
+    }
+
+  /* This is a reference to a symbol defined by a dynamic object which
+     is not a function.  */
+
+  /* If we are creating a shared library, we must presume that the
+     only references to the symbol are via the global offset table.
+     For such cases we need not do anything here; the relocations will
+     be handled correctly by relocate_section.  */
+  if (!bfd_link_executable (info))
+    return TRUE;
+
+  /* If there are no references to this symbol that do not use the
+     GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
+     reloc.  NB: gotoff_ref is always 0 for x86-64.  */
+  if (!h->non_got_ref && !eh->gotoff_ref)
+    return TRUE;
+
+  /* If -z nocopyreloc was given, we won't generate them either.  */
+  if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
+    {
+      h->non_got_ref = 0;
+      return TRUE;
+    }
+
+  htab = elf_x86_hash_table (info, bed->target_id);
+  if (htab == NULL)
+    return FALSE;
+
+  /* If there aren't any dynamic relocs in read-only sections nor
+     R_386_GOTOFF relocation, then we can keep the dynamic relocs and
+     avoid the copy reloc.  This doesn't work on VxWorks, where we can
+     not have dynamic relocations (other than copy and jump slot
+     relocations) in an executable.  */
+  if (ELIMINATE_COPY_RELOCS
+      && (bed->target_id == X86_64_ELF_DATA
+	  || (!eh->gotoff_ref
+	      && !htab->is_vxworks)))
+    {
+      for (p = eh->dyn_relocs; p != NULL; p = p->next)
+	{
+	  s = p->sec->output_section;
+	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	    break;
+	}
+
+      /* 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.  */
+      if (p == NULL)
+	{
+	  h->non_got_ref = 0;
+	  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
+     an entry for this symbol in the .dynsym section.  The dynamic
+     object will contain position independent code, so all references
+     from the dynamic object to this symbol will go through the global
+     offset table.  The dynamic linker will use the .dynsym entry to
+     determine the address it must put in the global offset table, so
+     both the dynamic object and the regular object will refer to the
+     same memory location for the variable.  */
+
+  /* We must generate a R_386_COPY/R_X86_64_COPY reloc to tell the
+     dynamic linker to copy the initial value out of the dynamic object
+     and into the runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+    {
+      srel->size += ((bed->target_id == I386_ELF_DATA)
+		     ? sizeof (Elf32_External_Rel)
+		     : bed->s->sizeof_rela);
+      h->needs_copy = 1;
+    }
+
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
+}
+
 static bfd_vma
 elf_i386_get_plt_got_vma (struct elf_x86_plt *plt_p ATTRIBUTE_UNUSED,
 			  bfd_vma off,
@@ -997,6 +1202,8 @@ error_alignment:
   if (htab == NULL)
     return pbfd;
 
+  htab->is_vxworks = plt_layout->is_vxworks;
+
   use_ibt_plt = info->ibtplt || info->ibt;
   if (!use_ibt_plt && pbfd != NULL)
     {
@@ -1119,7 +1326,7 @@ error_alignment:
   if (dynobj == NULL)
     return pbfd;
 
-  if (plt_layout->is_vxworks
+  if (htab->is_vxworks
       && !elf_vxworks_create_dynamic_sections (dynobj, info,
 					       &htab->srelplt2))
     {
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index feef0e7a2a..8f8fbeae87 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -287,6 +287,9 @@ struct elf_x86_link_hash_table
      to read-only sections.  */
   bfd_boolean readonly_dynrelocs_against_ifunc;
 
+  /* TRUE if this is a VxWorks x86 target.  */
+  bfd_boolean is_vxworks;
+
   /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.
      This is used for i386 only.  */
   asection *srelplt2;
@@ -416,6 +419,9 @@ extern bfd_boolean _bfd_x86_elf_fixup_symbol
 extern bfd_boolean _bfd_x86_elf_hash_symbol
   (struct elf_link_hash_entry *);
 
+extern bfd_boolean _bfd_x86_elf_adjust_dynamic_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry *);
+
 extern long _bfd_x86_elf_get_synthetic_symtab
   (bfd *, long, long, bfd_vma, struct elf_x86_plt [], asymbol **,
    asymbol **);
@@ -452,6 +458,8 @@ extern bfd * _bfd_x86_elf_link_setup_gnu_properties
   _bfd_x86_elf_fixup_symbol
 #define elf_backend_hash_symbol \
   _bfd_x86_elf_hash_symbol
+#define elf_backend_adjust_dynamic_symbol \
+  _bfd_x86_elf_adjust_dynamic_symbol
 #define elf_backend_omit_section_dynsym \
   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_parse_gnu_properties \
-- 
2.13.5


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