Skip to content

Commit 86d2419

Browse files
committed
[LLD][ELF][AArch64][ARM] When errata patching, round thunk size to 4KiB.
On some edge cases such as Chromium compiled with full instrumentation we have a .text section over twice the size of the maximum branch range and the instrumented code generation containing many examples of the erratum sequence. The combination of Thunks and many erratum sequences causes finalizeAddressDependentContent() to not converge. We end up with: start - Thunk Creation (disturbs addresses after thunks, creating more patches) - Patch Creation (disturbs addresses after patches, creating more thunks) - goto start In most images with few thunks and patches the mutual disturbance does not cause convergence problems. As the .text size and number of patches go up the risk increases. A way to prevent the thunk creation from interfering with patch creation is to round up the size of the thunks to a 4KiB boundary when the erratum patch is enabled. As the erratum sequence only triggers when an instruction sequence starts at 0xff8 or 0xffc modulo (4 KiB) by making the thunks not affect addresses modulo (4 KiB) we prevent thunks from interfering with the patch. The patches themselves could be aggregated in the same way that Thunks are within ThunkSections and we could round up the size in the same way. This would reduce the number of patches created in a .text section size > 128 MiB but would not likely help convergence problems. Differential Revision: https://reviews.llvm.org/D71281 fixes (remaining part of) pr44071, other part in D71242
1 parent 247b2ce commit 86d2419

File tree

4 files changed

+55
-44
lines changed

4 files changed

+55
-44
lines changed

lld/ELF/SyntheticSections.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3355,6 +3355,17 @@ ThunkSection::ThunkSection(OutputSection *os, uint64_t off)
33553355
this->outSecOff = off;
33563356
}
33573357

