diff options
author | Lang Hames <lhames@gmail.com> | 2016-08-19 01:15:39 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2016-08-19 01:15:39 +0000 |
commit | b65f16c8e56bd88872ba1fa5740b8628b361dccd (patch) | |
tree | 0cc4cdc11868aecf600dd0409dae4534dbcdcc60 /llvm/lib/ExecutionEngine | |
parent | 719238b7d3907182e5c1e325370a1b55dc438b2e (diff) | |
download | llvm-b65f16c8e56bd88872ba1fa5740b8628b361dccd.zip llvm-b65f16c8e56bd88872ba1fa5740b8628b361dccd.tar.gz llvm-b65f16c8e56bd88872ba1fa5740b8628b361dccd.tar.bz2 |
[RuntimeDyld] Add support for ELF R_ARM_REL32 and R_ARM_GOT_PREL.
Patch by William Dillon. Thanks William!
This patch adds support for the R_ARM_REL32 and R_ARM_GOT_PREL ELF ARM
relocations to RuntimeDyld, which should allow JITing of code that
produces these relocations.
No test case: Unfortunately RuntimeDyldELF's GOT building mechanism (which
uses a separate section for GOT entries) isn't compatible with
RuntimeDyldChecker. The correct fix for this is to fix RuntimeDyldELF's GOT
support (it's fundamentally broken at the moment: separate sections aren't
guaranteed to be in range of a GOT entry load), but that's a non-trivial job.
llvm-svn: 279182
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 6929732..5bc3264 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -480,6 +480,9 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, *TargetPtr |= Value & 0xFFF; *TargetPtr |= ((Value >> 12) & 0xF) << 16; break; + case ELF::R_ARM_REL32: + *TargetPtr += Value - FinalAddress; + break; // Write 24 bit relative value to the branch instruction. case ELF::R_ARM_PC24: // Fall through. case ELF::R_ARM_CALL: // Fall through. @@ -1365,6 +1368,19 @@ RuntimeDyldELF::processRelocationRef( RelType, 0); Section.advanceStubOffset(getMaxStubSize()); } + } else if (RelType == ELF::R_ARM_GOT_PREL) { + uint32_t GOTOffset = allocateGOTEntries(SectionID, 1); + + RelocationEntry GOTRE(SectionID, Offset, ELF::R_ARM_REL32, GOTOffset); + addRelocationForSection(GOTRE, GOTSectionID); + + // Fill in the value of the symbol we're targeting into the GOT + RelocationEntry RE = computeGOTOffsetRE(SectionID, GOTOffset, + Value.Offset, ELF::R_ARM_ABS32); + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); } else { uint32_t *Placeholder = reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset)); |