[PATCH] D36745: [LLD][ELF] Always write non-immediate bits for AArch64 branch instruction.

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 4 07:08:42 PDT 2017


peter.smith updated this revision to Diff 113748.
peter.smith added a comment.

Thanks both for the comments. My apologies for forgetting the context, I've added a new diff with it in. Adding a comprehensive test at this stage is difficult because (sensibly) there is no way with llvm-mc to generate a R_AARCH64_ JUMP26 relocation on a non branch instruction. What I've done here is added a test case that uses the full range of the immediate field of the JUMP26, if the extra overwriting would break anything in the immediate the test will fail. The next review in the sequence that implements the patching will heavily test this.


https://reviews.llvm.org/D36745

Files:
  ELF/Arch/AArch64.cpp
  test/ELF/aarch64-branch-fullrange.s


Index: test/ELF/aarch64-branch-fullrange.s
===================================================================
--- /dev/null
+++ test/ELF/aarch64-branch-fullrange.s
@@ -0,0 +1,42 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
+// RUN: echo "SECTIONS { \
+// RUN:          .text.below 0x1000 : { *(.text.below) } \
+// RUN:          .text 0x8001000 : { *.(.text) } \
+// RUN:          .text.high 0x10001000 : { *(.text.high) } }" > %t.script
+// RUN: ld.lld --script %t.script %t.o -o %t2
+// RUN: llvm-objdump -d -triple=aarch64-none-linux %t2 | FileCheck %s
+// Test extremes of AArch64 branch range
+ .section .text.below, "ax", %progbits
+ .balign 4
+ .globl low
+ .type low, %function
+low:
+ ret
+
+ .text
+ .balign 4
+ .globl _start
+ .type _start, %function
+_start:
+ b low
+ b high
+ ret
+
+ .section .text.high, "ax", %progbits
+ .balign 4
+ .globl high
+ .type high, %function
+high:
+ ret
+// CHECK: Disassembly of section .text.below:
+// CHECK-NEXT: low:
+// CHECK-NEXT:     1000:        c0 03 5f d6     ret
+// CHECK-NEXT: Disassembly of section .text:
+// CHECK-NEXT: _start:
+// CHECK-NEXT:  8001000:        00 00 00 16     b       #-134217728
+// CHECK-NEXT:  8001004:        ff ff ff 15     b       #134217724
+// CHECK-NEXT:  8001008:        c0 03 5f d6     ret
+// CHECK-NEXT: Disassembly of section .text.high:
+// CHECK-NEXT: high:
+// CHECK-NEXT: 10001000:        c0 03 5f d6     ret
Index: ELF/Arch/AArch64.cpp
===================================================================
--- ELF/Arch/AArch64.cpp
+++ ELF/Arch/AArch64.cpp
@@ -232,8 +232,13 @@
     checkInt<21>(Loc, Val, Type);
     write32AArch64Addr(Loc, Val);
     break;
-  case R_AARCH64_CALL26:
   case R_AARCH64_JUMP26:
+    // When patching instructions we may use a branch immediate to overwrite a
+    // potentially non-branch instruction so write the full branch instruction
+    // opcode (0 001 | 01 imm26).
+    write32le(Loc, 0x14000000);
+    // Fallthrough
+  case R_AARCH64_CALL26:
     checkInt<28>(Loc, Val, Type);
     or32le(Loc, (Val & 0x0FFFFFFC) >> 2);
     break;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36745.113748.patch
Type: text/x-patch
Size: 2120 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170904/6e58a591/attachment.bin>


More information about the llvm-commits mailing list