diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-12-27 10:13:06 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2022-01-07 17:58:20 -0800 |
commit | 3747999c6bd40a7ac905ef306a82214b336067b6 (patch) | |
tree | b05f73242942f28863f14a2a26929104b1d5ee86 /bfd/elf32-i386.c | |
parent | ce230579c65b9e04c830f35cb78ff33206e65db1 (diff) | |
download | gdb-3747999c6bd40a7ac905ef306a82214b336067b6.zip gdb-3747999c6bd40a7ac905ef306a82214b336067b6.tar.gz gdb-3747999c6bd40a7ac905ef306a82214b336067b6.tar.bz2 |
ld: Extract _bfd_elf_link_iterate_on_relocs
DT_RELR encodes consecutive R_*_RELATIVE relocations in GOT (the global
offset table) and data sections in a compact format:
https://groups.google.com/g/generic-abi/c/bX460iggiKg
On some targets, R_*_RELATIVE relocations are counted and the GOT offsets
are allocated when setting the dynamic section sizes after seeing all
relocations. R_*_RELATIVE relocations are generated while relocating
sections after section layout has been finalized.
To prepare for DT_RELR implementation on these targets, extract
_bfd_elf_link_iterate_on_relocs from _bfd_elf_link_check_relocs so
that a backend can scan relocations in elf_backend_always_size_sections
For x86 targets, the old check_relocs is renamed to scan_relocs and a
new check_relocs is added to chek input sections and create dynamic
relocation sections so that they will be mapped to output sections.
scan_relocs is now called from elf_backend_always_size_sections.
Since relocations are scanned after __start, __stop, .startof. and
.sizeof. symbols have been finalized on x86, __[start|stop]_SECNAME for
--gc-sections -z start-stop-gc are now zero when all SECNAME sections
been garbage collected. This is no need for elf_x86_start_stop_gc_p.
bfd/
* elf-bfd.h (_bfd_elf_link_iterate_on_relocs): New.
* elf32-i386.c (elf_i386_convert_load_reloc): Don't call
elf_x86_start_stop_gc_p.
(elf_i386_check_relocs): Renamed to ...
(elf_i386_scan_relocs): This. Don't call
_bfd_elf_make_dynamic_reloc_section.
(elf_i386_always_size_sections): New.
(elf_backend_check_relocs): Removed.
(elf_backend_always_size_sections): New.
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Don't call
elf_x86_start_stop_gc_p.
(elf_x86_64_check_relocs): Renamed to ...
(elf_x86_64_scan_relocs): This. Don't call
_bfd_elf_make_dynamic_reloc_section.
(elf_x86_64_always_size_sections): New.
(elf_backend_check_relocs): Removed.
(elf_backend_always_size_sections): New.
* elflink.c (elf_link_check_or_scan_relocs):
New. Extracted from _bfd_elf_link_check_relocs.
(_bfd_elf_link_check_relocs): Call elf_link_check_or_scan_relocs.
* elfxx-x86.c (_bfd_x86_elf_check_relocs): New.
* elfxx-x86.h (X86_64_NEED_DYNAMIC_RELOC_TYPE_P): New.
(I386_NEED_DYNAMIC_RELOC_TYPE_P): Likewise.
(X86_NEED_DYNAMIC_RELOC_TYPE_P): Likewise.
(_bfd_x86_elf_check_relocs): Likewise.
(elf_backend_check_relocs): Likewise.
(elf_backend_always_size_sections): Removed.
(elf_x86_start_stop_gc_p): Likewise.
ld/
* testsuite/ld-i386/pr27491-1a.d: Updated.
* testsuite/ld-x86-64/pr27491-1a.d: Likewise.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 9796207..d1f61be 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -522,7 +522,7 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) Functions named elf_i386_* are called by external routines, other functions are only called locally. elf_i386_* functions appear in this file more or less in the order in which they are called - from external routines. eg. elf_i386_check_relocs is called + from external routines. eg. elf_i386_scan_relocs is called early in the link process, elf_i386_finish_dynamic_sections is one of the last functions. */ @@ -1106,7 +1106,7 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, } /* We checked the transition before when we were called from - elf_i386_check_relocs. We only want to check the new + elf_i386_scan_relocs. We only want to check the new transition which hasn't been checked before. */ check = new_to_type != to_type && from_type == to_type; to_type = new_to_type; @@ -1387,11 +1387,6 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, || h->root.type == bfd_link_hash_defweak) && local_ref)) { - /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections - -z start-stop-gc are used. */ - if (elf_x86_start_stop_gc_p (link_info, h)) - return true; - convert_load: if (opcode == 0x8b) { @@ -1452,21 +1447,20 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, } /* Look through the relocs for a section during the first phase, and - calculate needed space in the global offset table, procedure linkage - table, and dynamic reloc sections. */ + calculate needed space in the global offset table, and procedure + linkage table. */ static bool -elf_i386_check_relocs (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) +elf_i386_scan_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { struct elf_x86_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; - asection *sreloc; bfd_byte *contents; bool converted; @@ -1496,8 +1490,6 @@ elf_i386_check_relocs (bfd *abfd, converted = false; - sreloc = NULL; - rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) { @@ -1818,18 +1810,6 @@ elf_i386_check_relocs (bfd *abfd, struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; - /* We must copy these reloc types into the output file. - Create a reloc section in dynobj and make room for - this reloc. */ - if (sreloc == NULL) - { - sreloc = _bfd_elf_make_dynamic_reloc_section - (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ false); - - if (sreloc == NULL) - goto error_return; - } - /* If this is a global symbol, we count the number of relocations we need for this symbol. */ if (h != NULL) @@ -1924,6 +1904,24 @@ elf_i386_check_relocs (bfd *abfd, return false; } +static bool +elf_i386_always_size_sections (bfd *output_bfd, + struct bfd_link_info *info) +{ + bfd *abfd; + + /* Scan relocations after rel_from_abs has been set on __ehdr_start. */ + for (abfd = info->input_bfds; + abfd != (bfd *) NULL; + abfd = abfd->link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && !_bfd_elf_link_iterate_on_relocs (abfd, info, + elf_i386_scan_relocs)) + return false; + + return _bfd_x86_elf_always_size_sections (output_bfd, info); +} + /* Set the correct type for an x86 ELF section. We do this by the section name, which is a hack, but ought to work. */ @@ -2000,7 +1998,7 @@ elf_i386_relocate_section (bfd *output_bfd, bool is_vxworks_tls; unsigned plt_entry_size; - /* Skip if check_relocs failed. */ + /* Skip if check_relocs or scan_relocs failed. */ if (input_section->check_relocs_failed) return false; @@ -4390,7 +4388,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) #define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab #define elf_backend_relocs_compatible _bfd_elf_relocs_compatible -#define elf_backend_check_relocs elf_i386_check_relocs +#define elf_backend_always_size_sections elf_i386_always_size_sections #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections #define elf_backend_fake_sections elf_i386_fake_sections #define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections |