Skip to content

Commit

Permalink
[AArch64] Cortex-a53-843419 erratum should not apply to relaxed TLS.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
smithp35 committed Nov 27, 2018
1 parent b93baf6 commit 8a3e717
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
12 changes: 8 additions & 4 deletions lld/ELF/AArch64ErrataFix.cpp
Expand Up @@ -538,20 +538,24 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
InputSection *IS,
std::vector<Patch843419Section *> &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 " +
Expand Down
38 changes: 38 additions & 0 deletions 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

0 comments on commit 8a3e717

Please sign in to comment.