From 8a3e7178f6cc29f57e1f608d50b17a8960300391 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Tue, 27 Nov 2018 10:17:35 +0000 Subject: [PATCH] [AArch64] Cortex-a53-843419 erratum should not apply to relaxed TLS. The changes to the instructions performed by TLS relaxation and the errata patching are performed with relocations. As these are applied so late the errata scanning won't see the changes in the section data made by the TLS relaxation. This can lead to a TLS relaxed sequence being patched when it doesn't need to be. The fix checks to see if there is a R_RELAX_TLS_IE_TO_LE instruction at the same address as the ADRP as this indicates the presence of a relaxation of a sequence that might get recognised as a patch. Differential Revision: https://reviews.llvm.org/D54854 llvm-svn: 347649 --- lld/ELF/AArch64ErrataFix.cpp | 12 ++++--- lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s | 38 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s diff --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp index db83129..239799d 100644 --- a/lld/ELF/AArch64ErrataFix.cpp +++ b/lld/ELF/AArch64ErrataFix.cpp @@ -538,20 +538,24 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset, InputSection *IS, std::vector &Patches) { // There may be a relocation at the same offset that we are patching. There - // are three cases that we need to consider. + // are four cases that we need to consider. // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this // instance of the erratum on a previous patch and altered the relocation. We // have nothing more to do. - // Case 2: A load/store register (unsigned immediate) class relocation. There + // Case 2: A TLS Relaxation R_RELAX_TLS_IE_TO_LE. In this case the ADRP that + // we read will be transformed into a MOVZ later so we actually don't match + // the sequence and have nothing more to do. + // Case 3: A load/store register (unsigned immediate) class relocation. There // are two of these R_AARCH_LD64_ABS_LO12_NC and R_AARCH_LD64_GOT_LO12_NC and // they are both absolute. We need to add the same relocation to the patch, // and replace the relocation with a R_AARCH_JUMP26 branch relocation. - // Case 3: No relocation. We must create a new R_AARCH64_JUMP26 branch + // Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch // relocation at the offset. auto RelIt = std::find_if( IS->Relocations.begin(), IS->Relocations.end(), [=](const Relocation &R) { return R.Offset == PatcheeOffset; }); - if (RelIt != IS->Relocations.end() && RelIt->Type == R_AARCH64_JUMP26) + if (RelIt != IS->Relocations.end() && + (RelIt->Type == R_AARCH64_JUMP26 || RelIt->Expr == R_RELAX_TLS_IE_TO_LE)) return; log("detected cortex-a53-843419 erratum sequence starting at " + diff --git a/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s b/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s new file mode 100644 index 0000000..bff72d3 --- /dev/null +++ b/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s @@ -0,0 +1,38 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: ld.lld -fix-cortex-a53-843419 %t.o -o %t2 +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s + +// The following code sequence is covered by the TLS IE to LE relaxation. It +// transforms the ADRP, LDR to MOVZ, MOVK. The former can trigger a +// cortex-a53-843419 patch, whereas the latter can not. As both +// relaxation and patching transform instructions very late in the +// link there is a possibility of them both being simultaneously +// applied. In this case the relaxed sequence is immune from the erratum so we +// prefer to keep it. + .text + .balign 4096 + .space 4096 - 8 + .globl _start + .type _start,@function +_start: + mrs x1, tpidr_el0 + adrp x0, :gottprel:v + ldr x1, [x0, #:gottprel_lo12:v] + adrp x0, :gottprel:v + ldr x1, [x0, #:gottprel_lo12:v] + ret + +// CHECK: _start: +// CHECK-NEXT: 210ff8: 41 d0 3b d5 mrs x1, TPIDR_EL0 +// CHECK-NEXT: 210ffc: 00 00 a0 d2 movz x0, #0, lsl #16 +// CHECK-NEXT: 211000: 01 02 80 f2 movk x1, #16 +// CHECK-NEXT: 211004: 00 00 a0 d2 movz x0, #0, lsl #16 +// CHECK-NEXT: 211008: 01 02 80 f2 movk x1, #16 +// CHECK-NEXT: 21100c: c0 03 5f d6 ret + + .type v,@object + .section .tbss,"awT",@nobits + .globl v +v: + .word 0 -- 2.7.4