3358+
// When the errata patching is on, we round the size up to a 4 KiB
3359+
// boundary. This limits the effect that adding Thunks has on the addresses
3360+
// of the program modulo 4 KiB. As the errata patching is sensitive to address
3361+
// modulo 4 KiB this can prevent further patches from being needed due to
3362+
// Thunk insertion.
3363+
size_t ThunkSection::getSize() const {
3364+
if (config->fixCortexA53Errata843419 || config->fixCortexA8)
3365+
return alignTo(size, 4096);
3366+
return size;
3367+
}
3368+
33583369
void ThunkSection::addThunk(Thunk *t) {
33593370
thunks.push_back(t);
33603371
t->addSymbols(*this);

lld/ELF/SyntheticSections.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ class ThunkSection : public SyntheticSection {
10331033
// Thunk defines a symbol in this InputSection that can be used as target
10341034
// of a relocation
10351035
void addThunk(Thunk *t);
1036-
size_t getSize() const override { return size; }
1036+
size_t getSize() const override;
10371037
void writeTo(uint8_t *buf) override;
10381038
InputSection *getTargetInputSection() const;
10391039
bool assignOffsets();

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

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
// RUN: echo "SECTIONS { \
44
// RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \
55
// RUN: .text2 0x8010000 : { *(.text.04) } } " > %t.script
6-
// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 2>&1 \
7-
// RUN: | FileCheck -check-prefix=CHECK-PRINT %s
8-
// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s
6+
// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 \
7+
// RUN: 2>&1 | FileCheck -check-prefix=CHECK-PRINT %s
98

10-
// %t2 is 128 Megabytes, so delete it early.
9+
// RUN: llvm-objdump --no-show-raw-insn -triple=aarch64-linux-gnu -d %t2 | FileCheck %s
10+
11+
/// %t2 is 128 Megabytes, so delete it early.
1112
// RUN: rm %t2
1213

13-
// Test cases for Cortex-A53 Erratum 843419 that involve interactions with
14-
// range extension thunks. Both erratum fixes and range extension thunks need
15-
// precise address information and after creation alter address information.
14+
/// Test cases for Cortex-A53 Erratum 843419 that involve interactions with
15+
/// range extension thunks. Both erratum fixes and range extension thunks need
16+
/// precise address information and after creation alter address information.
1617

1718

1819
.section .text.01, "ax", %progbits
@@ -21,13 +22,15 @@
2122
.type _start, %function
2223
_start:
2324
bl far_away
24-
// Thunk to far_away, size 16-bytes goes here.
25+
/// Thunk to far_away, size 16-bytes goes here.
26+
/// Thunk Section with patch enabled has its size rounded up to 4KiB
27+
/// this leaves the address of following sections the same modulo 4 KiB
2528

2629
.section .text.02, "ax", %progbits
27-
.space 4096 - 28
30+
.space 4096 - 12
2831

29-
// Erratum sequence will only line up at address 0 modulo 0xffc when
30-
// Thunk is inserted.
32+
/// Erratum sequence will only line up at address 0 modulo 0xffc when
33+
/// Thunk is inserted.
3134
.section .text.03, "ax", %progbits
3235
.globl t3_ff8_ldr
3336
.type t3_ff8_ldr, %function
@@ -37,16 +40,15 @@ t3_ff8_ldr:
3740
ldr x0, [x0, :got_lo12:dat]
3841
ret
3942

40-
// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 10FFC in unpatched output.
41-
// CHECK: t3_ff8_ldr:
42-
// CHECK-NEXT: 10ffc: 00 00 04 90 adrp x0, #134217728
43-
// CHECK-NEXT: 11000: 21 00 40 f9 ldr x1, [x1]
44-
// CHECK-NEXT: 11004: 02 00 00 14 b #8
45-
// CHECK-NEXT: 11008: c0 03 5f d6 ret
46-
// CHECK: __CortexA53843419_11004:
47-
// CHECK-NEXT: 1100c: 00 04 40 f9 ldr x0, [x0, #8]
48-
// CHECK-NEXT: 11010: fe ff ff 17 b #-8
49-
43+
// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 11FFC in unpatched output.
44+
// CHECK: 0000000000011ffc t3_ff8_ldr:
45+
// CHECK-NEXT: adrp x0, #134213632
46+
// CHECK-NEXT: ldr x1, [x1]
47+
// CHECK-NEXT: b #8
48+
// CHECK-NEXT: ret
49+
// CHECK: 000000000001200c __CortexA53843419_12004:
50+
// CHECK-NEXT: ldr x0, [x0, #8]
51+
// CHECK-NEXT: b #-8
5052
.section .text.04, "ax", %progbits
5153
.globl far_away
5254
.type far_away, function

lld/test/ELF/arm-fix-cortex-a8-thunk.s

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
// REQUIRES: arm
22
// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf --arm-add-build-attributes %s -o %t.o
33
// RUN: echo "SECTIONS { \
4-
// RUN: .text0 0x011006 : { *(.text.00) } \
4+
// RUN: .text0 0x01200a : { *(.text.00) } \
55
// RUN: .text1 0x110000 : { *(.text.01) *(.text.02) *(.text.03) \
66
// RUN: *(.text.04) } \
77
// RUN: .text2 0x210000 : { *(.text.05) } } " > %t.script
88
// RUN: ld.lld --script %t.script --fix-cortex-a8 --shared -verbose %t.o -o %t2 2>&1
9-
// RUN: llvm-objdump -d --no-show-raw-insn --start-address=0x110000 --stop-address=0x110010 %t2 | FileCheck --check-prefix=THUNK %s
10-
// RUN: llvm-objdump -d --no-show-raw-insn --start-address=0x110ffa --stop-address=0x111008 %t2 | FileCheck --check-prefix=PATCH %s
11-
// RUN: llvm-objdump -d --no-show-raw-insn --start-address=0x111008 --stop-address=0x111010 %t2 | FileCheck --check-prefix=THUNK2 %s
9+
// RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s
1210

1311
/// Test cases for Cortex-a8 Erratum 657417 that involve interactions with
1412
/// range extension thunks. Both erratum fixes and range extension thunks need
@@ -27,16 +25,14 @@ early:
2725
_start:
2826
beq.w far_away
2927
/// Thunk to far_away and state change needed, size 12-bytes goes here.
30-
// THUNK: 00110000 _start:
31-
// THUNK-NEXT: 110000: beq.w #0 <__ThumbV7PILongThunk_far_away+0x4>
32-
// THUNK: 00110004 __ThumbV7PILongThunk_far_away:
33-
// THUNK-NEXT: 110004: movw r12, #65524
34-
// THUNK-NEXT: 110008: movt r12, #15
35-
// THUNK-NEXT: 11000c: add r12, pc
36-
// THUNK-NEXT: 11000e: bx r12
28+
// CHECK: 00110004 __ThumbV7PILongThunk_far_away:
29+
// CHECK-NEXT: 110004: movw r12, #65524
30+
// CHECK-NEXT: movt r12, #15
31+
// CHECK-NEXT: add r12, pc
32+
// CHECK-NEXT: bx r12
3733

3834
.section .text.02, "ax", %progbits
39-
.space 4096 - 22
35+
.space 4096 - 10
4036

4137
.section .text.03, "ax", %progbits
4238
.thumb_func
@@ -47,20 +43,22 @@ target:
4743
bl target
4844

4945
/// Expect erratum patch inserted here
50-
// PATCH: 00110ffa target:
51-
// PATCH-NEXT: 110ffa: nop.w
52-
// PATCH-NEXT: 110ffe: bl #2
53-
// PATCH: 00111004 __CortexA8657417_110FFE:
54-
// PATCH-NEXT: 111004: b.w #-14
46+
// CHECK: 00111ffa target:
47+
// CHECK-NEXT: 111ffa: nop.w
48+
// CHECK-NEXT: bl #2
49+
// CHECK: 00112004 __CortexA8657417_111FFE:
50+
// CHECK-NEXT: 112004: b.w #-14
51+
52+
/// Expect range extension thunk here.
53+
// CHECK: 00112008 __ThumbV7PILongThunk_early:
54+
// CHECK-NEXT: 112008: b.w #-1048578
5555

56-
// THUNK2: 00111008 __ThumbV7PILongThunk_early:
57-
// THUNK2-NEXT: 111008: b.w #-1048582
5856
.section .text.04, "ax", %progbits
5957
/// The erratum patch will push this branch out of range, so another
6058
/// range extension thunk will be needed.
61-
beq.w early
62-
// THUNK2-NEXT 11100c: beq.w #-8
63-
/// Expect range extension thunk here.
59+
beq.w early
60+
// CHECK: 113008: beq.w #-4100
61+
6462
.section .text.05, "ax", %progbits
6563
.arm
6664
nop

0 commit comments

Comments
 (0)