aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp124
1 files changed, 74 insertions, 50 deletions
diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
index dc07eaeaf615..3a6162db75c4 100644
--- a/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
+++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
@@ -18,13 +18,19 @@ static const char *CommonSectionName = "__common";
namespace llvm {
namespace jitlink {
+static Triple createTripleWithCOFFFormat(Triple T) {
+ T.setObjectFormat(Triple::COFF);
+ return T;
+}
+
COFFLinkGraphBuilder::COFFLinkGraphBuilder(
const object::COFFObjectFile &Obj, Triple TT,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
: Obj(Obj),
- G(std::make_unique<LinkGraph>(
- Obj.getFileName().str(), Triple(std::move(TT)), getPointerSize(Obj),
- getEndianness(Obj), std::move(GetEdgeKindName))) {
+ G(std::make_unique<LinkGraph>(Obj.getFileName().str(),
+ createTripleWithCOFFFormat(TT),
+ getPointerSize(Obj), getEndianness(Obj),
+ std::move(GetEdgeKindName))) {
LLVM_DEBUG({
dbgs() << "Created COFFLinkGraphBuilder for \"" << Obj.getFileName()
<< "\"\n";
@@ -128,16 +134,6 @@ Error COFFLinkGraphBuilder::graphifySections() {
if (Expected<StringRef> SecNameOrErr = Obj.getSectionName(*Sec))
SectionName = *SecNameOrErr;
- bool IsDiscardable =
- (*Sec)->Characteristics &
- (COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_LNK_INFO);
- if (IsDiscardable) {
- LLVM_DEBUG(dbgs() << " " << SecIndex << ": \"" << SectionName
- << "\" is discardable: "
- "No graph section will be created.\n");
- continue;
- }
-
// FIXME: Skip debug info sections
LLVM_DEBUG({
@@ -145,6 +141,8 @@ Error COFFLinkGraphBuilder::graphifySections() {
<< "Creating section for \"" << SectionName << "\"\n";
});
+ // FIXME: Revisit crash when dropping IMAGE_SCN_MEM_DISCARDABLE sections
+
// Get the section's memory protection flags.
MemProt Prot = MemProt::None;
if ((*Sec)->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE)
@@ -190,6 +188,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
SymbolSets.resize(Obj.getNumberOfSections() + 1);
+ PendingComdatExports.resize(Obj.getNumberOfSections() + 1);
GraphSymbols.resize(Obj.getNumberOfSymbols());
for (COFFSymbolIndex SymIndex = 0;
@@ -232,18 +231,16 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
<< getCOFFSectionName(SectionIndex, Sec, *Sym)
<< " (index: " << SectionIndex << ") \n";
});
- GSym =
- &G->addExternalSymbol(SymbolName, Sym->getValue(), Linkage::Strong);
+ if (!ExternalSymbols.count(SymbolName))
+ ExternalSymbols[SymbolName] =
+ &G->addExternalSymbol(SymbolName, Sym->getValue(), Linkage::Strong);
+ GSym = ExternalSymbols[SymbolName];
} else if (Sym->isWeakExternal()) {
- COFFSymbolIndex TagIndex =
- Sym->getAux<object::coff_aux_weak_external>()->TagIndex;
- assert(Sym->getAux<object::coff_aux_weak_external>()->Characteristics !=
- COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY &&
- "IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY is not supported.");
- assert(Sym->getAux<object::coff_aux_weak_external>()->Characteristics !=
- COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY &&
- "IMAGE_WEAK_EXTERN_SEARCH_LIBRARY is not supported.");
- WeakAliasRequests.push_back({SymIndex, TagIndex, SymbolName});
+ auto *WeakExternal = Sym->getAux<object::coff_aux_weak_external>();
+ COFFSymbolIndex TagIndex = WeakExternal->TagIndex;
+ uint32_t Characteristics = WeakExternal->Characteristics;
+ WeakExternalRequests.push_back(
+ {SymIndex, TagIndex, Characteristics, SymbolName});
} else {
Expected<jitlink::Symbol *> NewGSym =
createDefinedSymbol(SymIndex, SymbolName, *Sym, Sec);
@@ -279,35 +276,41 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
// Export the weak external symbols and alias it
- for (auto &WeakAlias : WeakAliasRequests) {
- if (auto *Target = getGraphSymbol(WeakAlias.Target)) {
+ for (auto &WeakExternal : WeakExternalRequests) {
+ if (auto *Target = getGraphSymbol(WeakExternal.Target)) {
Expected<object::COFFSymbolRef> AliasSymbol =
- Obj.getSymbol(WeakAlias.Alias);
+ Obj.getSymbol(WeakExternal.Alias);
if (!AliasSymbol)
return AliasSymbol.takeError();
+ // FIXME: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY and
+ // IMAGE_WEAK_EXTERN_SEARCH_LIBRARY are handled in the same way.
+ Scope S =
+ WeakExternal.Characteristics == COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS
+ ? Scope::Default
+ : Scope::Local;
+
// FIXME: Support this when there's a way to handle this.
if (!Target->isDefined())
return make_error<JITLinkError>("Weak external symbol with external "
"symbol as alternative not supported.");
jitlink::Symbol *NewSymbol = &G->addDefinedSymbol(
- Target->getBlock(), Target->getOffset(), WeakAlias.SymbolName,
- Target->getSize(), Linkage::Weak, Scope::Default,
- Target->isCallable(), false);
- setGraphSymbol(AliasSymbol->getSectionNumber(), WeakAlias.Alias,
+ Target->getBlock(), Target->getOffset(), WeakExternal.SymbolName,
+ Target->getSize(), Linkage::Weak, S, Target->isCallable(), false);
+ setGraphSymbol(AliasSymbol->getSectionNumber(), WeakExternal.Alias,
*NewSymbol);
LLVM_DEBUG({
- dbgs() << " " << WeakAlias.Alias
+ dbgs() << " " << WeakExternal.Alias
<< ": Creating weak external symbol for COFF symbol \""
- << WeakAlias.SymbolName << "\" in section "
+ << WeakExternal.SymbolName << "\" in section "
<< AliasSymbol->getSectionNumber() << "\n";
dbgs() << " " << *NewSymbol << "\n";
});
} else
return make_error<JITLinkError>("Weak symbol alias requested but actual "
"symbol not found for symbol " +
- formatv("{0:d}", WeakAlias.Alias));
+ formatv("{0:d}", WeakExternal.Alias));
}
return Error::success();
}
@@ -324,6 +327,8 @@ Error COFFLinkGraphBuilder::calculateImplicitSizeOfSymbols() {
SecIndex <= static_cast<COFFSectionIndex>(Obj.getNumberOfSections());
SecIndex++) {
auto &SymbolSet = SymbolSets[SecIndex];
+ if (SymbolSet.empty())
+ continue;
jitlink::Block *B = getGraphBlock(SecIndex);
orc::ExecutorAddrDiff LastOffset = B->getSize();
orc::ExecutorAddrDiff LastDifferentOffset = B->getSize();
@@ -394,25 +399,35 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
formatv("{0:d}", SymIndex));
Block *B = getGraphBlock(Symbol.getSectionNumber());
+ if (!B) {
+ LLVM_DEBUG({
+ dbgs() << " " << SymIndex
+ << ": Skipping graph symbol since section was not created for "
+ "COFF symbol \""
+ << SymbolName << "\" in section " << Symbol.getSectionNumber()
+ << "\n";
+ });
+ return nullptr;
+ }
+
if (Symbol.isExternal()) {
// This is not a comdat sequence, export the symbol as it is
- if (!isComdatSection(Section))
+ if (!isComdatSection(Section)) {
+
return &G->addDefinedSymbol(
*B, Symbol.getValue(), SymbolName, 0, Linkage::Strong, Scope::Default,
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION, false);
- else {
- if (!PendingComdatExport)
+ } else {
+ if (!PendingComdatExports[Symbol.getSectionNumber()])
return make_error<JITLinkError>("No pending COMDAT export for symbol " +
formatv("{0:d}", SymIndex));
- if (PendingComdatExport->SectionIndex != Symbol.getSectionNumber())
- return make_error<JITLinkError>(
- "COMDAT export section number mismatch for symbol " +
- formatv("{0:d}", SymIndex));
+
return exportCOMDATSymbol(SymIndex, SymbolName, Symbol);
}
}
- if (Symbol.getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC) {
+ if (Symbol.getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC ||
+ Symbol.getStorageClass() == COFF::IMAGE_SYM_CLASS_LABEL) {
const object::coff_aux_section_definition *Definition =
Symbol.getSectionDefinition();
if (!Definition || !isComdatSection(Section)) {
@@ -422,12 +437,14 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION, false);
}
if (Definition->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
- // FIXME: don't dead strip this when parent section is alive
- return &G->addDefinedSymbol(
+ auto Target = Definition->getNumber(Symbol.isBigObj());
+ auto GSym = &G->addDefinedSymbol(
*B, Symbol.getValue(), SymbolName, 0, Linkage::Strong, Scope::Local,
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION, false);
+ getGraphBlock(Target)->addEdge(Edge::KeepAlive, 0, *GSym, 0);
+ return GSym;
}
- if (PendingComdatExport)
+ if (PendingComdatExports[Symbol.getSectionNumber()])
return make_error<JITLinkError>(
"COMDAT export request already exists before symbol " +
formatv("{0:d}", SymIndex));
@@ -474,10 +491,16 @@ Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
break;
}
case COFF::IMAGE_COMDAT_SELECT_LARGEST: {
- // FIXME: Support IMAGE_COMDAT_SELECT_LARGEST when LinkGraph is able to
- // handle this.
- return make_error<JITLinkError>(
- "IMAGE_COMDAT_SELECT_LARGEST is not supported.");
+ // FIXME: Support IMAGE_COMDAT_SELECT_LARGEST properly when LinkGraph is
+ // able to handle this.
+ LLVM_DEBUG({
+ dbgs() << " " << SymIndex
+ << ": Partially supported IMAGE_COMDAT_SELECT_LARGEST was used"
+ " in section "
+ << Symbol.getSectionNumber() << "\n";
+ });
+ L = Linkage::Weak;
+ break;
}
case COFF::IMAGE_COMDAT_SELECT_NEWEST: {
// Even link.exe doesn't support this selection properly.
@@ -489,7 +512,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
formatv("{0:d}", Definition->Selection));
}
}
- PendingComdatExport = {SymIndex, Symbol.getSectionNumber(), L};
+ PendingComdatExports[Symbol.getSectionNumber()] = {SymIndex, L};
return &G->addAnonymousSymbol(*B, Symbol.getValue(), Definition->Length,
false, false);
}
@@ -499,6 +522,7 @@ Expected<Symbol *>
COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
StringRef SymbolName,
object::COFFSymbolRef Symbol) {
+ auto &PendingComdatExport = PendingComdatExports[Symbol.getSectionNumber()];
COFFSymbolIndex TargetIndex = PendingComdatExport->SymbolIndex;
Linkage L = PendingComdatExport->Linkage;
jitlink::Symbol *Target = getGraphSymbol(TargetIndex);