]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
aarch64: Add DT_RELR support
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 27 Mar 2024 15:38:06 +0000 (15:38 +0000)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Fri, 31 May 2024 08:47:50 +0000 (09:47 +0100)
commita71d87680110d854f966d8cda0f1c7887001fcdd
tree4bbdaa23ef945131460beb405be9e3ae0453a750
parent939c703789ede7ddd2c9bc21198f430227ccbdf5
aarch64: Add DT_RELR support

The logic to decide if an input relocation for a symbol becomes a
particular kind of output relocation is one of the hard to maintain
parts of the bfd ld backend, since it is partially repeated across

 elfNN_aarch64_check_relocs (where dynamic relocations are counted per
 symbol and input section),

 elfNN_aarch64_late_size_sections (where relocation sections are sized
 and GOT offsets assigned),

 elfNN_aarch64_relocate_section (where most relocations are applied and
 output to a relocation section),

 elfNN_aarch64_finish_dynamic_symbol (where some of the GOT
 relocations are applied and output).

The DT_RELR support adds another layer to this complexity: after the
output relocation sections are sized, so all dynamic relocations are
accounted (in elfNN_aarch64_late_size_sections), we scan the symbols
and input relocations again to decide which ones become relative
relocations that can be packed. The sizes of the relocation sections
are updated accordingly. This logic must be consistent with the code
that applies the relocs later so each relative relocation is emitted
exactly once: either in .rela.* or packed in .relr.dyn.

Sizing of .relr.dyn is done via elfNN_aarch64_size_relative_relocs that
may be called repeatedly whenever the layout changes since an address
change can affect the size of the packed format. Then the final content
is emitted in elfNN_aarch64_finish_relative_relocs, that is called
after the layout is final and before relocations are applied and
emitted. These hooks are only called if DT_RELR is enabled.

We only pack relative relocs that are known to be aligned in the output
during .relr.dyn sizing, the potentially unaligned relative relocs are
emitted normally (in .rela.*, not packed), because the format requires
aligned addresses.
bfd/elfnn-aarch64.c
bfd/elfxx-aarch64.h
ld/emulparams/aarch64elf.sh
ld/emulparams/aarch64fbsd.sh
ld/emulparams/aarch64linux.sh