[lld] 247b2ce - [LLD][ELF][AArch64][ARM] Add missing classof to patch sections.

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


Author: Peter Smith
Date: 2019-12-11T14:09:15Z
New Revision: 247b2ce11cf0b9efeb3c1b0394dcc87ccab7be41

URL: https://github.com/llvm/llvm-project/commit/247b2ce11cf0b9efeb3c1b0394dcc87ccab7be41
DIFF: https://github.com/llvm/llvm-project/commit/247b2ce11cf0b9efeb3c1b0394dcc87ccab7be41.diff

LOG: [LLD][ELF][AArch64][ARM] Add missing classof to patch sections.

The code to insert patch section merges them with a comparison function that
uses logic of the form:
return (isa<PatchSection>(a) && !isa<PatchSection>(b));
If the PatchSections don't implement classof this check fails if b is also
a SyntheticSection. This can result in the patches being out of range if
the SyntheticSection is big, for example a ThunkSection with lots of thunks.

Differential Revision: https://reviews.llvm.org/D71242

fixes (part of) pr44071

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

Modified: 
    lld/ELF/AArch64ErrataFix.cpp
    lld/ELF/ARMErrataFix.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp
index 76fbd6cb96fa..398320af71e3 100644
--- a/lld/ELF/AArch64ErrataFix.cpp
+++ b/lld/ELF/AArch64ErrataFix.cpp
@@ -381,6 +381,10 @@ class Patch843419Section : public SyntheticSection {
 
   uint64_t getLDSTAddr() const;
 
+  static bool classof(const SectionBase *d) {
+    return d->kind() == InputSectionBase::Synthetic && d->name == ".text.patch";
+  }
+
   // The Section we are patching.
   const InputSection *patchee;
   // The offset of the instruction in the patchee section we are patching.

diff  --git a/lld/ELF/ARMErrataFix.cpp b/lld/ELF/ARMErrataFix.cpp
index eb3ebdea544c..91cd2b5a2f5f 100644
--- a/lld/ELF/ARMErrataFix.cpp
+++ b/lld/ELF/ARMErrataFix.cpp
@@ -82,6 +82,10 @@ class Patch657417Section : public SyntheticSection {
   // Get the virtual address of the branch instruction at patcheeOffset.
   uint64_t getBranchAddr() const;
 
+  static bool classof(const SectionBase *d) {
+    return d->kind() == InputSectionBase::Synthetic && d->name ==".text.patch";
+  }
+
   // The Section we are patching.
   const InputSection *patchee;
   // The offset of the instruction in the Patchee section we are patching.

diff  --git a/lld/test/ELF/aarch64-cortex-a53-843419-thunk-range.s b/lld/test/ELF/aarch64-cortex-a53-843419-thunk-range.s
new file mode 100644
index 000000000000..64658d37efdf
--- /dev/null
+++ b/lld/test/ELF/aarch64-cortex-a53-843419-thunk-range.s
@@ -0,0 +1,87 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux --asm-macro-max-nesting-depth=40000 %s -o %t.o
+// RUN: echo "SECTIONS { \
+// RUN:          .text1 0x10000 : { *(.text.*) } \
+// RUN:          .text2 0xf010000 : { *(.target) } } " > %t.script
+// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 %t.o -o %t2 --print-map 2>&1 | FileCheck %s
+
+/// We use %(\parameter) to evaluate expression, which requires .altmacro.
+ .altmacro
+
+/// Test to reproduce the conditions that trigger R_AARCH64_JUMP26 out of range
+/// errors in pr44071. We create a large number of patches and thunks, with an
+/// LLD with the fault, the patches will be inserted after the thunks and due
+/// to the size of the thunk section some of the patches go out of range.
+/// With a fixed LLD the patches are inserted before the thunks.
+
+// CHECK: <internal>:(.text.patch)
+// CHECK: <internal>:(.text.thunk)
+
+/// Macro to generate the cortex-a53-843419 patch sequence
+ .macro ERRATA from, to
+   .balign 4096
+   .space 4096 - 8
+   adrp x0, dat1
+   ldr x1, [x1, #0]
+   ldr x0, [x0, :got_lo12:dat1]
+   ret
+   .if (\to-\from)
+     ERRATA %(\from+1),\to
+   .endif
+ .endm
+
+ .section .text.01, "ax", %progbits
+ .balign 4096
+ .globl _start
+ .type _start, %function
+ .space 4096 - 8
+_start:
+/// Generate lots of patches.
+ ERRATA 0, 4000
+
+ .macro CALLS from, to
+   bl far\from
+   .if (\to-\from)
+     CALLS %(\from+1),\to
+   .endif
+ .endm
+
+ /// Generate long range thunks. These are inserted before the patches. Generate
+ /// a sufficient number such that the patches must be placed before the
+ /// .text.thunk section, and if they aren't some of the patches go out of
+ /// range.
+ .section .text.02, "ax", %progbits
+ .global func
+ .type func, %function
+func:
+ CALLS 0, 20000
+
+ .section .text.03, "ax", %progbits
+ .global space1
+space1:
+ .space (1024 * 1024 * 96) + (120 * 4 * 1024)
+ .balign 4096
+
+ .section .text.04, "ax", %progbits
+ .global space2
+space2:
+ .space 1024 * 1024
+
+ .macro DEFS from, to
+   .global far\from
+   .type far\from, %function
+far\from:
+   ret
+   .if (\to-\from)
+     DEFS %(\from+1),\to
+   .endif
+ .endm
+
+ /// Define the thunk targets
+ .section .target, "ax", %progbits
+ DEFS 0, 20000
+
+ .data
+ .global dat1
+dat1:
+ .xword 0


        


More information about the llvm-commits mailing list