Index: lld/trunk/ELF/CMakeLists.txt =================================================================== --- lld/trunk/ELF/CMakeLists.txt +++ lld/trunk/ELF/CMakeLists.txt @@ -7,6 +7,7 @@ endif() add_lld_library(lldELF + AArch64ErrataFix.cpp Arch/AArch64.cpp Arch/AMDGPU.cpp Arch/ARM.cpp Index: lld/trunk/ELF/Config.h =================================================================== --- lld/trunk/ELF/Config.h +++ lld/trunk/ELF/Config.h @@ -119,6 +119,7 @@ bool EmitRelocs; bool EnableNewDtags; bool ExportDynamic; + bool FixCortexA53Errata843419; bool GcSections; bool GdbIndex; bool GnuHash = false; Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -269,6 +269,9 @@ if (Config->EMachine == EM_MIPS && Config->GnuHash) error("the .gnu.hash section is not compatible with the MIPS target."); + if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64) + error("--fix-cortex-a53-843419 is only supported on AArch64 targets."); + if (Config->Pie && Config->Shared) error("-shared and -pie may not be used together"); @@ -610,6 +613,7 @@ Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); Config->FilterList = args::getStrings(Args, OPT_filter); Config->Fini = Args.getLastArgValue(OPT_fini, "_fini"); + Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419); Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false); Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false); Config->ICF = Args.hasFlag(OPT_icf_all, OPT_icf_none, false); Index: lld/trunk/ELF/Options.td =================================================================== --- lld/trunk/ELF/Options.td +++ lld/trunk/ELF/Options.td @@ -120,6 +120,9 @@ defm fini: Eq<"fini">, HelpText<"Specify a finalizer function">, MetaVarName<"">; +def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">, + HelpText<"Apply fixes for AArch64 Cortex-A53 erratum 843419">; + def full_shutdown : F<"full-shutdown">, HelpText<"Perform a full shutdown instead of calling _exit">; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "Writer.h" +#include "AArch64ErrataFix.h" #include "Config.h" #include "Filesystem.h" #include "LinkerScript.h" @@ -1349,9 +1350,11 @@ if (!Script->HasSectionsCommand && !Config->Relocatable) fixSectionAlignments(); - // Some architectures use small displacements for jump instructions. - // It is linker's responsibility to create thunks containing long - // jump instructions if jump targets are too far. Create thunks. + // Some architectures need to generate content that depends on the address + // of InputSections. For example some architectures use small displacements + // for jump instructions that is is the linker's responsibility for creating + // range extension thunks for. As the generation of the content may also + // alter InputSection addresses we must converge to a fixed point. if (Target->NeedsThunks || Config->AndroidPackDynRelocs) { ThunkCreator TC; bool Changed; @@ -1360,6 +1363,11 @@ Changed = false; if (Target->NeedsThunks) Changed |= TC.createThunks(OutputSections); + if (Config->FixCortexA53Errata843419) { + if (Changed) + Script->assignAddresses(); + reportA53Errata843419Fixes(); + } if (InX::MipsGot) InX::MipsGot->updateAllocSize(); Changed |= In::RelaDyn->updateAllocSize(); Index: lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s =================================================================== --- lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s +++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s @@ -0,0 +1,138 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: .text : { *(.text) *(.text.*) *(.newisd) } \ +// RUN: .text2 : { *.(newos) } \ +// RUN: .data : { *(.data) } }" > %t.script +// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck %s + +// Test cases for Cortex-A53 Erratum 843419 that involve interactions +// between the generated patches and the address of sections + +// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf +// for full erratum details. +// In Summary +// 1.) +// ADRP (0xff8 or 0xffc) +// 2.) +// - load or store single register or either integer or vector registers +// - STP or STNP of either vector or vector registers +// - Advanced SIMD ST1 store instruction +// Must not write Rn +// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn +// 4.) A load or store instruction from the Load/Store register unsigned +// immediate class using Rn as the base register + +// An aarch64 section can contain ranges of literal data embedded within the +// code, these ranges are encoded with mapping symbols. This tests that we +// can match the erratum sequence in code, but not data +// - We can handle more than one patch per code range (denoted by mapping +// symbols) +// - We can handle a patch in more than range of code, with literal data +// inbetween +// - We can handle redundant mapping symbols (two or more consecutive mapping +// symbols with the same type) +// - We can ignore erratum sequences in multiple literal data ranges. + +// CHECK: detected cortex-a53-843419 erratum sequence starting at FF8 in unpatched output. + + .section .text.01, "ax", %progbits + .balign 4096 + .space 4096 - 8 + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function +t3_ff8_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + + // create a redundant mapping symbol as we are already in a $x range + // some object producers unconditionally generate a mapping symbol on + // every symbol so we need to handle the case of $x $x + .local $x.999 +$x.999: +// CHECK-NEXT: detected cortex-a53-843419 erratum sequence starting at 1FFC in unpatched output. + .globl t3_ffc_ldrsimd + .type t3_ffc_ldrsimd, %function + .space 4096 - 12 +t3_ffc_ldrsimd: + adrp x0, dat + ldr s1, [x1, #0] + ldr x2, [x0, :got_lo12:dat] + ret + +// Inline data containing bit pattern of erratum sequence, expect no patch + .globl t3_ffc_ldralldata + .type t3_ff8_ldralldata, %function + .space 4096 - 20 +t3_ff8_ldralldata: + // 0x90000000 = adrp x0, #0 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x90 + // 0xf9400021 = ldr x1, [x1] + .byte 0x21 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + // 0xf9400000 = ldr x0, [x0] + .byte 0x00 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + // Check that we can recognise the erratum sequence post literal data + +// CHECK-NEXT: detected cortex-a53-843419 erratum sequence starting at 3FF8 in unpatched output. + + .space 4096 - 12 + .globl t3_ffc_ldr + .type t3_ffc_ldr, %function + t3_ffc_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.02, "ax", %progbits + .space 4096 - 12 + + // Start a new InputSectionDescription (see Linker Script) so the + // start address will be + // affected by any patches added to previous InputSectionDescription + +// CHECK: detected cortex-a53-843419 erratum sequence starting at 4FFC in unpatched output. + + .section .newisd, "ax", %progbits + .globl t3_ffc_str + .type t3_ffc_str, %function +t3_ffc_str: + adrp x0, dat + str x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + .space 4096 - 20 + +// CHECK: detected cortex-a53-843419 erratum sequence starting at 5FF8 in unpatched output. + + // Start a new OutputSection (see Linker Script) so the + // start address will be + // affected by any patches added to previous InputSectionDescription + .section .newos, "ax", %progbits + .globl t3_ff8_str + .type t3_ff8_str, %function +t3_ff8_str: + adrp x0, dat + str x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + .globl _start + .type _start, %function +_start: + ret + + .data + .globl dat +dat: .word 0 Index: lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s =================================================================== --- lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s +++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s @@ -0,0 +1,10 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: not ld.lld %t -fix-cortex-a53-843419 -o %t2 2>&1 | FileCheck %s + +// CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets. +.globl entry +.text + .quad 0 +entry: + ret Index: lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s =================================================================== --- lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s +++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s @@ -0,0 +1,338 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: ld.lld -fix-cortex-a53-843419 -verbose -t %t.o -o %t2 | FileCheck %s +// Test cases for Cortex-A53 Erratum 843419 that we don't expect to recognize +// as needing a patch as one or more of the conditions isn't satisfied. +// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf +// for full erratum details. +// In Summary +// 1.) +// ADRP (0xff8 or 0xffc) +// 2.) +// - load or store single register or either integer or vector registers +// - STP or STNP of either vector or vector registers +// - Advanced SIMD ST1 store instruction +// Must not write Rn +// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn +// 4.) A load or store instruction from the Load/Store register unsigned +// immediate class using Rn as the base register + +// Expect no patches detected. +// CHECK-NOT: detected cortex-a53-843419 erratum sequence + +// erratum sequence but adrp (address & 0xfff) is not 0xff8 or 0xffc + .section .text.01, "ax", %progbits + .balign 4096 + .globl t3_0_ldr + .type t3_ff8_ldr, %function +t3_0_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.02, "ax", %progbits + .balign 4096 + .globl t3_ff4_ldr + .space 4096 - 12 + .type t3_ff4_ldr, %function +t3_ff4_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// Close matches for erratum sequence, with adrp at correct address but +// instruction 2 is a load or store but not one that matches the erratum +// conditions, but with a similar encoding to an instruction that does. + + // ldp is not part of sequence, although stp is. + .section .text.03, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldp + .type t3_ff8_ldp, %function + .space 4096 - 8 +t3_ff8_ldp: + adrp x16, dat + ldp x1,x2, [x3, #0] + ldr x13, [x16, :got_lo12:dat] + ret + + // st2 is not part of sequence although st1 is. + .section .text.04, "ax", %progbits + .balign 4096 + .globl t3_ffc_st2 + .type t3_ffc_st2, %function + .space 4096 - 4 +t3_ffc_st2: + adrp x16, dat + st2 { v0.16b, v1.16b }, [x1] + ldr x13, [x16, :got_lo12:dat] + ret + + // st3 is not part of sequence although st1 is. + .section .text.05, "ax", %progbits + .balign 4096 + .globl t3_ffc_st3 + .type t3_ffc_st3, %function + .space 4096 - 4 +t3_ffc_st3: + adrp x16, dat + st3 { v0.16b, v1.16b, v2.16b }, [x1], x2 + ldr x13, [x16, :got_lo12:dat] + ret + + // ld1 is not part of sequence although st1 is. + .section .text.06, "ax", %progbits + .balign 4096 + .globl t3_ffc_ld2 + .type t3_ffc_st3, %function + .space 4096 - 4 +t3_ffc_ld1: + adrp x16, dat + ld1 { v0.16b }, [x2], x3 + ldr x13, [x16, :got_lo12:dat] + ret + + // ldnp is not part of sequence although stnp is. + .section .text.07, "ax", %progbits + .balign 4096 + .globl t4_ff8_ldnp + .type t4_ff8_ldnp, %function + .space 4096 - 8 +t4_ff8_ldnp: + adrp x7, dat + ldnp x1,x2, [x3, #0] + nop + ldr x10, [x7, :got_lo12:dat] + ret + +// Close match for erratum sequence, with adrp at correct address but +// instruction 2 writes to Rn, with Rn as either destination or as the +// transfer register but with writeback. + + // ldr instruction writes to Rn + .section .text.08, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function + .space 4096 - 8 +t3_ff8_ldr: + adrp x0, dat + ldr x0, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + // str instruction writes to Rn via writeback (pre index) + .section .text.09, "ax", %progbits + .balign 4096 + .globl t3_ff8_str + .type t3_ff8_str, %function + .space 4096 - 8 +t3_ff8_str: + adrp x0, dat + str x1, [x0, #4]! + ldr x0, [x0, :got_lo12:dat] + ret + + // ldr instruction writes to Rn via writeback (post index) + .section .text.09, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldr + .type t3_ffc_ldr, %function + .space 4096 - 8 +t3_ffc_ldr: + adrp x0, dat + ldr x1, [x0], 0x8 + ldr x0, [x0, :got_lo12:dat] + ret + + // stp writes to Rn via writeback (pre index) + .section .text.10, "ax", %progbits + .balign 4096 + .globl t4_ffc_stppre + .type t4_ffc_stppre, %function + .space 4096 - 4 +t4_ffc_stppre: + adrp x16, dat + stp x1,x2, [x16, #16]! + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + + // stp writes to Rn via writeback (post index) + .section .text.11, "ax", %progbits + .balign 4096 + .globl t4_ff8_stppost + .type t4_ff8_stppost, %function + .space 4096 - 8 +t4_ff8_stppost: + adrp x16, dat + stp x1,x2, [x16], #16 + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + + // st1 writes to Rn via writeback + .section .text.12, "ax", %progbits + .balign 4096 + .globl t3_ff8_st1 + .type t3_ff8_st1, %function + .space 4096 - 8 +t3_ff8_st1: + adrp x16, dat + st1 { v0.16b}, [x16], x2 + ldr x13, [x16, :got_lo12:dat] + ret + +// Close match for erratum sequence, but with optional instruction 3 a branch + + // function call via immediate + .section .text.13, "ax", %progbits + .balign 4096 + .globl t4_ffc_blimm + .type t4_ffc_blimm, %function + .space 4096 - 4 +t4_ffc_blimm: + adrp x7, dat + stnp x1,x2, [x3, #0] + bl t4_ffc_blimm + ldr x10, [x7, :got_lo12:dat] + ret + + // function call via register + .section .text.14, "ax", %progbits + .balign 4096 + .globl t4_ffc_blreg + .type t4_ffc_blreg, %function + .space 4096 - 4 +t4_ffc_blreg: + adrp x7, dat + stnp x1,x2, [x3, #0] + blr x4 + ldr x10, [x7, :got_lo12:dat] + ret + + // Unconditional branch immediate + .section .text.15, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchimm + .type t4_ffc_branchimm, %function + .space 4096 - 4 +t4_ffc_branchimm: + adrp x7, dat + stnp x1,x2, [x3, #0] + b t4_ffc_branchimm + ldr x10, [x7, :got_lo12:dat] + ret + + // Unconditional branch register + .section .text.16, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchreg + .type t4_ffc_branchreg, %function + .space 4096 - 4 +t4_ffc_branchreg: + adrp x7, dat + stnp x1,x2, [x3, #0] + br x4 + ldr x10, [x7, :got_lo12:dat] + ret + + // Conditional branch + .section .text.17, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchcond + .type t4_ffc_branchcond, %function + .space 4096 - 4 +t4_ffc_branchcond: + adrp x7, dat + stnp x1,x2, [x3, #0] + cbz x5, t4_ffc_branchcond + ldr x10, [x7, :got_lo12:dat] + ret + + // Conditional branch immediate + .section .text.18, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchcondimm + .type t4_ffc_branchcondimm, %function + .space 4096 - 4 +t4_ffc_branchcondimm: + adrp x7, dat + stnp x1,x2, [x3, #0] + beq t4_ffc_branchcondimm + ldr x10, [x7, :got_lo12:dat] + ret + +// Bitpattern matches erratum sequence but either all or part of the sequence +// is in inline literal data + .section .text.19, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldrtraildata + .type t3_ff8_ldrtraildata, %function + .space 4096 - 8 +t3_ff8_ldrtraildata: + adrp x0, dat + ldr x1, [x1, #0] + // 0xf9400000 = ldr x0, [x0] + .byte 0x00 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.20, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldrpredata + .type t3_ff8_ldrpredata, %function + .space 4096 - 8 +t3_ff8_ldrpredata: + // 0x90000000 = adrp x0, #0 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x90 + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.21, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldralldata + .type t3_ff8_ldralldata, %function + .space 4096 - 8 +t3_ff8_ldralldata: + // 0x90000000 = adrp x0, #0 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x90 + // 0xf9400021 = ldr x1, [x1] + .byte 0x21 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + // 0xf9400000 = ldr x0, [x0] + .byte 0x00 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + + ret + + .text + .globl _start + .type _start, %function +_start: + ret + + + + + +// Bitpattern matches erratum sequence but section is not executable + .data + .globl dat +dat: .word 0 Index: lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s =================================================================== --- lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s +++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s @@ -0,0 +1,336 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: ld.lld -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix CHECK-PRINT %s + +// Test cases for Cortex-A53 Erratum 843419 +// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf +// for full erratum details. +// In Summary +// 1.) +// ADRP (0xff8 or 0xffc) +// 2.) +// - load or store single register or either integer or vector registers +// - STP or STNP of either vector or vector registers +// - Advanced SIMD ST1 store instruction +// Must not write Rn +// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn +// 4.) A load or store instruction from the Load/Store register unsigned +// immediate class using Rn as the base register + +// Each section contains a sequence of instructions that should be recognized +// as erratum 843419. The test cases cover the major variations such as: +// adrp starts at 0xfff8 or 0xfffc +// Variations in instruction class for instruction 2 +// Optional instruction 3 present or not +// Load or store for instruction 4. + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FF8 in unpatched output. + .section .text.01, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function + .space 4096 - 8 +t3_ff8_ldr: + adrp x0, dat1 + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FF8 in unpatched output. + .section .text.02, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldrsimd + .type t3_ff8_ldrsimd, %function + .space 4096 - 8 +t3_ff8_ldrsimd: + adrp x0, dat2 + ldr s1, [x1, #0] + ldr x2, [x0, :got_lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 25FFC in unpatched output. + .section .text.03, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldrpost + .type t3_ffc_ldrpost, %function + .space 4096 - 4 +t3_ffc_ldrpost: + adrp x0, dat3 + ldr s1, [x1], #8 + ldr x3, [x0, :got_lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 27FF8 in unpatched output. + .section .text.04, "ax", %progbits + .balign 4096 + .globl t3_ff8_strpre + .type t3_ff8_strpre, %function + .space 4096 - 8 +t3_ff8_strpre: + adrp x0, dat1 + str s1, [x1, #8]! + ldr x2, [x0, :lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 29FFC in unpatched output. + .section .text.05, "ax", %progbits + .balign 4096 + .globl t3_ffc_str + .type t3_ffc_str, %function + .space 4096 - 4 +t3_ffc_str: + adrp x28, dat2 + str x2, [x2, #0] + str x28, [x28, :lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2BFFC in unpatched output. + .section .text.06, "ax", %progbits + .balign 4096 + .globl t3_ffc_strsimd + .type t3_ffc_strsimd, %function + .space 4096 - 4 +t3_ffc_strsimd: + adrp x28, dat3 + str w4, [x2, #0] + str x4, [x28, :lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2DFF8 in unpatched output. + .section .text.07, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldrunpriv + .type t3_ff8_ldrunpriv, %function + .space 4096 - 8 +t3_ff8_ldrunpriv: + adrp x29, dat1 + ldtrb w1, [x2, #0] + ldr x29, [x29, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2FFFC in unpatched output. + .section .text.08, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldur + .type t3_ffc_ldur, %function + .space 4096 - 4 +t3_ffc_ldur: + adrp x29, dat2 + ldur w2, [x2, #4] + ldr x29, [x29, :got_lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 31FFC in unpatched output. + .section .text.09, "ax", %progbits + .balign 4096 + .globl t3_ffc_sturh + .type t3_ffc_sturh, %function + .space 4096 - 4 +t3_ffc_sturh: + adrp x18, dat3 + sturh w3, [x2, #4] + ldr x1, [x18, :got_lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 33FF8 in unpatched output. + .section .text.10, "ax", %progbits + .balign 4096 + .globl t3_ff8_literal + .type t3_ff8_literal, %function + .space 4096 - 8 +t3_ff8_literal: + adrp x18, dat1 + ldr x3, t3_ff8_literal + ldr x18, [x18, :lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 35FFC in unpatched output. + .section .text.11, "ax", %progbits + .balign 4096 + .globl t3_ffc_register + .type t3_ffc_register, %function + .space 4096 - 4 +t3_ffc_register: + adrp x15, dat2 + ldr x3, [x2, x1] + ldr x10, [x15, :lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 37FF8 in unpatched output. + .section .text.12, "ax", %progbits + .balign 4096 + .globl t3_ff8_stp + .type t3_ff8_stp, %function + .space 4096 - 8 +t3_ff8_stp: + adrp x16, dat3 + stp x1,x2, [x3, #0] + ldr x13, [x16, :lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 39FFC in unpatched output. + .section .text.13, "ax", %progbits + .balign 4096 + .globl t3_ffc_stnp + .type t3_ffc_stnp, %function + .space 4096 - 4 +t3_ffc_stnp: + adrp x7, dat1 + stnp x1,x2, [x3, #0] + ldr x9, [x7, :lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output. + .section .text.14, "ax", %progbits + .balign 4096 + .globl t3_ffc_st1singlepost + .type t3_ffc_st1singlepost, %function + .space 4096 - 4 +t3_ffc_st1singlepost: + adrp x23, dat2 + st1 { v0.16b }, [x1], x2 + ldr x22, [x23, :lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3DFF8 in unpatched output. + .section .text.15, "ax", %progbits + .balign 4096 + .globl t3_ff8_st1multiple + .type t3_ff8_st1muliple, %function + .space 4096 - 8 +t3_ff8_st1multiple: + adrp x23, dat3 + st1 { v0.16b, v1.16b }, [x1] + ldr x24, [x23, :lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3FFF8 in unpatched output. + .section .text.16, "ax", %progbits + .balign 4096 + .globl t4_ff8_ldr + .type t4_ff8_ldr, %function + .space 4096 - 8 +t4_ff8_ldr: + adrp x0, dat1 + ldr x1, [x1, #0] + add x2, x2, x0 + ldr x2, [x0, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 41FFC in unpatched output. + .section .text.17, "ax", %progbits + .balign 4096 + .globl t4_ffc_str + .type t4_ffc_str, %function + .space 4096 - 4 +t4_ffc_str: + adrp x28, dat2 + str x2, [x2, #0] + sub x0, x1, x2 + str x27, [x28, :got_lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 43FF8 in unpatched output. + .section .text.18, "ax", %progbits + .balign 4096 + .globl t4_ff8_stp + .type t4_ff8_stp, %function + .space 4096 - 8 +t4_ff8_stp: + adrp x16, dat3 + stp x1,x2, [x3, #0] + mul x3, x16, x16 + ldr x14, [x16, :got_lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 45FF8 in unpatched output. + .section .text.19, "ax", %progbits + .balign 4096 + .globl t4_ff8_stppre + .type t4_ff8_stppre, %function + .space 4096 - 8 +t4_ff8_stppre: + adrp x16, dat1 + stp x1,x2, [x3, #16]! + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 47FF8 in unpatched output. + .section .text.20, "ax", %progbits + .balign 4096 + .globl t4_ff8_stppost + .type t4_ff8_stppost, %function + .space 4096 - 8 +t4_ff8_stppost: + adrp x16, dat2 + stp x1,x2, [x3], #16 + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 49FFC in unpatched output. + .section .text.21, "ax", %progbits + .balign 4096 + .globl t4_ffc_stpsimd + .type t4_ffc_stpsimd, %function + .space 4096 - 4 +t4_ffc_stpsimd: + adrp x16, dat3 + stp q1,q2, [x3, #0] + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4BFFC in unpatched output. + .section .text.22, "ax", %progbits + .balign 4096 + .globl t4_ffc_stnp + .type t4_ffc_stnp, %function + .space 4096 - 4 +t4_ffc_stnp: + adrp x7, dat1 + stnp x1,x2, [x3, #0] + nop + ldr x10, [x7, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output. + .section .text.23, "ax", %progbits + .balign 4096 + .globl t4_ffc_st1 + .type t4_ffc_st1, %function + .space 4096 - 4 +t4_ffc_st1: + adrp x24, dat2 + st1 { v0.16b }, [x1] + ldr x22, [x23, :got_lo12:dat2] + str x24, [x24, #32760] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4FFF8 in unpatched output. + .section .text.24, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldr_once + .type t3_ff8_ldr_once, %function + .space 4096 - 8 +t3_ff8_ldr_once: + adrp x0, dat3 + st1 { v0.16b }, [x1], x2 + ldr x1, [x0, #16] + ldr x2, [x0, #16] + ret + + .text + .globl _start + .type _start, %function +_start: + ret + + .data + .globl dat + .globl dat2 + .globl dat3 +dat1: .quad 1 +dat2: .quad 2 +dat3: .quad 3 Index: lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s =================================================================== --- lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s +++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s @@ -0,0 +1,44 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \ +// RUN: .text2 0x100000000 : { *(.text.04) } } " > %t.script +// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix=CHECK-PRINT %s + +// 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 + .balign 4096 + .globl _start + .type _start, %function +_start: + bl far_away + // Thunk to far_away, size 16-bytes goes here. + + .section .text.02, "ax", %progbits + .space 4096 - 28 + + // 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 +t3_ff8_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 10FFC in unpatched output. + .section .text.04, "ax", %progbits + .globl far_away + .type far_away, function +far_away: + ret + + .section .data + .globl dat +dat: .quad 0