[lld] 86d2419 - [LLD][ELF][AArch64][ARM] When errata patching, round thunk size to 4KiB.

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 11 06:09:32 PST 2019


Author: Peter Smith
Date: 2019-12-11T14:09:15Z
New Revision: 86d24193a9eb45d7bf3745fc2de96cd4e197b08a

URL: https://github.com/llvm/llvm-project/commit/86d24193a9eb45d7bf3745fc2de96cd4e197b08a
DIFF: https://github.com/llvm/llvm-project/commit/86d24193a9eb45d7bf3745fc2de96cd4e197b08a.diff

LOG: [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

Added: 
    

Modified: 
    lld/ELF/SyntheticSections.cpp
    lld/ELF/SyntheticSections.h
    lld/test/ELF/aarch64-cortex-a53-843419-thunk.s
    lld/test/ELF/arm-fix-cortex-a8-thunk.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index a8aabe75a180..d014da220817 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -3355,6 +3355,17 @@ ThunkSection::ThunkSection(OutputSection *os, uint64_t off)
   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/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index afd34bbbd8b3..dee21f319980 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1033,7 +1033,7 @@ class ThunkSection : public SyntheticSection {
   // 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/test/ELF/aarch64-cortex-a53-843419-thunk.s b/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s
index dac644f930bf..c1d3d673906d 100644
--- 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 @@ t3_ff8_ldr:
         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
index e7e07c33c8ee..c1efb5bd2481 100644
--- 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 @@ early:
 _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 @@ target:
  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


        


More information about the llvm-commits mailing list