mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
[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> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214285 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user