]> granicus.if.org Git - llvm/commitdiff
Fix PREL31 relocation on ARM
authorKeno Fischer <kfischer@college.harvard.edu>
Thu, 20 Oct 2016 21:15:29 +0000 (21:15 +0000)
committerKeno Fischer <kfischer@college.harvard.edu>
Thu, 20 Oct 2016 21:15:29 +0000 (21:15 +0000)
Summary:
This is a 31bits relative relocation instead of a 32bits absolute relocation.

Reviewers: t.p.northover, peter.smith, rengolin

Subscribers: aemerson, llvm-commits, samparker

Differential Revision: https://reviews.llvm.org/D25069

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284780 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s [new file with mode: 0644]

index cffd6e08cb42f54c83d60629b6859993803bacbb..d51461931a6301fb7841ae3ca57ca4cb70b23ad6 100644 (file)
@@ -463,7 +463,11 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
 
   case ELF::R_ARM_NONE:
     break;
+    // Write a 31bit signed offset
   case ELF::R_ARM_PREL31:
+    *TargetPtr &= 0x80000000;
+    *TargetPtr |= (Value - FinalAddress) & ~0x80000000;
+    break;
   case ELF::R_ARM_TARGET1:
   case ELF::R_ARM_ABS32:
     *TargetPtr = Value;
diff --git a/test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s b/test/ExecutionEngine/RuntimeDyld/ARM/ELF_ARM_EXIDX_relocations.s
new file mode 100644 (file)
index 0000000..eb07b00
--- /dev/null
@@ -0,0 +1,23 @@
+# RUN: llvm-mc -triple=arm-linux-gnueabihf -filetype=obj -o %T/reloc.o %s
+# RUN: llvm-rtdyld -triple=arm-linux-gnueabihf -verify -map-section reloc.o,.ARM.exidx=0x6000 -map-section reloc.o,.text=0x4000  -dummy-extern __aeabi_unwind_cpp_pr0=0x1234 -check=%s %T/reloc.o
+
+        .text
+        .syntax unified
+        .eabi_attribute 67, "2.09"      @ Tag_conformance
+        .cpu    cortex-a8
+        .fpu    neon
+        .file   "reloc.c"
+        .globl  g
+        .align  2
+        .type   g,%function
+g:
+        .fnstart
+        movw    r0, #1
+        bx      lr
+        .Lfunc_end0:
+        .size   g, .Lfunc_end0-g
+        .fnend
+
+# rtdyld-check: *{4}(section_addr(reloc.o, .ARM.exidx)) = (g - (section_addr(reloc.o, .ARM.exidx))) & 0x7fffffff
+# Compat unwind info: finish(0xb0), finish(0xb0), finish(0xb0)
+# rtdyld-check: *{4}(section_addr(reloc.o, .ARM.exidx) + 0x4) = 0x80b0b0b0