diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 6a03dfe41ec..7b0d5d22b0c 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -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. */ diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h index 70e50384fbc..dced9e42296 100644 --- a/gas/config/tc-aarch64.h +++ b/gas/config/tc-aarch64.h @@ -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 index 00000000000..306651adbcc --- /dev/null +++ b/gas/testsuite/gas/aarch64/fix-adj.d @@ -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 index 00000000000..e0e2d46eb65 --- /dev/null +++ b/gas/testsuite/gas/aarch64/fix-adj.s @@ -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 diff --git a/ld/testsuite/ld-aarch64/farcall-b-section.d b/ld/testsuite/ld-aarch64/farcall-b-section.d index fd83c25d00e..3872cd0b7c6 100644 --- a/ld/testsuite/ld-aarch64/farcall-b-section.d +++ b/ld/testsuite/ld-aarch64/farcall-b-section.d @@ -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 - 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 - 102c: 91000210 add x16, x16, #0x0 + 102c: 91001210 add x16, x16, #0x4 1030: d61f0200 br x16 ... diff --git a/ld/testsuite/ld-aarch64/farcall-bl-section.d b/ld/testsuite/ld-aarch64/farcall-bl-section.d index 665d9a4ef7e..03ebe2991d6 100644 --- a/ld/testsuite/ld-aarch64/farcall-bl-section.d +++ b/ld/testsuite/ld-aarch64/farcall-bl-section.d @@ -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 - 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 - 102c: 91000210 add x16, x16, #0x0 + 102c: 91001210 add x16, x16, #0x4 1030: d61f0200 br x16 ...