aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Malcomson <matthew.malcomson@arm.com>2022-11-04 10:01:52 +0000
committerMatthew Malcomson <matthew.malcomson@arm.com>2022-11-04 10:03:06 +0000
commitf8c6b621d4ed4cf68f595845f0222530f8d00de0 (patch)
treea873ab1ed8bcec09be42ce8ba2ef7251a1f64c54
parentea22e23a0c9fbc97f7b501a9e3670c8ca764306b (diff)
downloadgdb-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.c34
-rw-r--r--gas/testsuite/gas/aarch64/morello-ldst-reloc.d12
-rw-r--r--gas/testsuite/gas/aarch64/reloc-insn.d4
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