Skip to content

Commit e47d3a3

Browse files
authored
[LLD][AArch64] Increase alignment of AArch64AbsLongThunk to 8 (llvm#133738)
This permits an AArch64AbsLongThunk to be used in an environment where unaligned accesses are disabled. The AArch64AbsLongThunk does a load of an 8-byte address. When unaligned accesses are disabled this address must be 8-byte aligned. The vast majority of AArch64 systems will have unaligned accesses enabled in userspace. However, after a reset, before the MMU has been enabled, all memory accesses are to "device" memory, which requires aligned accesses. In systems with multi-stage boot loaders a thunk may be required to a later stage before the MMU has been enabled. As we only want to increase the alignment when the ldr is used we delay the increase in thunk alignment until we know we are going to write an ldr. We also need to account for the ThunkSection alignment increase when this happens. In some of the test updates, particularly those with shared CHECK lines with position independent thunks it was easier to ensure that the thunks started at an 8-byte aligned address in all cases.
1 parent 6c3adaa commit e47d3a3

9 files changed

+151
-99
lines changed

lld/ELF/SyntheticSections.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4317,14 +4317,20 @@ InputSection *ThunkSection::getTargetInputSection() const {
43174317

43184318
bool ThunkSection::assignOffsets() {
43194319
uint64_t off = 0;
4320+
bool changed = false;
43204321
for (Thunk *t : thunks) {
4322+
if (t->alignment > addralign) {
4323+
addralign = t->alignment;
4324+
changed = true;
4325+
}
43214326
off = alignToPowerOf2(off, t->alignment);
43224327
t->setOffset(off);
43234328
uint32_t size = t->size();
43244329
t->getThunkTargetSym()->size = size;
43254330
off += size;
43264331
}
4327-
bool changed = off != size;
4332+
if (off != size)
4333+
changed = true;
43284334
size = off;
43294335
return changed;
43304336
}

lld/ELF/Thunks.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,9 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
674674

675675
void AArch64ABSLongThunk::addLongMapSyms() {
676676
addSymbol("$d", STT_NOTYPE, 8, *tsec);
677+
// The ldr in the long Thunk requires 8-byte alignment when
678+
// unaligned accesses are disabled.
679+
alignment = 8;
677680
}
678681

679682
void AArch64ABSXOLongThunk::writeLong(uint8_t *buf) {

lld/test/ELF/aarch64-call26-thunk.s

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
_start:
1010
bl big
1111

12-
// CHECK: Disassembly of section .text:
12+
// CHECK-LABEL: <_start>:
13+
// CHECK-NEXT: 210120: bl 0x210128 <__AArch64AbsLongThunk_big>
14+
// CHECK-NEXT: udf #0x0
1315
// CHECK-EMPTY:
14-
// CHECK-NEXT: <_start>:
15-
// CHECK-NEXT: 210120: bl 0x210124
16-
// CHECK: <__AArch64AbsLongThunk_big>:
17-
// CHECK-NEXT: 210124: ldr x16, 0x21012c
18-
// CHECK-NEXT: 210128: br x16
19-
// CHECK-NEXT: 21012c: 00 00 00 00 .word 0x00000000
20-
// CHECK-NEXT: 210130: 10 00 00 00 .word 0x00000010
16+
// CHECK-LABEL: <__AArch64AbsLongThunk_big>:
17+
// CHECK-NEXT: 210128: ldr x16, 0x210130 <__AArch64AbsLongThunk_big+0x8>
18+
// CHECK-NEXT: br x16
19+
// CHECK-NEXT: 00 00 00 00 .word 0x00000000
20+
// CHECK-NEXT: 10 00 00 00 .word 0x00000010
2121

lld/test/ELF/aarch64-cortex-a53-843419-thunk.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ _start:
2424
/// Thunk to far_away, size 16-bytes goes here.
2525

2626
.section .text.02, "ax", %progbits
27-
.space 4096 - 28
27+
.space 4096 - 32
2828

2929
/// Erratum sequence will only line up at address 0 modulo 0xffc when
3030
/// Thunk is inserted.

lld/test/ELF/aarch64-jump26-thunk.s

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ _start:
1111

1212
// CHECK: Disassembly of section .text:
1313
// CHECK-EMPTY:
14-
// CHECK-NEXT: <_start>:
15-
// CHECK-NEXT: 210120: b 0x210124
16-
// CHECK: <__AArch64AbsLongThunk_big>:
17-
// CHECK-NEXT: 210124: ldr x16, 0x21012c
18-
// CHECK-NEXT: 210128: br x16
19-
// CHECK-NEXT: 21012c: 00 00 00 00 .word 0x00000000
20-
// CHECK-NEXT: 210130: 10 00 00 00 .word 0x00000010
14+
// CHECK-LABEL: <_start>:
15+
// CHECK-NEXT: 210120: b 0x210128
16+
// CHECK-NEXT: udf #0x0
17+
// CHECK-LABEL: <__AArch64AbsLongThunk_big>:
18+
// CHECK-NEXT: 210128: ldr x16, 0x210130
19+
// CHECK-NEXT: br x16
20+
// CHECK-NEXT: 00 00 00 00 .word 0x00000000
21+
// CHECK-NEXT: 10 00 00 00 .word 0x00000010

lld/test/ELF/aarch64-range-thunk-extension-plt32.s

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99

1010
// The word should be an offset to the range extension thunk.
1111
// CHECK-LABEL: <_start>:
12-
// CHECK-NEXT: 10000: 04 00 00 00 .word 0x00000004
12+
// CHECK-NEXT: 10000: 08 00 00 00 .word 0x00000008
1313

1414
// The thunk redirects to the address of callee.
1515
// CHECK-LABEL: <__AArch64AbsLongThunk_callee>:
16-
// CHECK-NEXT: 10004: ldr x16, 0x1000c <__AArch64AbsLongThunk_callee+0x8>
17-
// CHECK-NEXT: 10008: br x16
18-
// CHECK-NEXT: 1000c: 00 00 00 00 .word 0x00000000
19-
// CHECK-NEXT: 10010: 02 00 00 00 .word 0x00000002
16+
// CHECK-NEXT: 10008: ldr x16, 0x10010 <__AArch64AbsLongThunk_callee+0x8>
17+
// CHECK-NEXT: br x16
18+
// CHECK-NEXT: 00 00 00 00 .word 0x00000000
19+
// CHECK-NEXT: 02 00 00 00 .word 0x00000002
2020

2121
// CHECK-LABEL: <callee>:
2222
// CHECK-NEXT: 200000000: ret

lld/test/ELF/aarch64-thunk-align.s

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// REQUIRES: aarch64
2+
// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t
3+
// RUN: ld.lld -Ttext=0x12000 -defsym long=0x10000000 -defsym short=0x8012004 -defsym short2=0x8012008 -defsym short3=0x801200c %t -o %t.exe
4+
// RUN: llvm-objdump -d --no-show-raw-insn %t.exe | FileCheck %s
5+
6+
/// The AArch64AbsLongThunk requires 8-byte alignment just in case unaligned
7+
/// accesses are disabled. This increases the thunk section alignment to 8,
8+
/// and the alignment of the AArch64AbsLongThunk to 8. The short thunk form
9+
/// can still use 4-byte alignment.
10+
.text
11+
.type _start, %function
12+
.globl _start
13+
_start:
14+
b short
15+
b short2
16+
b short3
17+
b long
18+
nop
19+
20+
// CHECK-LABEL: <_start>:
21+
// CHECK-NEXT: 12000: b 0x12018 <__AArch64AbsLongThunk_short>
22+
// CHECK-NEXT: b 0x1201c <__AArch64AbsLongThunk_short2>
23+
// CHECK-NEXT: b 0x12020 <__AArch64AbsLongThunk_short3>
24+
// CHECK-NEXT: b 0x12028 <__AArch64AbsLongThunk_long>
25+
// CHECK-NEXT: nop
26+
// CHECK-NEXT: udf #0x0
27+
// CHECK-EMPTY:
28+
// CHECK-LABEL: <__AArch64AbsLongThunk_short>:
29+
// CHECK-NEXT: 12018: b 0x8012004 <__AArch64AbsLongThunk_long+0x7ffffdc>
30+
// CHECK-EMPY:
31+
// CHECK-LABEL: <__AArch64AbsLongThunk_short2>:
32+
// CHECK-NEXT: 1201c: b 0x8012008 <__AArch64AbsLongThunk_long+0x7ffffe0>
33+
// CHECK-EMPTY:
34+
// CHECK-LABEL: <__AArch64AbsLongThunk_short3>:
35+
// CHECK-NEXT: 12020: b 0x801200c <__AArch64AbsLongThunk_long+0x7ffffe4>
36+
// CHECK-NEXT: udf #0x0
37+
// CHECK-EMPTY:
38+
// CHECK-LABEL: <__AArch64AbsLongThunk_long>:
39+
// CHECK-NEXT: 12028: ldr x16, 0x12030 <__AArch64AbsLongThunk_long+0x8>
40+
// CHECK-NEXT: br x16
41+
// CHECK-NEXT: 00 00 00 10 .word 0x10000000
42+
// CHECK-NEXT: 00 00 00 00 .word 0x00000000

lld/test/ELF/aarch64-thunk-bti-multipass.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ _start:
3838
/// and will need a long branch thunk, which in turn needs a BTI landing pad.
3939

4040
// CHECK-LABEL: <_start>:
41-
// CHECK-NEXT: 10001000: bl 0x10002004 <__AArch64AbsLongThunk_fn1>
41+
// CHECK-NEXT: 10001000: bl 0x10002008 <__AArch64AbsLongThunk_fn1>
4242

4343
// CHECK-LABEL: <__AArch64AbsLongThunk_fn1>:
44-
// CHECK-NEXT: 10002004: ldr x16, 0x1000200c <__AArch64AbsLongThunk_fn1+0x8>
44+
// CHECK-NEXT: 10002008: ldr x16, 0x10002010 <__AArch64AbsLongThunk_fn1+0x8>
4545
// CHECK-NEXT: br x16
4646
// CHECK-NEXT: 00 30 00 18 .word 0x18003000
4747
// CHECK-NEXT: 00 00 00 00 .word 0x00000000

0 commit comments

Comments
 (0)