aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h63
1 files changed, 44 insertions, 19 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
index fbfbb3285233..44fda87e0f94 100644
--- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
+++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
@@ -34,40 +34,66 @@ public:
unsigned getStubAlignment() override { return 1; }
- relocation_iterator processRelocationRef(unsigned SectionID,
- relocation_iterator RelI,
- const ObjectFile &Obj,
- ObjSectionToIDMap &ObjSectionToID,
- StubMap &Stubs) override {
+ Expected<relocation_iterator>
+ processRelocationRef(unsigned SectionID,
+ relocation_iterator RelI,
+ const ObjectFile &Obj,
+ ObjSectionToIDMap &ObjSectionToID,
+ StubMap &Stubs) override {
+
auto Symbol = RelI->getSymbol();
if (Symbol == Obj.symbol_end())
report_fatal_error("Unknown symbol in relocation");
- ErrorOr<StringRef> TargetNameOrErr = Symbol->getName();
- if (auto EC = TargetNameOrErr.getError())
- report_fatal_error(EC.message());
+ Expected<StringRef> TargetNameOrErr = Symbol->getName();
+ if (!TargetNameOrErr)
+ return TargetNameOrErr.takeError();
StringRef TargetName = *TargetNameOrErr;
- auto Section = *Symbol->getSection();
+ auto SectionOrErr = Symbol->getSection();
+ if (!SectionOrErr)
+ return SectionOrErr.takeError();
+ auto Section = *SectionOrErr;
uint64_t RelType = RelI->getType();
uint64_t Offset = RelI->getOffset();
+ // Determine the Addend used to adjust the relocation value.
+ uint64_t Addend = 0;
+ SectionEntry &AddendSection = Sections[SectionID];
+ uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;
+ uint8_t *Displacement = (uint8_t *)ObjTarget;
+
+ switch (RelType) {
+ case COFF::IMAGE_REL_I386_DIR32:
+ case COFF::IMAGE_REL_I386_DIR32NB:
+ case COFF::IMAGE_REL_I386_SECREL:
+ case COFF::IMAGE_REL_I386_REL32: {
+ Addend = readBytesUnaligned(Displacement, 4);
+ break;
+ }
+ default:
+ break;
+ }
+
#if !defined(NDEBUG)
SmallString<32> RelTypeName;
RelI->getTypeName(RelTypeName);
#endif
DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
<< " RelType: " << RelTypeName << " TargetName: " << TargetName
- << "\n");
+ << " Addend " << Addend << "\n");
unsigned TargetSectionID = -1;
if (Section == Obj.section_end()) {
RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);
addRelocationForSymbol(RE, TargetName);
} else {
- TargetSectionID =
- findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID);
+ if (auto TargetSectionIDOrErr =
+ findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID))
+ TargetSectionID = *TargetSectionIDOrErr;
+ else
+ return TargetSectionIDOrErr.takeError();
switch (RelType) {
case COFF::IMAGE_REL_I386_ABSOLUTE:
@@ -77,7 +103,7 @@ public:
case COFF::IMAGE_REL_I386_DIR32NB:
case COFF::IMAGE_REL_I386_REL32: {
RelocationEntry RE =
- RelocationEntry(SectionID, Offset, RelType, 0, TargetSectionID,
+ RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,
getSymbolOffset(*Symbol), 0, 0, false, 0);
addRelocationForSection(RE, TargetSectionID);
break;
@@ -90,7 +116,7 @@ public:
}
case COFF::IMAGE_REL_I386_SECREL: {
RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
- getSymbolOffset(*Symbol));
+ getSymbolOffset(*Symbol) + Addend);
addRelocationForSection(RE, TargetSectionID);
break;
}
@@ -148,8 +174,10 @@ public:
}
case COFF::IMAGE_REL_I386_REL32: {
// 32-bit relative displacement to the target.
- uint64_t Result = Sections[RE.Sections.SectionA].getLoadAddress() -
- Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;
+ uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1)
+ ? Value
+ : Sections[RE.Sections.SectionA].getLoadAddress();
+ Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;
assert(static_cast<int32_t>(Result) <= INT32_MAX &&
"relocation overflow");
assert(static_cast<int32_t>(Result) >= INT32_MIN &&
@@ -190,9 +218,6 @@ public:
void registerEHFrames() override {}
void deregisterEHFrames() override {}
-
- void finalizeLoad(const ObjectFile &Obj,
- ObjSectionToIDMap &SectionMap) override {}
};
}