aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2024-03-27 15:38:06 +0000
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2024-05-31 09:47:50 +0100
commita71d87680110d854f966d8cda0f1c7887001fcdd (patch)
tree4bbdaa23ef945131460beb405be9e3ae0453a750 /ld
parent939c703789ede7ddd2c9bc21198f430227ccbdf5 (diff)
downloadbinutils-a71d87680110d854f966d8cda0f1c7887001fcdd.zip
binutils-a71d87680110d854f966d8cda0f1c7887001fcdd.tar.gz
binutils-a71d87680110d854f966d8cda0f1c7887001fcdd.tar.bz2
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/emulparams/aarch64elf.sh2
-rw-r--r--ld/emulparams/aarch64fbsd.sh2
-rw-r--r--ld/emulparams/aarch64linux.sh2
3 files changed, 6 insertions, 0 deletions
diff --git a/ld/emulparams/aarch64elf.sh b/ld/emulparams/aarch64elf.sh
index 8f68e51..72616b5 100644
--- a/ld/emulparams/aarch64elf.sh
+++ b/ld/emulparams/aarch64elf.sh
@@ -1,3 +1,5 @@
+source_sh ${srcdir}/emulparams/dt-relr.sh
+
ARCH=aarch64
MACHINE=
NOP=0x1f2003d5
diff --git a/ld/emulparams/aarch64fbsd.sh b/ld/emulparams/aarch64fbsd.sh
index 0bcab7a..db68d43 100644
--- a/ld/emulparams/aarch64fbsd.sh
+++ b/ld/emulparams/aarch64fbsd.sh
@@ -1,3 +1,5 @@
+source_sh ${srcdir}/emulparams/dt-relr.sh
+
ARCH=aarch64
MACHINE=
NOP=0x1f2003d5
diff --git a/ld/emulparams/aarch64linux.sh b/ld/emulparams/aarch64linux.sh
index 7b4a0e8..6fe82a7 100644
--- a/ld/emulparams/aarch64linux.sh
+++ b/ld/emulparams/aarch64linux.sh
@@ -1,3 +1,5 @@
+source_sh ${srcdir}/emulparams/dt-relr.sh
+
ARCH=aarch64
MACHINE=
NOP=0x1f2003d5