[lld] [lld][WebAssembly] Handle stub symbol dependencies when an explicit import name is used (PR #80169)
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 19 11:39:15 PDT 2024
https://github.com/sbc100 updated https://github.com/llvm/llvm-project/pull/80169
>From cd133776fe54be283f9936c46d210fbdf8761dc9 Mon Sep 17 00:00:00 2001
From: Sam Clegg <sbc at chromium.org>
Date: Sun, 28 Jan 2024 10:19:49 -0800
Subject: [PATCH] [lld][WebAssembly] Handle stub symbol dependencies when an
exlicit import name is used
---
lld/wasm/Driver.cpp | 94 ++++++++++++++++++++++++----------------
lld/wasm/SymbolTable.cpp | 33 +++++++++++---
lld/wasm/SymbolTable.h | 2 +
3 files changed, 86 insertions(+), 43 deletions(-)
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index b06c1e9b0be1b..d099689911fc6 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -955,6 +955,47 @@ static void processStubLibrariesPreLTO() {
}
}
+static bool addStubSymbolDeps(const StubFile *stub_file, Symbol *sym,
+ ArrayRef<StringRef> deps) {
+ // The first stub library to define a given symbol sets this and
+ // definitions in later stub libraries are ignored.
+ if (sym->forceImport)
+ return false; // Already handled
+ sym->forceImport = true;
+ if (sym->traced)
+ message(toString(stub_file) + ": importing " + sym->getName());
+ else
+ LLVM_DEBUG(llvm::dbgs() << toString(stub_file) << ": importing "
+ << sym->getName() << "\n");
+ bool depsAdded = false;
+ for (const auto dep : deps) {
+ auto *needed = symtab->find(dep);
+ if (!needed) {
+ error(toString(stub_file) + ": undefined symbol: " + dep +
+ ". Required by " + toString(*sym));
+ } else if (needed->isUndefined()) {
+ error(toString(stub_file) + ": undefined symbol: " + toString(*needed) +
+ ". Required by " + toString(*sym));
+ } else {
+ if (needed->traced)
+ message(toString(stub_file) + ": exported " + toString(*needed) +
+ " due to import of " + sym->getName());
+ else
+ LLVM_DEBUG(llvm::dbgs()
+ << "force export: " << toString(*needed) << "\n");
+ needed->forceExport = true;
+ if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
+ depsAdded = true;
+ lazy->extract();
+ if (!config->whyExtract.empty())
+ ctx.whyExtractRecords.emplace_back(toString(stub_file),
+ sym->getFile(), *sym);
+ }
+ }
+ }
+ return depsAdded;
+}
+
static void processStubLibraries() {
log("-- processStubLibraries");
bool depsAdded = false;
@@ -963,49 +1004,28 @@ static void processStubLibraries() {
for (auto &stub_file : ctx.stubFiles) {
LLVM_DEBUG(llvm::dbgs()
<< "processing stub file: " << stub_file->getName() << "\n");
+
+ // First look for any imported symbols that directly match
+ // the names of the stub imports
for (auto [name, deps]: stub_file->symbolDependencies) {
auto* sym = symtab->find(name);
- if (!sym || !sym->isUndefined()) {
+ if (sym && sym->isUndefined()) {
+ depsAdded |= addStubSymbolDeps(stub_file, sym, deps);
+ } else {
if (sym && sym->traced)
message(toString(stub_file) + ": stub symbol not needed: " + name);
else
- LLVM_DEBUG(llvm::dbgs() << "stub symbol not needed: `" << name << "`\n");
- continue;
+ LLVM_DEBUG(llvm::dbgs()
+ << "stub symbol not needed: `" << name << "`\n");
}
- // The first stub library to define a given symbol sets this and
- // definitions in later stub libraries are ignored.
- if (sym->forceImport)
- continue; // Already handled
- sym->forceImport = true;
- if (sym->traced)
- message(toString(stub_file) + ": importing " + name);
- else
- LLVM_DEBUG(llvm::dbgs()
- << toString(stub_file) << ": importing " << name << "\n");
- for (const auto dep : deps) {
- auto* needed = symtab->find(dep);
- if (!needed) {
- error(toString(stub_file) + ": undefined symbol: " + dep +
- ". Required by " + toString(*sym));
- } else if (needed->isUndefined()) {
- error(toString(stub_file) +
- ": undefined symbol: " + toString(*needed) +
- ". Required by " + toString(*sym));
- } else {
- if (needed->traced)
- message(toString(stub_file) + ": exported " + toString(*needed) +
- " due to import of " + name);
- else
- LLVM_DEBUG(llvm::dbgs()
- << "force export: " << toString(*needed) << "\n");
- needed->forceExport = true;
- if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
- depsAdded = true;
- lazy->extract();
- if (!config->whyExtract.empty())
- ctx.whyExtractRecords.emplace_back(stub_file->getName(),
- sym->getFile(), *sym);
- }
+ }
+
+ // Secondly looks for any symbols with an `importName` that matches
+ for (Symbol *sym : symtab->symbols()) {
+ if (sym->isUndefined() && sym->importName.has_value()) {
+ auto it = stub_file->symbolDependencies.find(sym->importName.value());
+ if (it != stub_file->symbolDependencies.end()) {
+ depsAdded |= addStubSymbolDeps(stub_file, sym, it->second);
}
}
}
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 00c347ea3ef24..8a1c0ab1d4f43 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -507,6 +507,15 @@ static void setImportAttributes(T *existing,
}
}
+static void traceImport(std::optional<StringRef> importName, InputFile *file) {
+ if (importName.has_value()) {
+ auto name = importName.value();
+ if (symtab->isTraced(name)) {
+ printTraceSymbolUndefined(name, file);
+ }
+ }
+}
+
Symbol *SymbolTable::addUndefinedFunction(StringRef name,
std::optional<StringRef> importName,
std::optional<StringRef> importModule,
@@ -526,6 +535,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
printTraceSymbolUndefined(name, file);
auto replaceSym = [&]() {
+ traceImport(importName, file);
replaceSymbol<UndefinedFunction>(s, name, importName, importModule, flags,
file, sig, isCalledDirectly);
};
@@ -560,6 +570,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
replaceSym();
}
if (existingUndefined) {
+ traceImport(importName, file);
setImportAttributes(existingUndefined, importName, importModule, flags,
file);
if (isCalledDirectly)
@@ -612,10 +623,11 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
if (s->traced)
printTraceSymbolUndefined(name, file);
- if (wasInserted)
+ if (wasInserted) {
+ traceImport(importName, file);
replaceSymbol<UndefinedGlobal>(s, name, importName, importModule, flags,
file, type);
- else if (auto *lazy = dyn_cast<LazySymbol>(s))
+ } else if (auto *lazy = dyn_cast<LazySymbol>(s))
lazy->extract();
else if (s->isDefined())
checkGlobalType(s, file, type);
@@ -638,10 +650,11 @@ Symbol *SymbolTable::addUndefinedTable(StringRef name,
if (s->traced)
printTraceSymbolUndefined(name, file);
- if (wasInserted)
+ if (wasInserted) {
+ traceImport(importName, file);
replaceSymbol<UndefinedTable>(s, name, importName, importModule, flags,
file, type);
- else if (auto *lazy = dyn_cast<LazySymbol>(s))
+ } else if (auto *lazy = dyn_cast<LazySymbol>(s))
lazy->extract();
else if (s->isDefined())
checkTableType(s, file, type);
@@ -664,10 +677,11 @@ Symbol *SymbolTable::addUndefinedTag(StringRef name,
if (s->traced)
printTraceSymbolUndefined(name, file);
- if (wasInserted)
+ if (wasInserted) {
+ traceImport(importName, file);
replaceSymbol<UndefinedTag>(s, name, importName, importModule, flags, file,
sig);
- else if (auto *lazy = dyn_cast<LazySymbol>(s))
+ } else if (auto *lazy = dyn_cast<LazySymbol>(s))
lazy->extract();
else if (s->isDefined())
checkTagType(s, file, sig);
@@ -831,6 +845,13 @@ void SymbolTable::trace(StringRef name) {
symMap.insert({CachedHashStringRef(name), -1});
}
+bool SymbolTable::isTraced(StringRef name) {
+ auto it = symMap.find(CachedHashStringRef(name));
+ if (it == symMap.end())
+ return false;
+ return it->second == -1 || symVector[it->second]->traced;
+}
+
void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// Swap symbols as instructed by -wrap.
int &origIdx = symMap[CachedHashStringRef(sym->getName())];
diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h
index 42ebb8be8eb3f..cec30bea91ea0 100644
--- a/lld/wasm/SymbolTable.h
+++ b/lld/wasm/SymbolTable.h
@@ -50,6 +50,8 @@ class SymbolTable {
void trace(StringRef name);
+ bool isTraced(StringRef name);
+
Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
InputFunction *function);
Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,
More information about the llvm-commits
mailing list