diff options
author | Lang Hames <lhames@gmail.com> | 2014-07-30 03:35:05 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2014-07-30 03:35:05 +0000 |
commit | 1316365e2cee88687b503d3818987a5fed147463 (patch) | |
tree | 21fd3153e620b2a893bc138cc21133249f50ff80 /llvm/lib/ExecutionEngine | |
parent | 005214ce50dd62936cf5834d46a2dd257a7f0b3d (diff) | |
download | bcm5719-llvm-1316365e2cee88687b503d3818987a5fed147463.tar.gz bcm5719-llvm-1316365e2cee88687b503d3818987a5fed147463.zip |
[MCJIT] Fix the ARM BR24 relocation in RuntimeDyldMachO.
We now (1) correctly decode the branch immediate, (2) modify the immediate to
corretly treat it as PC-rel, and (3) properly populate the stub entry.
Previously we had been doing each of these wrong.
<rdar://problem/17750739>
llvm-svn: 214285
Diffstat (limited to 'llvm/lib/ExecutionEngine')
6 files changed, 31 insertions, 12 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 920b999fa08..bae2471054d 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -79,7 +79,8 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value, ObjectImage &ObjImg, - const relocation_iterator &RI) { + const relocation_iterator &RI, + unsigned OffsetToNextPC) { const MachOObjectFile &Obj = static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = @@ -89,8 +90,7 @@ void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value, if (IsPCRel) { uint64_t RelocAddr = 0; RI->getAddress(RelocAddr); - unsigned RelocSize = Obj.getAnyRelocationLength(RelInfo); - Value.Addend += RelocAddr + (1ULL << RelocSize); + Value.Addend += RelocAddr + OffsetToNextPC; } } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 7450f1141e1..30f61e98e32 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -73,7 +73,8 @@ protected: /// Make the RelocationValueRef addend PC-relative. void makeValueAddendPCRel(RelocationValueRef &Value, ObjectImage &ObjImg, - const relocation_iterator &RI); + const relocation_iterator &RI, + unsigned OffsetToNextPC); /// Dump information about the relocation entry (RE) and resolved value. void dumpRelocationToResolve(const RelocationEntry &RE, uint64_t Value) const; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index 967b12ff440..ced85f3e55a 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -276,7 +276,7 @@ public: bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, ObjImg, RelI); + makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size); RE.Addend = Value.Addend; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index 1de99421982..dadde769656 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -18,6 +18,9 @@ namespace llvm { class RuntimeDyldMachOARM : public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOARM> { +private: + typedef RuntimeDyldMachOCRTPBase<RuntimeDyldMachOARM> ParentT; + public: RuntimeDyldMachOARM(RTDyldMemoryManager *MM) : RuntimeDyldMachOCRTPBase(MM) {} @@ -25,6 +28,21 @@ public: unsigned getStubAlignment() override { return 4; } + int64_t decodeAddend(uint8_t *LocalAddress, unsigned NumBytes, + MachO::RelocationInfoType RelType) const { + switch (RelType) { + default: + return ParentT::decodeAddend(LocalAddress, NumBytes, RelType); + case MachO::ARM_RELOC_BR24: { + uint32_t Temp; + memcpy(&Temp, LocalAddress, 4); + Temp &= 0x00ffffff; // Mask out the opcode. + // Now we've got the shifted immediate, shift by 2, sign extend and ret. + return SignExtend32<26>(Temp << 2); + } + } + } + relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID, @@ -41,9 +59,8 @@ public: RelocationValueRef Value( getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols)); - bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); - if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, ObjImg, RelI); + if (RE.IsPCRel) + makeValueAddendPCRel(Value, ObjImg, RelI, 8); if ((RE.RelType & 0xf) == MachO::ARM_RELOC_BR24) processBranchRelocation(RE, Value, Stubs); @@ -134,7 +151,8 @@ private: uint8_t *StubTargetAddr = createStubFunction(Section.Address + Section.StubOffset); RelocationEntry StubRE(RE.SectionID, StubTargetAddr - Section.Address, - MachO::GENERIC_RELOC_VANILLA, Value.Addend); + MachO::GENERIC_RELOC_VANILLA, Value.Addend, false, + 2); if (Value.SymbolName) addRelocationForSymbol(StubRE, Value.SymbolName); else @@ -142,7 +160,7 @@ private: Addr = Section.Address + Section.StubOffset; Section.StubOffset += getMaxStubSize(); } - RelocationEntry TargetRE(Value.SectionID, RE.Offset, RE.RelType, 0, + RelocationEntry TargetRE(RE.SectionID, RE.Offset, RE.RelType, 0, RE.IsPCRel, RE.Size); resolveRelocation(TargetRE, (uint64_t)Addr); } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 856c6ca3035..156287b3af1 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -62,7 +62,7 @@ public: // Value.Addend += RelocAddr + 4; // } if (RE.IsPCRel) - makeValueAddendPCRel(Value, ObjImg, RelI); + makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size); RE.Addend = Value.Addend; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index 99efe9da448..9106f415422 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -44,7 +44,7 @@ public: bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, ObjImg, RelI); + makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size); if (RE.RelType == MachO::X86_64_RELOC_GOT || RE.RelType == MachO::X86_64_RELOC_GOT_LOAD) |