[lld] r319780 - [ELF] Implement scanner for Cortex-A53 Erratum 843419
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 5 07:59:06 PST 2017
Author: psmith
Date: Tue Dec 5 07:59:05 2017
New Revision: 319780
URL: http://llvm.org/viewvc/llvm-project?rev=319780&view=rev
Log:
[ELF] Implement scanner for Cortex-A53 Erratum 843419
Add a new file AArch64ErrataFix.cpp that implements the logic to scan for
the Cortex-A53 Erratum 843419. This involves finding all the executable
code, disassembling the instructions that might trigger the erratum and
reporting a message if the sequence is detected.
At this stage we do not attempt to fix the erratum, this functionality
will be added in a later patch. See D36749 for proposal.
Differential Revision: https://reviews.llvm.org/D36742
Added:
lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s
lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s
lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s
lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s
lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s
Modified:
lld/trunk/ELF/CMakeLists.txt
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/Options.td
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/CMakeLists.txt?rev=319780&r1=319779&r2=319780&view=diff
==============================================================================
--- lld/trunk/ELF/CMakeLists.txt (original)
+++ lld/trunk/ELF/CMakeLists.txt Tue Dec 5 07:59:05 2017
@@ -7,6 +7,7 @@ if(NOT LLD_BUILT_STANDALONE)
endif()
add_lld_library(lldELF
+ AArch64ErrataFix.cpp
Arch/AArch64.cpp
Arch/AMDGPU.cpp
Arch/ARM.cpp
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=319780&r1=319779&r2=319780&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Dec 5 07:59:05 2017
@@ -119,6 +119,7 @@ struct Configuration {
bool EmitRelocs;
bool EnableNewDtags;
bool ExportDynamic;
+ bool FixCortexA53Errata843419;
bool GcSections;
bool GdbIndex;
bool GnuHash = false;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=319780&r1=319779&r2=319780&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Dec 5 07:59:05 2017
@@ -269,6 +269,9 @@ static void checkOptions(opt::InputArgLi
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 @@ void LinkerDriver::readConfigs(opt::Inpu
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);
Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=319780&r1=319779&r2=319780&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Tue Dec 5 07:59:05 2017
@@ -120,6 +120,9 @@ defm filter: Eq<"filter">,
defm fini: Eq<"fini">,
HelpText<"Specify a finalizer function">, MetaVarName<"<symbol>">;
+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">;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=319780&r1=319779&r2=319780&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Dec 5 07:59:05 2017
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "Writer.h"
+#include "AArch64ErrataFix.h"
#include "Config.h"
#include "Filesystem.h"
#include "LinkerScript.h"
@@ -1349,9 +1350,11 @@ template <class ELFT> void Writer<ELFT>:
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 @@ template <class ELFT> void Writer<ELFT>:
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<ELFT>::RelaDyn->updateAllocSize();
Added: lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s?rev=319780&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s (added)
+++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-address.s Tue Dec 5 07:59:05 2017
@@ -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
Added: lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s?rev=319780&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s (added)
+++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-cli.s Tue Dec 5 07:59:05 2017
@@ -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
Added: lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s?rev=319780&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s (added)
+++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-nopatch.s Tue Dec 5 07:59:05 2017
@@ -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
Added: lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s?rev=319780&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s (added)
+++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-recognize.s Tue Dec 5 07:59:05 2017
@@ -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
Added: lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s?rev=319780&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s (added)
+++ lld/trunk/test/ELF/aarch64-cortex-a53-843419-thunk.s Tue Dec 5 07:59:05 2017
@@ -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
More information about the llvm-commits
mailing list