diff options
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h')
-rw-r--r-- | lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h | 63 |
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 {} }; } |