[lld] r312727 - [ELF] Always write non-immediate bits for AArch64 branch instruction.

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 7 09:29:52 PDT 2017


Author: psmith
Date: Thu Sep  7 09:29:52 2017
New Revision: 312727

URL: http://llvm.org/viewvc/llvm-project?rev=312727&view=rev
Log:
[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


Added:
    lld/trunk/test/ELF/relocation-b-aarch64.test
Modified:
    lld/trunk/ELF/Arch/AArch64.cpp

Modified: lld/trunk/ELF/Arch/AArch64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AArch64.cpp?rev=312727&r1=312726&r2=312727&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AArch64.cpp (original)
+++ lld/trunk/ELF/Arch/AArch64.cpp Thu Sep  7 09:29:52 2017
@@ -232,8 +232,17 @@ void AArch64::relocateOne(uint8_t *Loc,
     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;

Added: lld/trunk/test/ELF/relocation-b-aarch64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-b-aarch64.test?rev=312727&view=auto
==============================================================================
--- lld/trunk/test/ELF/relocation-b-aarch64.test (added)
+++ lld/trunk/test/ELF/relocation-b-aarch64.test Thu Sep  7 09:29:52 2017
@@ -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




More information about the llvm-commits mailing list