diff options
author | Matthew Malcomson <matthew.malcomson@arm.com> | 2022-11-04 10:01:52 +0000 |
---|---|---|
committer | Matthew Malcomson <matthew.malcomson@arm.com> | 2022-11-04 10:03:06 +0000 |
commit | f8c6b621d4ed4cf68f595845f0222530f8d00de0 (patch) | |
tree | a873ab1ed8bcec09be42ce8ba2ef7251a1f64c54 | |
parent | ea22e23a0c9fbc97f7b501a9e3670c8ca764306b (diff) | |
download | gdb-f8c6b621d4ed4cf68f595845f0222530f8d00de0.zip gdb-f8c6b621d4ed4cf68f595845f0222530f8d00de0.tar.gz gdb-f8c6b621d4ed4cf68f595845f0222530f8d00de0.tar.bz2 |
Disable some symbol -> section_symbol + offset translations
We're disabling transformations of relocations against symbols like this
in the assembler when the relocation is against something in the GOT and
when the relocation is against something which generates a capability.
For entries in the GOT we disable this transformation since the GNU bfd
linker relies on indexing into its internal representation of the GOT
using symbols and does not distiinguish between entries using the same
symbol but different offsets. Hence transforming multiple symbols into
the same section symbol with different offsets would mean that at least
one will get an incorrect value.
Relocations which require the static linker to emit dynamic relocations
in order to generate capabilities (CAPINIT and capability relocations
into the GOT) require symbol information so that the dynamic linker can
put correct permissions and bounds on those relocations.
NOTE: We get to use an existing testcase for this change, but it showed
up something strange about objdump. One `adrp` instruction has changed
in the output so that it shows as pointing to a different location.
This happens to be an `objdump` quirk. Objdump looks at the relocation
associated with an address and attempts to include that relocation when
determining what address to print out. This mechanism has two problems,
one is that objdump does not account for the offset in that relocation
(only the symbol). Another is that on an object file (i.e. not a final
executable) the virtual memory address of all sections is zero. These
combined mean that the vma is miscalculated, and the translation from
vma to symbol is not injective. In other words: the extra change in
morello-ldst-reloc.d on top of switching the relocation symbols is in
order to account for an objdump bug and not a problem with this gas
change.
-rw-r--r-- | gas/config/tc-aarch64.c | 34 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/morello-ldst-reloc.d | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/reloc-insn.d | 4 |
3 files changed, 37 insertions, 13 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index a1bd6e1..c8373b3 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -9382,13 +9382,37 @@ check_mapping_symbols (bfd * abfd ATTRIBUTE_UNUSED, asection * sec, bfd_boolean aarch64_fix_adjustable (struct fix *fixP) { - /* We need size information of the target symbols to initialise - capabilities. */ - if (fixP->fx_r_type == BFD_RELOC_MORELLO_CAPINIT) - return FALSE; - switch (fixP->fx_r_type) { + /* The AArch64 GNU bfd linker can not handle 'symbol + offset' entries in the + GOT (it internally uses a symbol to reference a GOT slot). Hence we can't + emit any "section symbol + offset" relocations for the GOT. */ + case BFD_RELOC_AARCH64_GOT_LD_PREL19: + case BFD_RELOC_AARCH64_ADR_GOT_PAGE: + case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: + case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: + case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: + case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: + case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: + case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: + case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: + case BFD_RELOC_AARCH64_LD_GOT_LO12_NC: + case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC: + return FALSE; + + /* We need size information of the target symbols to initialise + capabilities. */ + case BFD_RELOC_MORELLO_CAPINIT: + case BFD_RELOC_MORELLO_ADR_GOT_PAGE: + case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC: + return FALSE; + /* We need to retain symbol information when jumping between A64 and C64 states or between two C64 functions. In the C64 -> C64 situation it's really only a corner case that breaks when symbols get replaced with diff --git a/gas/testsuite/gas/aarch64/morello-ldst-reloc.d b/gas/testsuite/gas/aarch64/morello-ldst-reloc.d index d2fb08e..2199e90 100644 --- a/gas/testsuite/gas/aarch64/morello-ldst-reloc.d +++ b/gas/testsuite/gas/aarch64/morello-ldst-reloc.d @@ -21,13 +21,13 @@ Disassembly of section \.text: .*: R_AARCH64_ADD_ABS_LO12_NC ptr .* <f1>: - .*: 90800002 adrp c2, 0 <_start> - .*: R_MORELLO_ADR_GOT_PAGE \.data\+0x10 + .*: 90800002 adrp c2, 10 <add> + .*: R_MORELLO_ADR_GOT_PAGE cap .*: c2400042 ldr c2, \[c2\] - .*: R_MORELLO_LD128_GOT_LO12_NC \.data\+0x10 + .*: R_MORELLO_LD128_GOT_LO12_NC cap .*: 82600042 ldr c2, \[x2\] - .*: R_MORELLO_LD128_GOT_LO12_NC \.data\+0x20 + .*: R_MORELLO_LD128_GOT_LO12_NC ptr .*: f9400042 ldr x2, \[c2\] - .*: R_AARCH64_LD64_GOT_LO12_NC \.data\+0x20 + .*: R_AARCH64_LD64_GOT_LO12_NC ptr .*: 82600c42 ldr x2, \[x2\] - .*: R_AARCH64_LD64_GOT_LO12_NC \.data\+0x20 + .*: R_AARCH64_LD64_GOT_LO12_NC ptr diff --git a/gas/testsuite/gas/aarch64/reloc-insn.d b/gas/testsuite/gas/aarch64/reloc-insn.d index 0f3b414..8898a88 100644 --- a/gas/testsuite/gas/aarch64/reloc-insn.d +++ b/gas/testsuite/gas/aarch64/reloc-insn.d @@ -157,9 +157,9 @@ Disassembly of section \.text: 18c: 39400001 ldrb w1, \[x0\] 190: d65f03c0 ret 194: f94001bc ldr x28, \[x13\] - 194: R_AARCH64_LD64_GOTPAGE_LO15 \.data + 194: R_AARCH64_LD64_GOTPAGE_LO15 dummy 198: f9400000 ldr x0, \[x0\] - 198: R_AARCH64_LD64_GOTOFF_LO15 .data + 198: R_AARCH64_LD64_GOTOFF_LO15 dummy 000000000000019c <llit>: 19c: deadf00d \.word 0xdeadf00d |