This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [Bug ld/22903] New: [AArch64] Insufficient veneer stub alignment
- From: Nick Clifton <nickc at redhat dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>, rearnsha at arm dot com, marcus dot shawcroft at arm dot com
- Date: Wed, 28 Feb 2018 16:23:23 +0000
- Subject: Re: [Bug ld/22903] New: [AArch64] Insufficient veneer stub alignment
- Authentication-results: sourceware.org; auth=none
- References: <bug-22903-70@http.sourceware.org/bugzilla/>
Hi Guys,
PR 22903 has just been filed concerning a potential problem with misaligned AArch64 long branch stubs:
> https://sourceware.org/bugzilla/show_bug.cgi?id=22903
Attached is a patch that can fix the problem, but it does have the side effect of potentially
increasing the size of AArch64 binaries, in the cases where a long branch stub needs to be
aligned to an 8-byte boundary. Is this going to be a problem for anyone ?
Cheers
Nick
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 59027ccaf9..3b5d8cfd51 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -3044,10 +3044,25 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
{
bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
+ stub_sec->output_offset);
-
+#if ARCH_SIZE == 64
+ /* Long branch stubs need 8-byte alignment as the initial
+ LDR instruction will fault if only aligned to 4-bytes
+ and executed with hardware alignment checking enabled. */
+ place = BFD_ALIGN (place, 8);
+#endif
/* See if we can relax the stub. */
if (aarch64_valid_for_adrp_p (sym_value, place))
stub_entry->stub_type = aarch64_select_branch_stub (sym_value, place);
+
+#if ARCH_SIZE == 64
+ if (stub_entry->stub_type == aarch64_stub_long_branch
+ && (stub_entry->stub_offset & 4))
+ {
+ bfd_putl32 (INSN_NOP, loc);
+ loc += 4;
+ stub_entry->stub_offset += 4;
+ }
+#endif
}
switch (stub_entry->stub_type)
@@ -7898,6 +7913,12 @@ aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
return FALSE;
break;
case aarch64_stub_long_branch:
+#if ARCH_SIZE == 64
+ /* Long branch stubs need 8-byte alignment as the initial
+ LDR instruction will fault if only aligned to 4-bytes
+ and executed with hardware alignment checking enabled. */
+ addr = BFD_ALIGN (addr, 8);
+#endif
if (!elfNN_aarch64_output_stub_sym
(osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
return FALSE;
diff --git a/ld/testsuite/ld-aarch64/farcall-back.d b/ld/testsuite/ld-aarch64/farcall-back.d
index 8b2236067b..15fecc736a 100644
--- a/ld/testsuite/ld-aarch64/farcall-back.d
+++ b/ld/testsuite/ld-aarch64/farcall-back.d
@@ -13,8 +13,8 @@ Disassembly of section .text:
1004: 94000412 bl 204c <__bar1_veneer>
1008: 14000407 b 2024 <__bar2_veneer>
100c: 94000406 bl 2024 <__bar2_veneer>
- 1010: 14000409 b 2034 <__bar3_veneer>
- 1014: 94000408 bl 2034 <__bar3_veneer>
+ 1010: 1400040a b 2038 <__bar3_veneer>
+ 1014: 94000409 bl 2038 <__bar3_veneer>
1018: d65f03c0 ret
...
@@ -22,19 +22,20 @@ Disassembly of section .text:
201c: d65f03c0 ret
[ \t]+2020:[ \t]+14000013[ \t]+b[ \t]+206c <__bar1_veneer\+0x20>
+
0000000000002024 <__bar2_veneer>:
2024: f07ffff0 adrp x16, 100001000 <bar1\+0x1000>
2028: 91002210 add x16, x16, #0x8
202c: d61f0200 br x16
2030: 00000000 .inst 0x00000000 ; undefined
+ 2034: d503201f nop
-0000000000002034 <__bar3_veneer>:
- 2034: 58000090 ldr x16, 2044 <__bar3_veneer\+0x10>
- 2038: 10000011 adr x17, 2038 <__bar3_veneer\+0x4>
- 203c: 8b110210 add x16, x16, x17
- 2040: d61f0200 br x16
- 2044: ffffffd8 .word 0xffffffd8
- 2048: 00000000 .word 0x00000000
+0000000000002038 <__bar3_veneer>:
+ 2038: 58000090 ldr x16, 2048 <__bar3_veneer\+0x10>
+ 203c: 10000011 adr x17, 203c <__bar3_veneer\+0x4>
+ 2040: 8b110210 add x16, x16, x17
+ 2044: d61f0200 br x16
+ 2048: ffffffd4 .word 0xffffffd4
000000000000204c <__bar1_veneer>:
204c: d07ffff0 adrp x16, 100000000 <bar1>
@@ -46,26 +47,26 @@ Disassembly of section .foo:
0000000100000000 <bar1>:
100000000: d65f03c0 ret
- 100000004: 14000806 b 10000201c <___start_veneer>
+ 100000004: 14000807 b 100002020 <___start_veneer>
...
0000000100001008 <bar2>:
100001008: d65f03c0 ret
- 10000100c: 14000404 b 10000201c <___start_veneer>
+ 10000100c: 14000405 b 100002020 <___start_veneer>
...
0000000100002010 <bar3>:
100002010: d65f03c0 ret
100002014: 14000008 b 100002034 <___back_veneer>
-
[ \t]+100002018:[ \t]+1400000d[ \t]+b[ \t]+10000204c <___back_veneer\+0x18>
-000000010000201c <___start_veneer>:
- 10000201c: 58000090 ldr x16, 10000202c <___start_veneer\+0x10>
- 100002020: 10000011 adr x17, 100002020 <___start_veneer\+0x4>
- 100002024: 8b110210 add x16, x16, x17
- 100002028: d61f0200 br x16
- 10000202c: ffffefe0 .word 0xffffefe0
- 100002030: fffffffe .word 0xfffffffe
+ 10000201c: d503201f nop
+
+0000000100002020 <___start_veneer>:
+ 100002020: 58000090 ldr x16, 100002030 <___start_veneer\+0x10>
+ 100002024: 10000011 adr x17, 100002024 <___start_veneer\+0x4>
+ 100002028: 8b110210 add x16, x16, x17
+ 10000202c: d61f0200 br x16
+ 100002030: ffffefdc .word 0xffffefdc
0000000100002034 <___back_veneer>:
100002034: 90800010 adrp x16, 2000 <_start\+0x1000>