This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Bug ld/22903] New: [AArch64] Insufficient veneer stub alignment


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>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]