[llvm] r182800 - ARM: use pristine object file while processing relocations

Tim Northover tnorthover at apple.com
Tue May 28 12:48:19 PDT 2013


Author: tnorthover
Date: Tue May 28 14:48:19 2013
New Revision: 182800

URL: http://llvm.org/viewvc/llvm-project?rev=182800&view=rev
Log:
ARM: use pristine object file while processing relocations

Previously we would read-modify-write the target bits when processing
relocations for the MCJIT. This had the problem that when relocations
were processed multiple times for the same object file (as they can
be), the result is not idempotent and the values became corrupted.

The solution to this is to take any bits used in the destination from
the pristine object file as LLVM emitted it.

This should fix PR16013 and remote MCJIT on ARM ELF targets.

Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
    llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll
    llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll
    llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=182800&r1=182799&r2=182800&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Tue May 28 14:48:19 2013
@@ -377,13 +377,14 @@ void RuntimeDyldELF::resolveAArch64Reloc
   }
 }
 
-// FIXME: PR16013: this routine needs modification to handle repeated relocations.
 void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
                                           uint64_t Offset,
                                           uint32_t Value,
                                           uint32_t Type,
                                           int32_t Addend) {
   // TODO: Add Thumb relocations.
+  uint32_t *Placeholder = reinterpret_cast<uint32_t*>(Section.ObjAddress +
+                                                      Offset);
   uint32_t* TargetPtr = (uint32_t*)(Section.Address + Offset);
   uint32_t FinalAddress = ((Section.LoadAddress + Offset) & 0xFFFFFFFF);
   Value += Addend;
@@ -402,44 +403,51 @@ void RuntimeDyldELF::resolveARMRelocatio
 
   // Write a 32bit value to relocation address, taking into account the
   // implicit addend encoded in the target.
-  case ELF::R_ARM_TARGET1 :
-  case ELF::R_ARM_ABS32 :
-    *TargetPtr += Value;
+  case ELF::R_ARM_TARGET1:
+  case ELF::R_ARM_ABS32:
+    *TargetPtr = *Placeholder + Value;
     break;
-
   // Write first 16 bit of 32 bit value to the mov instruction.
   // Last 4 bit should be shifted.
-  case ELF::R_ARM_MOVW_ABS_NC :
+  case ELF::R_ARM_MOVW_ABS_NC:
     // We are not expecting any other addend in the relocation address.
     // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2
     // non-contiguous fields.
+    assert((*Placeholder & 0x000F0FFF) == 0);
     Value = Value & 0xFFFF;
-    *TargetPtr &= ~0x000F0FFF; // Not really right; see FIXME at top.
-    *TargetPtr |= Value & 0xFFF;
+    *TargetPtr = *Placeholder | (Value & 0xFFF);
     *TargetPtr |= ((Value >> 12) & 0xF) << 16;
     break;
-
   // Write last 16 bit of 32 bit value to the mov instruction.
   // Last 4 bit should be shifted.
-  case ELF::R_ARM_MOVT_ABS :
+  case ELF::R_ARM_MOVT_ABS:
     // We are not expecting any other addend in the relocation address.
     // Use 0x000F0FFF for the same reason as R_ARM_MOVW_ABS_NC.
+    assert((*Placeholder & 0x000F0FFF) == 0);
+
     Value = (Value >> 16) & 0xFFFF;
-    *TargetPtr &= ~0x000F0FFF; // Not really right; see FIXME at top.
-    *TargetPtr |= Value & 0xFFF;
+    *TargetPtr = *Placeholder | (Value & 0xFFF);
     *TargetPtr |= ((Value >> 12) & 0xF) << 16;
     break;
-
   // Write 24 bit relative value to the branch instruction.
   case ELF::R_ARM_PC24 :    // Fall through.
   case ELF::R_ARM_CALL :    // Fall through.
-  case ELF::R_ARM_JUMP24 :
+  case ELF::R_ARM_JUMP24: {
     int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
     RelValue = (RelValue & 0x03FFFFFC) >> 2;
+    assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE);
     *TargetPtr &= 0xFF000000;
     *TargetPtr |= RelValue;
     break;
   }
+  case ELF::R_ARM_PRIVATE_0:
+    // This relocation is reserved by the ARM ELF ABI for internal use. We
+    // appropriate it here to act as an R_ARM_ABS32 without any addend for use
+    // in the stubs created during JIT (which can't put an addend into the
+    // original object file).
+    *TargetPtr = Value;
+    break;
+  }
 }
 
 void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
@@ -898,7 +906,7 @@ void RuntimeDyldELF::processRelocationRe
       uint8_t *StubTargetAddr = createStubFunction(Section.Address +
                                                    Section.StubOffset);
       RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
-                         ELF::R_ARM_ABS32, Value.Addend);
+                         ELF::R_ARM_PRIVATE_0, Value.Addend);
       if (Value.SymbolName)
         addRelocationForSymbol(RE, Value.SymbolName);
       else

Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll?rev=182800&r1=182799&r2=182800&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll (original)
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll Tue May 28 14:48:19 2013
@@ -1,5 +1,5 @@
 ; RUN: %lli_mcjit -remote-mcjit %s > /dev/null
-; XFAIL: arm, mips
+; XFAIL:  mips
 
 define i32 @bar() {
 	ret i32 0

Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll?rev=182800&r1=182799&r2=182800&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll (original)
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll Tue May 28 14:48:19 2013
@@ -1,5 +1,5 @@
 ; RUN: %lli_mcjit -remote-mcjit -disable-lazy-compilation=false %s
-; XFAIL: arm, mips
+; XFAIL:  mips
 
 define i32 @main() nounwind {
 entry:

Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll?rev=182800&r1=182799&r2=182800&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll (original)
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll Tue May 28 14:48:19 2013
@@ -1,5 +1,5 @@
 ; RUN: %lli_mcjit -remote-mcjit %s > /dev/null
-; XFAIL: arm, mips
+; XFAIL:  mips
 
 define double @test(double* %DP, double %Arg) {
 	%D = load double* %DP		; <double> [#uses=1]





More information about the llvm-commits mailing list