diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1033,7 +1033,7 @@ // Thunk defines a symbol in this InputSection that can be used as target // of a relocation void addThunk(Thunk *t); - size_t getSize() const override { return size; } + size_t getSize() const override; void writeTo(uint8_t *buf) override; InputSection *getTargetInputSection() const; bool assignOffsets(); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3355,6 +3355,17 @@ this->outSecOff = off; } +// When the errata patching is on, we round the size up to a 4 KiB +// boundary. This limits the effect that adding Thunks has on the addresses +// of the program modulo 4 KiB. As the errata patching is sensitive to address +// modulo 4 KiB this can prevent further patches from being needed due to +// Thunk insertion. +size_t ThunkSection::getSize() const { + if (config->fixCortexA53Errata843419 || config->fixCortexA8) + return alignTo(size, 4096); + return size; +} + void ThunkSection::addThunk(Thunk *t) { thunks.push_back(t); t->addSymbols(*this); diff --git a/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s b/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s --- a/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s +++ b/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s @@ -3,16 +3,17 @@ // RUN: echo "SECTIONS { \ // RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \ // RUN: .text2 0x8010000 : { *(.text.04) } } " > %t.script -// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-PRINT %s -// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s +// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 \ +// RUN: 2>&1 | FileCheck -check-prefix=CHECK-PRINT %s -// %t2 is 128 Megabytes, so delete it early. +// RUN: llvm-objdump --no-show-raw-insn -triple=aarch64-linux-gnu -d %t2 | FileCheck %s + +/// %t2 is 128 Megabytes, so delete it early. // RUN: rm %t2 -// Test cases for Cortex-A53 Erratum 843419 that involve interactions with -// range extension thunks. Both erratum fixes and range extension thunks need -// precise address information and after creation alter address information. +/// Test cases for Cortex-A53 Erratum 843419 that involve interactions with +/// range extension thunks. Both erratum fixes and range extension thunks need +/// precise address information and after creation alter address information. .section .text.01, "ax", %progbits @@ -21,13 +22,15 @@ .type _start, %function _start: bl far_away - // Thunk to far_away, size 16-bytes goes here. + /// Thunk to far_away, size 16-bytes goes here. + /// Thunk Section with patch enabled has its size rounded up to 4KiB + /// this leaves the address of following sections the same modulo 4 KiB .section .text.02, "ax", %progbits - .space 4096 - 28 + .space 4096 - 12 - // Erratum sequence will only line up at address 0 modulo 0xffc when - // Thunk is inserted. + /// Erratum sequence will only line up at address 0 modulo 0xffc when + /// Thunk is inserted. .section .text.03, "ax", %progbits .globl t3_ff8_ldr .type t3_ff8_ldr, %function @@ -37,16 +40,15 @@ ldr x0, [x0, :got_lo12:dat] ret -// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 10FFC in unpatched output. -// CHECK: t3_ff8_ldr: -// CHECK-NEXT: 10ffc: 00 00 04 90 adrp x0, #134217728 -// CHECK-NEXT: 11000: 21 00 40 f9 ldr x1, [x1] -// CHECK-NEXT: 11004: 02 00 00 14 b #8 -// CHECK-NEXT: 11008: c0 03 5f d6 ret -// CHECK: __CortexA53843419_11004: -// CHECK-NEXT: 1100c: 00 04 40 f9 ldr x0, [x0, #8] -// CHECK-NEXT: 11010: fe ff ff 17 b #-8 - +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 11FFC in unpatched output. +// CHECK: 0000000000011ffc t3_ff8_ldr: +// CHECK-NEXT: adrp x0, #134213632 +// CHECK-NEXT: ldr x1, [x1] +// CHECK-NEXT: b #8 +// CHECK-NEXT: ret +// CHECK: 000000000001200c __CortexA53843419_12004: +// CHECK-NEXT: ldr x0, [x0, #8] +// CHECK-NEXT: b #-8 .section .text.04, "ax", %progbits .globl far_away .type far_away, function diff --git a/lld/test/ELF/arm-fix-cortex-a8-thunk.s b/lld/test/ELF/arm-fix-cortex-a8-thunk.s --- a/lld/test/ELF/arm-fix-cortex-a8-thunk.s +++ b/lld/test/ELF/arm-fix-cortex-a8-thunk.s @@ -1,14 +1,12 @@ // REQUIRES: arm // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf --arm-add-build-attributes %s -o %t.o // RUN: echo "SECTIONS { \ -// RUN: .text0 0x011006 : { *(.text.00) } \ +// RUN: .text0 0x01200a : { *(.text.00) } \ // RUN: .text1 0x110000 : { *(.text.01) *(.text.02) *(.text.03) \ // RUN: *(.text.04) } \ // RUN: .text2 0x210000 : { *(.text.05) } } " > %t.script // RUN: ld.lld --script %t.script --fix-cortex-a8 --shared -verbose %t.o -o %t2 2>&1 -// RUN: llvm-objdump -d --no-show-raw-insn --start-address=0x110000 --stop-address=0x110010 %t2 | FileCheck --check-prefix=THUNK %s -// RUN: llvm-objdump -d --no-show-raw-insn --start-address=0x110ffa --stop-address=0x111008 %t2 | FileCheck --check-prefix=PATCH %s -// RUN: llvm-objdump -d --no-show-raw-insn --start-address=0x111008 --stop-address=0x111010 %t2 | FileCheck --check-prefix=THUNK2 %s +// RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s /// Test cases for Cortex-a8 Erratum 657417 that involve interactions with /// range extension thunks. Both erratum fixes and range extension thunks need @@ -27,16 +25,14 @@ _start: beq.w far_away /// Thunk to far_away and state change needed, size 12-bytes goes here. -// THUNK: 00110000 _start: -// THUNK-NEXT: 110000: beq.w #0 <__ThumbV7PILongThunk_far_away+0x4> -// THUNK: 00110004 __ThumbV7PILongThunk_far_away: -// THUNK-NEXT: 110004: movw r12, #65524 -// THUNK-NEXT: 110008: movt r12, #15 -// THUNK-NEXT: 11000c: add r12, pc -// THUNK-NEXT: 11000e: bx r12 +// CHECK: 00110004 __ThumbV7PILongThunk_far_away: +// CHECK-NEXT: 110004: movw r12, #65524 +// CHECK-NEXT: movt r12, #15 +// CHECK-NEXT: add r12, pc +// CHECK-NEXT: bx r12 .section .text.02, "ax", %progbits - .space 4096 - 22 + .space 4096 - 10 .section .text.03, "ax", %progbits .thumb_func @@ -47,20 +43,22 @@ bl target /// Expect erratum patch inserted here -// PATCH: 00110ffa target: -// PATCH-NEXT: 110ffa: nop.w -// PATCH-NEXT: 110ffe: bl #2 -// PATCH: 00111004 __CortexA8657417_110FFE: -// PATCH-NEXT: 111004: b.w #-14 +// CHECK: 00111ffa target: +// CHECK-NEXT: 111ffa: nop.w +// CHECK-NEXT: bl #2 +// CHECK: 00112004 __CortexA8657417_111FFE: +// CHECK-NEXT: 112004: b.w #-14 + +/// Expect range extension thunk here. +// CHECK: 00112008 __ThumbV7PILongThunk_early: +// CHECK-NEXT: 112008: b.w #-1048578 -// THUNK2: 00111008 __ThumbV7PILongThunk_early: -// THUNK2-NEXT: 111008: b.w #-1048582 .section .text.04, "ax", %progbits /// The erratum patch will push this branch out of range, so another /// range extension thunk will be needed. - beq.w early -// THUNK2-NEXT 11100c: beq.w #-8 -/// Expect range extension thunk here. + beq.w early +// CHECK: 113008: beq.w #-4100 + .section .text.05, "ax", %progbits .arm nop