diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp')
| -rw-r--r-- | llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp | 109 |
1 files changed, 65 insertions, 44 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp index 1fd2a33d3f11..e898d336dbe4 100644 --- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp @@ -11,6 +11,8 @@ //===----------------------------------------------------------------------===// #include "COFFLinkGraphBuilder.h" +#include <memory> + #define DEBUG_TYPE "jitlink" static const char *CommonSectionName = "__common"; @@ -24,12 +26,15 @@ static Triple createTripleWithCOFFFormat(Triple T) { } COFFLinkGraphBuilder::COFFLinkGraphBuilder( - const object::COFFObjectFile &Obj, Triple TT, SubtargetFeatures Features, + const object::COFFObjectFile &Obj, + std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT, + SubtargetFeatures Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) - : Obj(Obj), G(std::make_unique<LinkGraph>( - Obj.getFileName().str(), createTripleWithCOFFFormat(TT), - std::move(Features), getPointerSize(Obj), - getEndianness(Obj), std::move(GetEdgeKindName))) { + : Obj(Obj), + G(std::make_unique<LinkGraph>(Obj.getFileName().str(), std::move(SSP), + createTripleWithCOFFFormat(std::move(TT)), + std::move(Features), + std::move(GetEdgeKindName))) { LLVM_DEBUG({ dbgs() << "Created COFFLinkGraphBuilder for \"" << Obj.getFileName() << "\"\n"; @@ -38,17 +43,6 @@ COFFLinkGraphBuilder::COFFLinkGraphBuilder( COFFLinkGraphBuilder::~COFFLinkGraphBuilder() = default; -unsigned -COFFLinkGraphBuilder::getPointerSize(const object::COFFObjectFile &Obj) { - return Obj.getBytesInAddress(); -} - -llvm::endianness -COFFLinkGraphBuilder::getEndianness(const object::COFFObjectFile &Obj) { - return Obj.isLittleEndian() ? llvm::endianness::little - : llvm::endianness::big; -} - uint64_t COFFLinkGraphBuilder::getSectionSize(const object::COFFObjectFile &Obj, const object::coff_section *Sec) { // Consider the difference between executable form and object form. @@ -226,18 +220,19 @@ Error COFFLinkGraphBuilder::graphifySymbols() { " (" + toString(SecOrErr.takeError()) + ")"); Sec = *SecOrErr; } + auto InternedSymbolName = G->intern(std::move(SymbolName)); // Create jitlink symbol jitlink::Symbol *GSym = nullptr; if (Sym->isFileRecord()) LLVM_DEBUG({ dbgs() << " " << SymIndex << ": Skipping FileRecord symbol \"" - << SymbolName << "\" in " + << InternedSymbolName << "\" in " << getCOFFSectionName(SectionIndex, Sec, *Sym) << " (index: " << SectionIndex << ") \n"; }); else if (Sym->isUndefined()) { - GSym = createExternalSymbol(SymIndex, SymbolName, *Sym, Sec); + GSym = createExternalSymbol(SymIndex, InternedSymbolName, *Sym, Sec); } else if (Sym->isWeakExternal()) { auto *WeakExternal = Sym->getAux<object::coff_aux_weak_external>(); COFFSymbolIndex TagIndex = WeakExternal->TagIndex; @@ -246,7 +241,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() { {SymIndex, TagIndex, Characteristics, SymbolName}); } else { Expected<jitlink::Symbol *> NewGSym = - createDefinedSymbol(SymIndex, SymbolName, *Sym, Sec); + createDefinedSymbol(SymIndex, InternedSymbolName, *Sym, Sec); if (!NewGSym) return NewGSym.takeError(); GSym = *NewGSym; @@ -254,7 +249,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() { LLVM_DEBUG({ dbgs() << " " << SymIndex << ": Creating defined graph symbol for COFF symbol \"" - << SymbolName << "\" in " + << InternedSymbolName << "\" in " << getCOFFSectionName(SectionIndex, Sec, *Sym) << " (index: " << SectionIndex << ") \n"; dbgs() << " " << *GSym << "\n"; @@ -293,14 +288,13 @@ Error COFFLinkGraphBuilder::handleDirectiveSection(StringRef Str) { if (From.empty() || To.empty()) return make_error<JITLinkError>( "Invalid COFF /alternatename directive"); - AlternateNames[From] = To; + AlternateNames[G->intern(From)] = G->intern(To); break; } case COFF_OPT_incl: { - auto DataCopy = G->allocateContent(S); - StringRef StrCopy(DataCopy.data(), DataCopy.size()); - ExternalSymbols[StrCopy] = &G->addExternalSymbol(StrCopy, 0, false); - ExternalSymbols[StrCopy]->setLive(true); + auto Symbol = &G->addExternalSymbol(S, 0, false); + Symbol->setLive(true); + ExternalSymbols[Symbol->getName()] = Symbol; break; } case COFF_OPT_export: @@ -332,8 +326,8 @@ Error COFFLinkGraphBuilder::flushWeakAliasRequests() { ? Scope::Default : Scope::Local; - auto NewSymbol = - createAliasSymbol(WeakExternal.SymbolName, Linkage::Weak, S, *Target); + auto NewSymbol = createAliasSymbol(G->intern(WeakExternal.SymbolName), + Linkage::Weak, S, *Target); if (!NewSymbol) return NewSymbol.takeError(); setGraphSymbol(AliasSymbol->getSectionNumber(), WeakExternal.Alias, @@ -354,37 +348,44 @@ Error COFFLinkGraphBuilder::flushWeakAliasRequests() { } Error COFFLinkGraphBuilder::handleAlternateNames() { - for (auto &KeyValue : AlternateNames) - if (DefinedSymbols.count(KeyValue.second) && - ExternalSymbols.count(KeyValue.first)) { - auto *Target = DefinedSymbols[KeyValue.second]; - auto *Alias = ExternalSymbols[KeyValue.first]; + for (auto &KeyValue : AlternateNames) { + auto DefinedSymbolName = KeyValue.second; + auto ExternalSymbolsName = KeyValue.first; + if (DefinedSymbols.count(DefinedSymbolName) && + ExternalSymbols.count(ExternalSymbolsName)) { + auto *Target = DefinedSymbols[DefinedSymbolName]; + auto *Alias = ExternalSymbols[ExternalSymbolsName]; G->makeDefined(*Alias, Target->getBlock(), Target->getOffset(), Target->getSize(), Linkage::Weak, Scope::Local, false); } + } return Error::success(); } Symbol *COFFLinkGraphBuilder::createExternalSymbol( - COFFSymbolIndex SymIndex, StringRef SymbolName, + COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName, object::COFFSymbolRef Symbol, const object::coff_section *Section) { - if (!ExternalSymbols.count(SymbolName)) - ExternalSymbols[SymbolName] = - &G->addExternalSymbol(SymbolName, Symbol.getValue(), false); + llvm::jitlink::Symbol *Sym = nullptr; + if (!ExternalSymbols.count(SymbolName)) { + Sym = &G->addExternalSymbol(*SymbolName, Symbol.getValue(), false); + ExternalSymbols[Sym->getName()] = Sym; + } else { + Sym = ExternalSymbols[SymbolName]; + } LLVM_DEBUG({ dbgs() << " " << SymIndex << ": Creating external graph symbol for COFF symbol \"" - << SymbolName << "\" in " + << Sym->getName() << "\" in " << getCOFFSectionName(Symbol.getSectionNumber(), Section, Symbol) << " (index: " << Symbol.getSectionNumber() << ") \n"; }); - return ExternalSymbols[SymbolName]; + return Sym; } -Expected<Symbol *> COFFLinkGraphBuilder::createAliasSymbol(StringRef SymbolName, - Linkage L, Scope S, - Symbol &Target) { +Expected<Symbol *> +COFFLinkGraphBuilder::createAliasSymbol(orc::SymbolStringPtr SymbolName, + Linkage L, Scope S, Symbol &Target) { if (!Target.isDefined()) { // FIXME: Support this when there's a way to handle this. return make_error<JITLinkError>("Weak external symbol with external " @@ -460,16 +461,18 @@ Error COFFLinkGraphBuilder::calculateImplicitSizeOfSymbols() { } Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol( - COFFSymbolIndex SymIndex, StringRef SymbolName, + COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName, object::COFFSymbolRef Symbol, const object::coff_section *Section) { + if (Symbol.isCommon()) { // FIXME: correct alignment return &G->addDefinedSymbol( G->createZeroFillBlock(getCommonSection(), Symbol.getValue(), orc::ExecutorAddr(), Symbol.getValue(), 0), - 0, SymbolName, Symbol.getValue(), Linkage::Strong, Scope::Default, + 0, SymbolName, Symbol.getValue(), Linkage::Weak, Scope::Default, false, false); } + if (Symbol.isAbsolute()) return &G->addAbsoluteSymbol(SymbolName, orc::ExecutorAddr(Symbol.getValue()), 0, @@ -603,7 +606,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest( // Process the second symbol of COMDAT sequence. Expected<Symbol *> COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex, - StringRef SymbolName, + orc::SymbolStringPtr SymbolName, object::COFFSymbolRef Symbol) { Block *B = getGraphBlock(Symbol.getSectionNumber()); auto &PendingComdatExport = PendingComdatExports[Symbol.getSectionNumber()]; @@ -627,5 +630,23 @@ COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex, return GSym; } +Symbol *GetImageBaseSymbol::operator()(LinkGraph &G) { + if (ImageBase) + return *ImageBase; + + auto IBN = G.intern(ImageBaseName); + ImageBase = G.findExternalSymbolByName(IBN); + if (*ImageBase) + return *ImageBase; + ImageBase = G.findAbsoluteSymbolByName(IBN); + if (*ImageBase) + return *ImageBase; + ImageBase = G.findDefinedSymbolByName(IBN); + if (*ImageBase) + return *ImageBase; + + return nullptr; +} + } // namespace jitlink } // namespace llvm |
