Skip to content

Commit 20489ec

Browse files
committedSep 7, 2017
[ELF] Always write non-immediate bits for AArch64 branch instruction.
To support errata patching on AArch64 we need to be able to overwrite an arbitrary instruction with a branch. For AArch64 it is sufficient to always write all the bits of the branch instruction and not just the immediate field. This is safe as the non-immediate bits of the branch instruction are always the same. Differential Revision: https://reviews.llvm.org/D36745 llvm-svn: 312727
1 parent 9927431 commit 20489ec

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed
 

‎lld/ELF/Arch/AArch64.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,17 @@ void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
232232
checkInt<21>(Loc, Val, Type);
233233
write32AArch64Addr(Loc, Val);
234234
break;
235-
case R_AARCH64_CALL26:
236235
case R_AARCH64_JUMP26:
236+
// Normally we would just write the bits of the immediate field, however
237+
// when patching instructions for the cpu errata fix -fix-cortex-a53-843419
238+
// we want to replace a non-branch instruction with a branch immediate
239+
// instruction. By writing all the bits of the instruction including the
240+
// opcode and the immediate (0 001 | 01 imm26) we can do this
241+
// transformation by placing a R_AARCH64_JUMP26 relocation at the offset of
242+
// the instruction we want to patch.
243+
write32le(Loc, 0x14000000);
244+
LLVM_FALLTHROUGH;
245+
case R_AARCH64_CALL26:
237246
checkInt<28>(Loc, Val, Type);
238247
or32le(Loc, (Val & 0x0FFFFFFC) >> 2);
239248
break;
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# REQUIRES: aarch64
2+
3+
# RUN: yaml2obj %s -o %t.o
4+
# RUN: ld.lld %t.o -o %t.out
5+
# RUN: llvm-objdump -d -triple=aarch64-none-linux %t.out | FileCheck %s
6+
7+
# Check that the R_AARCH64_JUMP26 writes the branch opcode as well as the
8+
# immediate. We use this property to overwrite instructions with a branch.
9+
10+
# CHECK: Disassembly of section .text:
11+
# CHECK-NEXT: foo:
12+
# CHECK-NEXT: 20000: 01 00 00 14 b #4
13+
# CHECK: bar:
14+
# CHECK-NEXT: 20004: ff ff ff 17 b #-4
15+
16+
!ELF
17+
FileHeader:
18+
Class: ELFCLASS64
19+
Data: ELFDATA2LSB
20+
Type: ET_REL
21+
Machine: EM_AARCH64
22+
Sections:
23+
- Type: SHT_PROGBITS
24+
Name: .text
25+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
26+
Content: "0000000000000000"
27+
- Type: SHT_RELA
28+
Name: .rela.text
29+
Link: .symtab
30+
Info: .text
31+
Relocations:
32+
- Offset: 0
33+
Symbol: bar
34+
Type: R_AARCH64_JUMP26
35+
- Offset: 4
36+
Symbol: foo
37+
Type: R_AARCH64_JUMP26
38+
39+
Symbols:
40+
Local:
41+
- Type: STT_FUNC
42+
Section: .text
43+
Name: foo
44+
Value: 0
45+
- Type: STT_FUNC
46+
Section: .text
47+
Name: bar
48+
Value: 4

0 commit comments

Comments
 (0)
Please sign in to comment.