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/elfxx-x86.h | |
parent | ce230579c65b9e04c830f35cb78ff33206e65db1 (diff) | |
download | fsf-binutils-gdb-3747999c6bd40a7ac905ef306a82214b336067b6.zip fsf-binutils-gdb-3747999c6bd40a7ac905ef306a82214b336067b6.tar.gz fsf-binutils-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/elfxx-x86.h')
-rw-r--r-- | bfd/elfxx-x86.h | 60 |
1 files changed, 25 insertions, 35 deletions
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 16565a5..1bb8028 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -47,6 +47,25 @@ #define X86_SIZE_TYPE_P(IS_X86_64, TYPE) \ ((IS_X86_64) ? X86_64_SIZE_TYPE_P(TYPE) : I386_SIZE_TYPE_P (TYPE)) +#define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ + (X86_64_SIZE_TYPE_P (TYPE) \ + || X86_64_PCREL_TYPE_P (TYPE) \ + || (TYPE) == R_X86_64_8 \ + || (TYPE) == R_X86_64_16 \ + || (TYPE) == R_X86_64_32 \ + || (TYPE) == R_X86_64_32S \ + || (TYPE) == R_X86_64_64) +#define I386_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ + (I386_SIZE_TYPE_P (TYPE) \ + || I386_PCREL_TYPE_P (TYPE) \ + || (TYPE) == R_386_32 \ + || (TYPE) == R_386_TLS_LE \ + || (TYPE) == R_386_TLS_LE_32) +#define X86_NEED_DYNAMIC_RELOC_TYPE_P(IS_X86_64, TYPE) \ + ((IS_X86_64) \ + ? X86_64_NEED_DYNAMIC_RELOC_TYPE_P (TYPE) \ + : I386_NEED_DYNAMIC_RELOC_TYPE_P (TYPE)) + #define PLT_CIE_LENGTH 20 #define PLT_FDE_LENGTH 36 #define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8 @@ -653,6 +672,10 @@ extern int _bfd_x86_elf_compare_relocs extern bool _bfd_x86_elf_link_check_relocs (bfd *, struct bfd_link_info *); +extern bool _bfd_x86_elf_check_relocs + (bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *); + extern bool _bfd_elf_x86_valid_reloc_p (asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *, const Elf_Internal_Rela *, struct elf_link_hash_entry *, @@ -730,10 +753,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc #define bfd_elf32_bfd_link_check_relocs \ _bfd_x86_elf_link_check_relocs +#define elf_backend_check_relocs \ + _bfd_x86_elf_check_relocs #define elf_backend_size_dynamic_sections \ _bfd_x86_elf_size_dynamic_sections -#define elf_backend_always_size_sections \ - _bfd_x86_elf_always_size_sections #define elf_backend_merge_symbol_attribute \ _bfd_x86_elf_merge_symbol_attribute #define elf_backend_copy_indirect_symbol \ @@ -757,39 +780,6 @@ extern void _bfd_x86_elf_link_report_relative_reloc #define ELF_P_ALIGN ELF_MINPAGESIZE -/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the - SECNAME section which has been garbage collected by --gc-sections - -z start-stop-gc. */ - -static inline bool -elf_x86_start_stop_gc_p (struct bfd_link_info *link_info, - struct elf_link_hash_entry *h) -{ - if (h->start_stop - && link_info->gc_sections - && link_info->start_stop_gc) - { - asection *s = h->root.u.def.section; - - do - { - /* Return false if any SECNAME section is kept. */ - if (s->gc_mark) - return false; - s = bfd_get_next_section_by_name (s->owner, s); - } - while (s != NULL); - - /* Return true only if all SECNAME sections have been garbage - collected. */ - return true; - } - - /* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or - --gc-sections or -z start-stop-gc isn't used. */ - return false; -} - /* Allocate x86 GOT info for local symbols. */ static inline bool |