diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-09-07 04:03:15 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-09-07 04:03:30 -0700 |
commit | 6999821f8b1e898f02d0c1196c4c83337c3b565e (patch) | |
tree | afd4c30d7e1fc646fe5c27996bb4ce58db0ec6b8 /bfd/elfxx-x86.c | |
parent | 639257e981e61472e5fc215eb60c5d545ac5e2ab (diff) | |
download | gdb-6999821f8b1e898f02d0c1196c4c83337c3b565e.zip gdb-6999821f8b1e898f02d0c1196c4c83337c3b565e.tar.gz gdb-6999821f8b1e898f02d0c1196c4c83337c3b565e.tar.bz2 |
x86: Remove _bfd_{i386,x86_64}_elf_convert_load
Instead of converting GOT relocations when sizing dynamic sections, we
convert GOT relocations during relocation check. Add a field, local_ref,
to elf_x86_link_hash_entry to indicate if symbol references are always
local with a new function to check if symbol references are always local,
which works in check_relocs.
* elf32-i386.c (elf_i386_convert_load_reloc): Add an argument,
r_type_p. Remove the converted argument. Replace
SYMBOL_REFERENCES_LOCAL with SYMBOL_REFERENCES_LOCAL_P. Return
the new relocation type via r_type_p.
(elf_i386_relocate_section): Likewise.
(elf_i386_finish_dynamic_symbol): Likewise.
(need_convert_load): Removed.
(check_relocs_failed): Updated.
(elf_i386_check_relocs): Call elf_i386_convert_load_reloc,
instead of setting need_convert_load.
(_bfd_i386_elf_convert_load): Removed.
* elf64-x86-64.c (need_convert_load): Removed.
(check_relocs_failed): Updated.
(elf_x86_64_convert_load_reloc): Add an argument, r_type_p.
Replace SYMBOL_REFERENCES_LOCAL with SYMBOL_REFERENCES_LOCAL_P.
Return the new relocation type via r_type_p.
(elf_x86_64_check_relocs): Call elf_x86_64_convert_load_reloc,
instead of setting need_convert_load.
(elf_x86_64_check_relocs): Don't check PIC if relocation has
been converted.
(_bfd_x86_64_elf_convert_load): Removed.
(elf_x86_64_relocate_section): Replace SYMBOL_REFERENCES_LOCAL
with SYMBOL_REFERENCES_LOCAL_P.
(elf_x86_64_finish_dynamic_symbol): Likewise.
* elfxx-x86.c (_bfd_x86_elf_link_hash_table_create): Don't
set convert_load.
(_bfd_x86_elf_size_dynamic_sections): Don't call convert_load.
(_bfd_x86_elf_link_symbol_references_local): New function.
* elfxx-x86.h (SYMBOL_REFERENCES_LOCAL_P): New.
(UNDEFINED_WEAK_RESOLVED_TO_ZERO): Replace elf.forced_local with
SYMBOL_REFERENCES_LOCAL_P.
(elf_x86_link_hash_entry): Add local_ref.
(elf_x86_link_hash_table): Remove convert_load.
(_bfd_i386_elf_convert_load): Removed.
(_bfd_x86_64_elf_convert_load): Likewise.
(_bfd_x86_elf_link_symbol_references_local): New.
Diffstat (limited to 'bfd/elfxx-x86.c')
-rw-r--r-- | bfd/elfxx-x86.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index a7e9eda..4f6b09e 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -766,7 +766,6 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd) /* NB: If BFD64 isn't defined, only i386 will be supported. */ if (bed->target_id == X86_64_ELF_DATA) { - ret->convert_load = _bfd_x86_64_elf_convert_load; ret->is_reloc_section = elf_x86_64_is_reloc_section; ret->dt_reloc = DT_RELA; ret->dt_reloc_sz = DT_RELASZ; @@ -798,7 +797,6 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd) } else { - ret->convert_load = _bfd_i386_elf_convert_load; ret->is_reloc_section = elf_i386_is_reloc_section; ret->dt_reloc = DT_REL; ret->dt_reloc_sz = DT_RELSZ; @@ -909,9 +907,6 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, { struct elf_dyn_relocs *p; - if (!htab->convert_load (ibfd, s, info)) - return FALSE; - for (p = ((struct elf_dyn_relocs *) elf_section_data (s)->local_dynrel); p != NULL; @@ -1677,6 +1672,45 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info, return _bfd_elf_adjust_dynamic_copy (info, h, s); } +/* Return TRUE if a symbol is referenced locally. It is similar to + SYMBOL_REFERENCES_LOCAL, but it also checks version script. It + works in check_relocs. */ + +bfd_boolean +_bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + struct elf_x86_link_hash_entry *eh + = (struct elf_x86_link_hash_entry *) h; + + if (eh->local_ref > 1) + return TRUE; + + if (eh->local_ref == 1) + return FALSE; + + /* Unversioned symbols defined in regular objects can be forced local + by linker version script. A weak undefined symbol can fored local + if it has non-default visibility or "-z nodynamic-undefined-weak" + is used. */ + if (SYMBOL_REFERENCES_LOCAL (info, h) + || ((ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + || info->dynamic_undefined_weak == 0) + && h->root.type == bfd_link_hash_undefweak) + || ((h->def_regular || ELF_COMMON_DEF_P (h)) + && h->versioned == unversioned + && info->version_info != NULL + && bfd_hide_sym_by_version (info->version_info, + h->root.root.string))) + { + eh->local_ref = 2; + return TRUE; + } + + eh->local_ref = 1; + return FALSE; +} + /* Return the section that should be marked against GC for a given relocation. */ |