Skip to content

Commit cd13377

Browse files
committed
[lld][WebAssembly] Handle stub symbol dependencies when an exlicit import name is used
1 parent 9a88aa0 commit cd13377

File tree

3 files changed

+86
-43
lines changed

3 files changed

+86
-43
lines changed

lld/wasm/Driver.cpp

+57-37
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,47 @@ static void processStubLibrariesPreLTO() {
955955
}
956956
}
957957

958+
static bool addStubSymbolDeps(const StubFile *stub_file, Symbol *sym,
959+
ArrayRef<StringRef> deps) {
960+
// The first stub library to define a given symbol sets this and
961+
// definitions in later stub libraries are ignored.
962+
if (sym->forceImport)
963+
return false; // Already handled
964+
sym->forceImport = true;
965+
if (sym->traced)
966+
message(toString(stub_file) + ": importing " + sym->getName());
967+
else
968+
LLVM_DEBUG(llvm::dbgs() << toString(stub_file) << ": importing "
969+
<< sym->getName() << "\n");
970+
bool depsAdded = false;
971+
for (const auto dep : deps) {
972+
auto *needed = symtab->find(dep);
973+
if (!needed) {
974+
error(toString(stub_file) + ": undefined symbol: " + dep +
975+
". Required by " + toString(*sym));
976+
} else if (needed->isUndefined()) {
977+
error(toString(stub_file) + ": undefined symbol: " + toString(*needed) +
978+
". Required by " + toString(*sym));
979+
} else {
980+
if (needed->traced)
981+
message(toString(stub_file) + ": exported " + toString(*needed) +
982+
" due to import of " + sym->getName());
983+
else
984+
LLVM_DEBUG(llvm::dbgs()
985+
<< "force export: " << toString(*needed) << "\n");
986+
needed->forceExport = true;
987+
if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
988+
depsAdded = true;
989+
lazy->extract();
990+
if (!config->whyExtract.empty())
991+
ctx.whyExtractRecords.emplace_back(toString(stub_file),
992+
sym->getFile(), *sym);
993+
}
994+
}
995+
}
996+
return depsAdded;
997+
}
998+
958999
static void processStubLibraries() {
9591000
log("-- processStubLibraries");
9601001
bool depsAdded = false;
@@ -963,49 +1004,28 @@ static void processStubLibraries() {
9631004
for (auto &stub_file : ctx.stubFiles) {
9641005
LLVM_DEBUG(llvm::dbgs()
9651006
<< "processing stub file: " << stub_file->getName() << "\n");
1007+
1008+
// First look for any imported symbols that directly match
1009+
// the names of the stub imports
9661010
for (auto [name, deps]: stub_file->symbolDependencies) {
9671011
auto* sym = symtab->find(name);
968-
if (!sym || !sym->isUndefined()) {
1012+
if (sym && sym->isUndefined()) {
1013+
depsAdded |= addStubSymbolDeps(stub_file, sym, deps);
1014+
} else {
9691015
if (sym && sym->traced)
9701016
message(toString(stub_file) + ": stub symbol not needed: " + name);
9711017
else
972-
LLVM_DEBUG(llvm::dbgs() << "stub symbol not needed: `" << name << "`\n");
973-
continue;
1018+
LLVM_DEBUG(llvm::dbgs()
1019+
<< "stub symbol not needed: `" << name << "`\n");
9741020
}
975-
// The first stub library to define a given symbol sets this and
976-
// definitions in later stub libraries are ignored.
977-
if (sym->forceImport)
978-
continue; // Already handled
979-
sym->forceImport = true;
980-
if (sym->traced)
981-
message(toString(stub_file) + ": importing " + name);
982-
else
983-
LLVM_DEBUG(llvm::dbgs()
984-
<< toString(stub_file) << ": importing " << name << "\n");
985-
for (const auto dep : deps) {
986-
auto* needed = symtab->find(dep);
987-
if (!needed) {
988-
error(toString(stub_file) + ": undefined symbol: " + dep +
989-
". Required by " + toString(*sym));
990-
} else if (needed->isUndefined()) {
991-
error(toString(stub_file) +
992-
": undefined symbol: " + toString(*needed) +
993-
". Required by " + toString(*sym));
994-
} else {
995-
if (needed->traced)
996-
message(toString(stub_file) + ": exported " + toString(*needed) +
997-
" due to import of " + name);
998-
else
999-
LLVM_DEBUG(llvm::dbgs()
1000-
<< "force export: " << toString(*needed) << "\n");
1001-
needed->forceExport = true;
1002-
if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
1003-
depsAdded = true;
1004-
lazy->extract();
1005-
if (!config->whyExtract.empty())
1006-
ctx.whyExtractRecords.emplace_back(stub_file->getName(),
1007-
sym->getFile(), *sym);
1008-
}
1021+
}
1022+
1023+
// Secondly looks for any symbols with an `importName` that matches
1024+
for (Symbol *sym : symtab->symbols()) {
1025+
if (sym->isUndefined() && sym->importName.has_value()) {
1026+
auto it = stub_file->symbolDependencies.find(sym->importName.value());
1027+
if (it != stub_file->symbolDependencies.end()) {
1028+
depsAdded |= addStubSymbolDeps(stub_file, sym, it->second);
10091029
}
10101030
}
10111031
}

lld/wasm/SymbolTable.cpp

+27-6
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,15 @@ static void setImportAttributes(T *existing,
507507
}
508508
}
509509

510+
static void traceImport(std::optional<StringRef> importName, InputFile *file) {
511+
if (importName.has_value()) {
512+
auto name = importName.value();
513+
if (symtab->isTraced(name)) {
514+
printTraceSymbolUndefined(name, file);
515+
}
516+
}
517+
}
518+
510519
Symbol *SymbolTable::addUndefinedFunction(StringRef name,
511520
std::optional<StringRef> importName,
512521
std::optional<StringRef> importModule,
@@ -526,6 +535,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
526535
printTraceSymbolUndefined(name, file);
527536

528537
auto replaceSym = [&]() {
538+
traceImport(importName, file);
529539
replaceSymbol<UndefinedFunction>(s, name, importName, importModule, flags,
530540
file, sig, isCalledDirectly);
531541
};
@@ -560,6 +570,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
560570
replaceSym();
561571
}
562572
if (existingUndefined) {
573+
traceImport(importName, file);
563574
setImportAttributes(existingUndefined, importName, importModule, flags,
564575
file);
565576
if (isCalledDirectly)
@@ -612,10 +623,11 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
612623
if (s->traced)
613624
printTraceSymbolUndefined(name, file);
614625

615-
if (wasInserted)
626+
if (wasInserted) {
627+
traceImport(importName, file);
616628
replaceSymbol<UndefinedGlobal>(s, name, importName, importModule, flags,
617629
file, type);
618-
else if (auto *lazy = dyn_cast<LazySymbol>(s))
630+
} else if (auto *lazy = dyn_cast<LazySymbol>(s))
619631
lazy->extract();
620632
else if (s->isDefined())
621633
checkGlobalType(s, file, type);
@@ -638,10 +650,11 @@ Symbol *SymbolTable::addUndefinedTable(StringRef name,
638650
if (s->traced)
639651
printTraceSymbolUndefined(name, file);
640652

641-
if (wasInserted)
653+
if (wasInserted) {
654+
traceImport(importName, file);
642655
replaceSymbol<UndefinedTable>(s, name, importName, importModule, flags,
643656
file, type);
644-
else if (auto *lazy = dyn_cast<LazySymbol>(s))
657+
} else if (auto *lazy = dyn_cast<LazySymbol>(s))
645658
lazy->extract();
646659
else if (s->isDefined())
647660
checkTableType(s, file, type);
@@ -664,10 +677,11 @@ Symbol *SymbolTable::addUndefinedTag(StringRef name,
664677
if (s->traced)
665678
printTraceSymbolUndefined(name, file);
666679

667-
if (wasInserted)
680+
if (wasInserted) {
681+
traceImport(importName, file);
668682
replaceSymbol<UndefinedTag>(s, name, importName, importModule, flags, file,
669683
sig);
670-
else if (auto *lazy = dyn_cast<LazySymbol>(s))
684+
} else if (auto *lazy = dyn_cast<LazySymbol>(s))
671685
lazy->extract();
672686
else if (s->isDefined())
673687
checkTagType(s, file, sig);
@@ -831,6 +845,13 @@ void SymbolTable::trace(StringRef name) {
831845
symMap.insert({CachedHashStringRef(name), -1});
832846
}
833847

848+
bool SymbolTable::isTraced(StringRef name) {
849+
auto it = symMap.find(CachedHashStringRef(name));
850+
if (it == symMap.end())
851+
return false;
852+
return it->second == -1 || symVector[it->second]->traced;
853+
}
854+
834855
void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
835856
// Swap symbols as instructed by -wrap.
836857
int &origIdx = symMap[CachedHashStringRef(sym->getName())];

lld/wasm/SymbolTable.h

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class SymbolTable {
5050

5151
void trace(StringRef name);
5252

53+
bool isTraced(StringRef name);
54+
5355
Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
5456
InputFunction *function);
5557
Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,

0 commit comments

Comments
 (0)