summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2014-07-30 03:35:05 +0000
committerLang Hames <lhames@gmail.com>2014-07-30 03:35:05 +0000
commit1316365e2cee88687b503d3818987a5fed147463 (patch)
tree21fd3153e620b2a893bc138cc21133249f50ff80 /llvm/lib/ExecutionEngine
parent005214ce50dd62936cf5834d46a2dd257a7f0b3d (diff)
downloadbcm5719-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')
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp6
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h3
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h2
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h28
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h2
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h2
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)
OpenPOWER on IntegriCloud