[PATCH] D104905: [LLD][ELF][ARM] Fix case of patched unrelocated BLX

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 30 06:08:09 PDT 2021


This revision was automatically updated to reflect the committed changes.
Closed by commit rGdd4d3f74062c: [LLD][ELF][ARM] Fix case of patched unrelocated BLX (authored by psmith).
Herald added a project: LLVM.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D104905/new/

https://reviews.llvm.org/D104905

Files:
  lld/ELF/ARMErrataFix.cpp
  lld/test/ELF/arm-fix-cortex-a8-blx.s


Index: lld/test/ELF/arm-fix-cortex-a8-blx.s
===================================================================
--- lld/test/ELF/arm-fix-cortex-a8-blx.s
+++ lld/test/ELF/arm-fix-cortex-a8-blx.s
@@ -30,4 +30,4 @@
 // CHECK-PATCH:         21ffa:          nop.w
 // CHECK-PATCH-NEXT:    21ffe:          blx     0x22004 <__CortexA8657417_21FFE>
 // CHECK-PATCH:      00022004 <__CortexA8657417_21FFE>:
-// CHECK-PATCH-NEXT:    22004:          b       0x21004 <{{.+}}> @ imm = #-4104
+// CHECK-PATCH-NEXT:    22004:          b       0x21000 <_start>
Index: lld/ELF/ARMErrataFix.cpp
===================================================================
--- lld/ELF/ARMErrataFix.cpp
+++ lld/ELF/ARMErrataFix.cpp
@@ -164,6 +164,15 @@
     offset = target->getImplicitAddend(buf, R_ARM_THM_JUMP24);
   else
     offset = target->getImplicitAddend(buf, R_ARM_THM_CALL);
+  // A BLX instruction from Thumb to Arm may have an address that is
+  // not 4-byte aligned. As Arm instructions are always 4-byte aligned
+  // the instruction is calculated (from Arm ARM):
+  // targetAddress = Align(PC, 4) + imm32
+  // where
+  //   Align(x, y) = y * (x Div y)
+  // which corresponds to alignDown.
+  if (isBLX(instr))
+    sourceAddr = alignDown(sourceAddr, 4);
   return sourceAddr + offset + 4;
 }
 
@@ -185,7 +194,11 @@
   // We cannot use the instruction in the patchee section as this will have
   // been altered to point to us!
   uint64_t s = getThumbDestAddr(getBranchAddr(), instr);
-  uint64_t p = getVA(4);
+  // A BLX changes the state of the branch in the patch to Arm state, which
+  // has a PC Bias of 8, whereas in all other cases the branch is in Thumb
+  // state with a PC Bias of 4.
+  uint64_t pcBias = isBLX(instr) ? 8 : 4;
+  uint64_t p = getVA(pcBias);
   target->relocateNoSym(buf, isARM ? R_ARM_JUMP24 : R_ARM_THM_JUMP24, s - p);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104905.355521.patch
Type: text/x-patch
Size: 1847 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210630/0b3405ee/attachment.bin>


More information about the llvm-commits mailing list