forked from Imagelibrary/binutils-gdb
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.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user