]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Disable some symbol -> section_symbol + offset translations
authorMatthew Malcomson <matthew.malcomson@arm.com>
Fri, 4 Nov 2022 10:01:52 +0000 (10:01 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Fri, 4 Nov 2022 10:03:06 +0000 (10:03 +0000)
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.

gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/morello-ldst-reloc.d
gas/testsuite/gas/aarch64/reloc-insn.d

index a1bd6e1a769d968ed0bdb2b3dca7bc87732cc498..c8373b311dd14f3c53ce4099ab1ffee28d360e8a 100644 (file)
@@ -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
index d2fb08ec9d13c28e6fa70f12c8f49f88fc37f34f..2199e90dd9091367ff6b8f237fa806ab642386ca 100644 (file)
@@ -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
index 0f3b4143d964ed08ef1d435fd518a7e2b13a80f8..8898a88bca0fe8f8e2755741c9d466636bf4aaff 100644 (file)
@@ -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