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/elflink.c | |
parent | Automatic date update in version.in (diff) | |
download | binutils-gdb-3747999c6bd40a7ac905ef306a82214b336067b6.tar.gz binutils-gdb-3747999c6bd40a7ac905ef306a82214b336067b6.tar.bz2 binutils-gdb-3747999c6bd40a7ac905ef306a82214b336067b6.zip |
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/elflink.c')
-rw-r--r-- | bfd/elflink.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c index 08c161713cc..059461b5725 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4008,10 +4008,13 @@ _bfd_elf_notice_as_needed (bfd *ibfd, return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0); } -/* Check relocations an ELF object file. */ +/* Call ACTION on each relocation in an ELF object file. */ bool -_bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) +_bfd_elf_link_iterate_on_relocs + (bfd *abfd, struct bfd_link_info *info, + bool (*action) (bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)) { const struct elf_backend_data *bed = get_elf_backend_data (abfd); struct elf_link_hash_table *htab = elf_hash_table (info); @@ -4035,7 +4038,6 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) different format. It probably can't be done. */ if ((abfd->flags & DYNAMIC) == 0 && is_elf_hash_table (&htab->root) - && bed->check_relocs != NULL && elf_object_id (abfd) == elf_hash_table_id (htab) && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec)) { @@ -4070,7 +4072,7 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) if (internal_relocs == NULL) return false; - ok = (*bed->check_relocs) (abfd, info, o, internal_relocs); + ok = action (abfd, info, o, internal_relocs); if (elf_section_data (o)->relocs != internal_relocs) free (internal_relocs); @@ -4083,6 +4085,19 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) return true; } +/* Check relocations in an ELF object file. This is called after + all input files have been opened. */ + +bool +_bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) +{ + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + if (bed->check_relocs != NULL) + return _bfd_elf_link_iterate_on_relocs (abfd, info, + bed->check_relocs); + return true; +} + /* Add symbols from an ELF object file to the linker hash table. */ static bool |