[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 Jan 31 09:16:22 PST 2024
https://github.com/sbc100 created https://github.com/llvm/llvm-project/pull/80169
None
>From 1fc5bc55edaefac18bce78407e2b40edb42b1751 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 | 92 ++++++++++++++++++++++++----------------
lld/wasm/SymbolTable.cpp | 34 ++++++++++++---
lld/wasm/SymbolTable.h | 2 +
3 files changed, 86 insertions(+), 42 deletions(-)
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 635f19f78b15e..d984987591f74 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -947,6 +947,48 @@ 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;
@@ -955,49 +997,27 @@ 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;
}
- // 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..b6b52b1f180e1 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -507,6 +507,16 @@ 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 +536,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 +571,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
replaceSym();
}
if (existingUndefined) {
+ traceImport(importName, file);
setImportAttributes(existingUndefined, importName, importModule, flags,
file);
if (isCalledDirectly)
@@ -612,10 +624,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 +651,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 +678,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 +846,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