]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
aarch64: Don't relax relocations to static function symbols
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 9 Jan 2026 17:59:45 +0000 (17:59 +0000)
committerRichard Earnshaw <rearnsha@arm.com>
Mon, 12 Jan 2026 10:55:55 +0000 (10:55 +0000)
The aarch64 ABI states that long branch veneers may be added to
facilitate linking code that is beyond the range of a 26-bit call or
branch; but it requires that the target symbol be a function symbol.

Ensure that this latter condition is maintained by rejecting
relaxation of a static function symbol to it's section symbol.

Note that there should probably be a fix to the linker to enforce this
during link time.  I've not done this for now because that might break
some existing object code that has been built with older versions of
gas.  At some point we should revisit this.

This change also causes a small change in the LD testsuite: instead of
generating some veneers with the section name we now (correctly)
generate them using the name of the called function.

gas/config/tc-aarch64.c
gas/config/tc-aarch64.h
gas/testsuite/gas/aarch64/fix-adj.d [new file with mode: 0644]
gas/testsuite/gas/aarch64/fix-adj.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/farcall-b-section.d
ld/testsuite/ld-aarch64/farcall-bl-section.d

index 6a03dfe41ecb7b1e98f5e20efad0ae58c4e99b13..7b0d5d22b0cda1a14432d3f084b139f35b151746 100644 (file)
@@ -10259,6 +10259,24 @@ cons_fix_new_aarch64 (fragS * frag, int where, int size, expressionS * exp)
   fix_new_exp (frag, where, size, exp, pcrel, type);
 }
 
+/* Implement tc_fix_adjustable().
+   On aarch64 a jump or call to a function symbol must not be relaxed to
+   some other type of symbol: the linker uses this information to determine
+   when it is safe to insert far-branch veneers.  */
+
+bool
+aarch64_fix_adjustable (fixS *fixp)
+{
+  if (fixp->fx_addsy == NULL)
+    return true;
+
+  /* Preserve relocations against function symbols.  */
+  if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION)
+    return false;
+
+  return true;
+}
+
 /* Implement md_after_parse_args.  This is the earliest time we need to decide
    ABI.  If no -mabi specified, the ABI will be decided by target triplet.  */
 
index 70e50384fbc8e2059ce45e24a91425404b730270..dced9e42296dde3def5dab166592045222b316bc 100644 (file)
@@ -276,7 +276,7 @@ extern void aarch64_after_parse_args (void);
 #define md_after_parse_args() aarch64_after_parse_args ()
 
 # define EXTERN_FORCE_RELOC                    1
-# define tc_fix_adjustable(FIX)                1
+# define tc_fix_adjustable(FIX)                aarch64_fix_adjustable (FIX)
 
 /* Values passed to md_apply_fix don't include the symbol value.  */
 # define MD_APPLY_SYM_VALUE(FIX)               0
@@ -360,6 +360,7 @@ extern void aarch64_init_frag (struct frag *, int);
 extern void aarch64_handle_align (struct frag *);
 extern int tc_aarch64_regname_to_dw2regnum (char *regname);
 extern void tc_aarch64_frame_initial_instructions (void);
+extern bool aarch64_fix_adjustable (struct fix *);
 
 #ifdef TE_PE
 
diff --git a/gas/testsuite/gas/aarch64/fix-adj.d b/gas/testsuite/gas/aarch64/fix-adj.d
new file mode 100644 (file)
index 0000000..306651a
--- /dev/null
@@ -0,0 +1,11 @@
+#objdump: -r
+#notarget: *-*-*coff
+# Relocations to functions should point to the symbol, not the section.
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR \[\.text\.2\]:
+OFFSET           TYPE              VALUE
+0+0 R_AARCH64_CALL26  f1
+0+4 R_AARCH64_JUMP26  f1
+#...
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/fix-adj.s b/gas/testsuite/gas/aarch64/fix-adj.s
new file mode 100644 (file)
index 0000000..e0e2d46
--- /dev/null
@@ -0,0 +1,13 @@
+       .section .text.1, "ax", @progbits
+       .type f1, %function
+       .p2align 2
+       nop
+f1:
+       nop
+       .section .text.2, "ax", @progbits
+       .global f2
+       .type f2, %function
+       .p2align 2
+f2:
+       bl      f1
+       b       f1
index fd83c25d00ea08448768636f399cc61776972c1e..3872cd0b7c66c808ddfd55b1f1e0c8a1872fd8c0 100644 (file)
@@ -8,22 +8,22 @@
 Disassembly of section .text:
 
 .* <_start>:
-    1000:      1400000a        b       1028 <__\.foo_veneer>
-    1004:      14000005        b       1018 <__\.foo_veneer>
+    1000:      14000006        b       1018 <__bar_veneer>
+    1004:      14000009        b       1028 <__bar2_veneer>
     1008:      d65f03c0        ret
     100c:      d503201f        nop
-    1010:      1400000e        b       1048 <__\.foo_veneer\+0x20>
+    1010:      1400000e        b       1048 <__bar2_veneer\+0x20>
     1014:      d503201f        nop
 
-.* <__\.foo_veneer>:
+.* <__bar_veneer>:
     1018:      90040010        adrp    x16, 8001000 <bar>
-    101c:      91001210        add     x16, x16, #0x4
+    101c:      91000210        add     x16, x16, #0x0
     1020:      d61f0200        br      x16
     1024:      00000000        udf     #0
 
-.* <__\.foo_veneer>:
+.* <__bar2_veneer>:
     1028:      90040010        adrp    x16, 8001000 <bar>
-    102c:      91000210        add     x16, x16, #0x0
+    102c:      91001210        add     x16, x16, #0x4
     1030:      d61f0200        br      x16
        ...
 
index 665d9a4ef7ece167beba9d185a3bae6ca36d6dfd..03ebe2991d636ffc39e6cd972d684ed204b0435a 100644 (file)
@@ -8,22 +8,22 @@
 Disassembly of section .text:
 
 .* <_start>:
-    1000:      9400000a        bl      1028 <__\.foo_veneer>
-    1004:      94000005        bl      1018 <__\.foo_veneer>
+    1000:      94000006        bl      1018 <__bar_veneer>
+    1004:      94000009        bl      1028 <__bar2_veneer>
     1008:      d65f03c0        ret
     100c:      d503201f        nop
-    1010:      1400000e        b       1048 <__\.foo_veneer\+0x20>
+    1010:      1400000e        b       1048 <__bar2_veneer\+0x20>
     1014:      d503201f        nop
 
-.* <__\.foo_veneer>:
+.* <__bar_veneer>:
     1018:      90040010        adrp    x16, 8001000 <bar>
-    101c:      91001210        add     x16, x16, #0x4
+    101c:      91000210        add     x16, x16, #0x0
     1020:      d61f0200        br      x16
     1024:      00000000        udf     #0
 
-.* <__\.foo_veneer>:
+.* <__bar2_veneer>:
     1028:      90040010        adrp    x16, 8001000 <bar>
-    102c:      91000210        add     x16, x16, #0x0
+    102c:      91001210        add     x16, x16, #0x4
     1030:      d61f0200        br      x16
        ...