Index: lld/trunk/ELF/Arch/AArch64.cpp =================================================================== --- lld/trunk/ELF/Arch/AArch64.cpp +++ lld/trunk/ELF/Arch/AArch64.cpp @@ -232,8 +232,17 @@ checkInt<21>(Loc, Val, Type); write32AArch64Addr(Loc, Val); break; - case R_AARCH64_CALL26: case R_AARCH64_JUMP26: + // Normally we would just write the bits of the immediate field, however + // when patching instructions for the cpu errata fix -fix-cortex-a53-843419 + // we want to replace a non-branch instruction with a branch immediate + // instruction. By writing all the bits of the instruction including the + // opcode and the immediate (0 001 | 01 imm26) we can do this + // transformation by placing a R_AARCH64_JUMP26 relocation at the offset of + // the instruction we want to patch. + write32le(Loc, 0x14000000); + LLVM_FALLTHROUGH; + case R_AARCH64_CALL26: checkInt<28>(Loc, Val, Type); or32le(Loc, (Val & 0x0FFFFFFC) >> 2); break; Index: lld/trunk/test/ELF/relocation-b-aarch64.test =================================================================== --- lld/trunk/test/ELF/relocation-b-aarch64.test +++ lld/trunk/test/ELF/relocation-b-aarch64.test @@ -0,0 +1,48 @@ +# REQUIRES: aarch64 + +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o -o %t.out +# RUN: llvm-objdump -d -triple=aarch64-none-linux %t.out | FileCheck %s + +# Check that the R_AARCH64_JUMP26 writes the branch opcode as well as the +# immediate. We use this property to overwrite instructions with a branch. + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: foo: +# CHECK-NEXT: 20000: 01 00 00 14 b #4 +# CHECK: bar: +# CHECK-NEXT: 20004: ff ff ff 17 b #-4 + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Type: SHT_PROGBITS + Name: .text + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Content: "0000000000000000" + - Type: SHT_RELA + Name: .rela.text + Link: .symtab + Info: .text + Relocations: + - Offset: 0 + Symbol: bar + Type: R_AARCH64_JUMP26 + - Offset: 4 + Symbol: foo + Type: R_AARCH64_JUMP26 + +Symbols: + Local: + - Type: STT_FUNC + Section: .text + Name: foo + Value: 0 + - Type: STT_FUNC + Section: .text + Name: bar + Value: 4