aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp109
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