diff options
author | Lang Hames <lhames@gmail.com> | 2016-04-27 20:24:48 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2016-04-27 20:24:48 +0000 |
commit | 8959531c51af99600296b3db6c94af567ec22aca (patch) | |
tree | 3bbdc6579a298c81b3c2f6bcf17dab485366b1e0 /llvm/lib/ExecutionEngine/RuntimeDyld/Targets | |
parent | 21a12fc69ac28a41efe417ad45ef6aebbb062195 (diff) | |
download | bcm5719-llvm-8959531c51af99600296b3db6c94af567ec22aca.tar.gz bcm5719-llvm-8959531c51af99600296b3db6c94af567ec22aca.zip |
[RuntimeDyld] Plumb Error/Expected through the internals of RuntimeDyld.
Also replaces a number of calls to report_fatal_error with Error returns.
The plumbing will make it easier to return errors originating in libObject.
Replacing report_fatal_errors with Error returns will give JIT clients the
opportunity to recover gracefully when the JIT is unable to produce/relocate
code, as well as providing meaningful error messages that can be used to file
bug reports.
llvm-svn: 267776
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld/Targets')
6 files changed, 153 insertions, 87 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h index 9573d3f2ed4..3456b337197 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -34,11 +34,13 @@ 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"); @@ -71,8 +73,11 @@ public: 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: @@ -195,9 +200,6 @@ public: void registerEHFrames() override {} void deregisterEHFrames() override {} - - void finalizeLoad(const ObjectFile &Obj, - ObjSectionToIDMap &SectionMap) override {} }; } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h index 1fd851545d6..7dd112e5f83 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -106,11 +106,12 @@ public: } } - 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 { // If possible, find the symbol referred to in the relocation, // and the section that contains it. symbol_iterator Symbol = RelI->getSymbol(); @@ -170,8 +171,12 @@ public: addRelocationForSymbol(RE, TargetName); } else { bool IsCode = SecI->isText(); - unsigned TargetSectionID = - findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID); + unsigned TargetSectionID; + if (auto TargetSectionIDOrErr = + findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID)) + TargetSectionID = *TargetSectionIDOrErr; + else + return TargetSectionIDOrErr.takeError(); uint64_t TargetOffset = getSymbolOffset(*Symbol); RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend); addRelocationForSection(RE, TargetSectionID); @@ -194,19 +199,21 @@ public: void deregisterEHFrames() override { // Stub } - void finalizeLoad(const ObjectFile &Obj, - ObjSectionToIDMap &SectionMap) override { + Error finalizeLoad(const ObjectFile &Obj, + ObjSectionToIDMap &SectionMap) override { // Look for and record the EH frame section IDs. for (const auto &SectionPair : SectionMap) { const SectionRef &Section = SectionPair.first; StringRef Name; - Check(Section.getName(Name)); + if (auto EC = Section.getName(Name)) + return errorCodeToError(EC); // Note unwind info is split across .pdata and .xdata, so this // may not be sufficiently general for all users. if (Name == ".xdata") { UnregisteredEHFrameSections.push_back(SectionPair.second); } } + return Error::success(); } }; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index fba157b9424..7d1a62f08e1 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -242,7 +242,7 @@ public: } } - relocation_iterator + Expected<relocation_iterator> processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, ObjSectionToIDMap &ObjSectionToID, @@ -252,7 +252,9 @@ public: MachO::any_relocation_info RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); - assert(!Obj.isRelocationScattered(RelInfo) && ""); + if (Obj.isRelocationScattered(RelInfo)) + return make_error<RuntimeDyldError>("Scattered relocations not supported " + "for MachO AArch64"); // ARM64 has an ARM64_RELOC_ADDEND relocation type that carries an explicit // addend for the following relocation. If found: (1) store the associated @@ -281,8 +283,11 @@ public: if (ExplicitAddend) RE.Addend = ExplicitAddend; - RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); + RelocationValueRef Value; + if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) + Value = *ValueOrErr; + else + return ValueOrErr.takeError(); bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) @@ -371,8 +376,10 @@ public: } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, - const SectionRef &Section) {} + Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, + const SectionRef &Section) { + return Error::success(); + } private: void processGOTRelocation(const RelocationEntry &RE, diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index 7731df09bd2..b3f4ce44e09 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -49,7 +49,7 @@ public: } } - relocation_iterator + Expected<relocation_iterator> processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, ObjSectionToIDMap &ObjSectionToID, @@ -70,10 +70,30 @@ public: return ++RelI; } + // Sanity check relocation type. + switch (RelType) { + UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_PAIR); + UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_SECTDIFF); + UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_LOCAL_SECTDIFF); + UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_PB_LA_PTR); + UNIMPLEMENTED_RELOC(MachO::ARM_THUMB_RELOC_BR22); + UNIMPLEMENTED_RELOC(MachO::ARM_THUMB_32BIT_BRANCH); + UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_HALF); + default: + if (RelType > MachO::ARM_RELOC_HALF_SECTDIFF) + return make_error<RuntimeDyldError>("MachO ARM relocation type " + + std::to_string(RelType) + + " is out of range"); + break; + } + RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); RE.Addend = decodeAddend(RE); - RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); + RelocationValueRef Value; + if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) + Value = *ValueOrErr; + else + return ValueOrErr.takeError(); if (RE.IsPCRel) makeValueAddendPCRel(Value, RelI, 8); @@ -108,8 +128,6 @@ public: } switch (RE.RelType) { - default: - llvm_unreachable("Invalid relocation type!"); case MachO::ARM_RELOC_VANILLA: writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size); break; @@ -147,26 +165,20 @@ public: break; } - case MachO::ARM_THUMB_RELOC_BR22: - case MachO::ARM_THUMB_32BIT_BRANCH: - case MachO::ARM_RELOC_HALF: - case MachO::ARM_RELOC_PAIR: - case MachO::ARM_RELOC_SECTDIFF: - case MachO::ARM_RELOC_LOCAL_SECTDIFF: - case MachO::ARM_RELOC_PB_LA_PTR: - Error("Relocation type not implemented yet!"); - return; + default: + llvm_unreachable("Invalid relocation type"); } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, + Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, const SectionRef &Section) { StringRef Name; Section.getName(Name); if (Name == "__nl_symbol_ptr") - populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), - Section, SectionID); + return populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), + Section, SectionID); + return Error::success(); } private: @@ -201,7 +213,7 @@ private: resolveRelocation(TargetRE, (uint64_t)Addr); } - relocation_iterator + Expected<relocation_iterator> processHALFSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseTObj, ObjSectionToIDMap &ObjSectionToID) { @@ -237,8 +249,12 @@ private: uint64_t SectionAOffset = AddrA - SectionABase; SectionRef SectionA = *SAI; bool IsCode = SectionA.isText(); - uint32_t SectionAID = - findOrEmitSection(MachO, SectionA, IsCode, ObjSectionToID); + uint32_t SectionAID = ~0U; + if (auto SectionAIDOrErr = + findOrEmitSection(MachO, SectionA, IsCode, ObjSectionToID)) + SectionAID = *SectionAIDOrErr; + else + return SectionAIDOrErr.takeError(); uint32_t AddrB = MachO.getScatteredRelocationValue(RE2); section_iterator SBI = getSectionByAddress(MachO, AddrB); @@ -246,8 +262,12 @@ private: uint64_t SectionBBase = SBI->getAddress(); uint64_t SectionBOffset = AddrB - SectionBBase; SectionRef SectionB = *SBI; - uint32_t SectionBID = - findOrEmitSection(MachO, SectionB, IsCode, ObjSectionToID); + uint32_t SectionBID = ~0U; + if (auto SectionBIDOrErr = + findOrEmitSection(MachO, SectionB, IsCode, ObjSectionToID)) + SectionBID = *SectionBIDOrErr; + else + return SectionBIDOrErr.takeError(); uint32_t OtherHalf = MachO.getAnyRelocationAddress(RE2) & 0xffff; unsigned Shift = (HalfDiffKindBits & 0x1) ? 16 : 0; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 843aa364c4f..129acf7c762 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -30,7 +30,7 @@ public: unsigned getStubAlignment() override { return 1; } - relocation_iterator + Expected<relocation_iterator> processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, ObjSectionToIDMap &ObjSectionToID, @@ -48,13 +48,29 @@ public: ObjSectionToID); else if (RelType == MachO::GENERIC_RELOC_VANILLA) return processScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID); - llvm_unreachable("Unhandled scattered relocation."); + return make_error<RuntimeDyldError>("Unhandled I386 scattered relocation " + "type: " + std::to_string(RelType)); + } + + switch (RelType) { + UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PAIR); + UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PB_LA_PTR); + UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_TLV); + default: + if (RelType > MachO::GENERIC_RELOC_TLV) + return make_error<RuntimeDyldError>("MachO I386 relocation type " + + std::to_string(RelType) + + " is out of range"); + break; } RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); RE.Addend = memcpyAddend(RE); - RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); + RelocationValueRef Value; + if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) + Value = *ValueOrErr; + else + return ValueOrErr.takeError(); // Addends for external, PC-rel relocations on i386 point back to the zero // offset. Calculate the final offset from the relocation target instead. @@ -91,8 +107,6 @@ public: } switch (RE.RelType) { - default: - llvm_unreachable("Invalid relocation type!"); case MachO::GENERIC_RELOC_VANILLA: writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size); break; @@ -106,25 +120,26 @@ public: writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size); break; } - case MachO::GENERIC_RELOC_PB_LA_PTR: - Error("Relocation type not implemented yet!"); + default: + llvm_unreachable("Invalid relocation type!"); } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, + Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, const SectionRef &Section) { StringRef Name; Section.getName(Name); if (Name == "__jump_table") - populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID); + return populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID); else if (Name == "__pointers") - populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), - Section, SectionID); + return populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), + Section, SectionID); + return Error::success(); } private: - relocation_iterator + Expected<relocation_iterator> processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, ObjSectionToIDMap &ObjSectionToID) { @@ -153,8 +168,12 @@ private: uint64_t SectionAOffset = AddrA - SectionABase; SectionRef SectionA = *SAI; bool IsCode = SectionA.isText(); - uint32_t SectionAID = - findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID); + uint32_t SectionAID = ~0U; + if (auto SectionAIDOrErr = + findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID)) + SectionAID = *SectionAIDOrErr; + else + return SectionAIDOrErr.takeError(); uint32_t AddrB = Obj.getScatteredRelocationValue(RE2); section_iterator SBI = getSectionByAddress(Obj, AddrB); @@ -162,8 +181,12 @@ private: uint64_t SectionBBase = SBI->getAddress(); uint64_t SectionBOffset = AddrB - SectionBBase; SectionRef SectionB = *SBI; - uint32_t SectionBID = - findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID); + uint32_t SectionBID = ~0U; + if (auto SectionBIDOrErr = + findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID)) + SectionBID = *SectionBIDOrErr; + else + return SectionBIDOrErr.takeError(); // Compute the addend 'C' from the original expression 'A - B + C'. Addend -= AddrA - AddrB; @@ -183,11 +206,9 @@ private: } // Populate stubs in __jump_table section. - void populateJumpTable(const MachOObjectFile &Obj, const SectionRef &JTSection, + Error populateJumpTable(const MachOObjectFile &Obj, + const SectionRef &JTSection, unsigned JTSectionID) { - assert(!Obj.is64Bit() && - "__jump_table section not supported in 64-bit MachO."); - MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand(); MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl()); uint32_t JTSectionSize = Sec32.size; @@ -197,21 +218,17 @@ private: uint8_t *JTSectionAddr = getSectionAddress(JTSectionID); unsigned JTEntryOffset = 0; - assert((JTSectionSize % JTEntrySize) == 0 && - "Jump-table section does not contain a whole number of stubs?"); + if (JTSectionSize % JTEntrySize != 0) + return make_error<RuntimeDyldError>("Jump-table section does not contain " + "a whole number of stubs?"); for (unsigned i = 0; i < NumJTEntries; ++i) { unsigned SymbolIndex = Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i); symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); Expected<StringRef> IndirectSymbolName = SI->getName(); - if (!IndirectSymbolName) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(IndirectSymbolName.takeError(), OS, ""); - OS.flush(); - report_fatal_error(Buf); - } + if (!IndirectSymbolName) + return IndirectSymbolName.takeError(); uint8_t *JTEntryAddr = JTSectionAddr + JTEntryOffset; createStubFunction(JTEntryAddr); RelocationEntry RE(JTSectionID, JTEntryOffset + 1, @@ -219,6 +236,8 @@ private: addRelocationForSymbol(RE, *IndirectSymbolName); JTEntryOffset += JTEntrySize; } + + return Error::success(); } }; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index 8f566b7eff5..a46658d94bd 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -30,7 +30,7 @@ public: unsigned getStubAlignment() override { return 1; } - relocation_iterator + Expected<relocation_iterator> processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, ObjSectionToIDMap &ObjSectionToID, @@ -49,13 +49,26 @@ public: RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); RE.Addend = memcpyAddend(RE); - RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); + RelocationValueRef Value; + if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) + Value = *ValueOrErr; + else + return ValueOrErr.takeError(); bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) makeValueAddendPCRel(Value, RelI, 1 << RE.Size); + switch (RelType) { + UNIMPLEMENTED_RELOC(MachO::X86_64_RELOC_TLV); + default: + if (RelType > MachO::X86_64_RELOC_TLV) + return make_error<RuntimeDyldError>("MachO X86_64 relocation type " + + std::to_string(RelType) + + " is out of range"); + break; + } + if (RE.RelType == MachO::X86_64_RELOC_GOT || RE.RelType == MachO::X86_64_RELOC_GOT_LOAD) processGOTRelocation(RE, Value, Stubs); @@ -104,15 +117,13 @@ public: writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size); break; } - case MachO::X86_64_RELOC_GOT_LOAD: - case MachO::X86_64_RELOC_GOT: - case MachO::X86_64_RELOC_TLV: - Error("Relocation type not implemented yet!"); } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, - const SectionRef &Section) {} + Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, + const SectionRef &Section) { + return Error::success(); + } private: void processGOTRelocation(const RelocationEntry &RE, |