+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
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. */
#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
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. */
#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
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,
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)
{
if (dynobj == NULL)
return pbfd;
- if (plt_layout->is_vxworks
+ if (htab->is_vxworks
&& !elf_vxworks_create_dynamic_sections (dynobj, info,
&htab->srelplt2))
{
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;
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 **);
_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 \