[lld] 965c3d7 - [lld][WebAssembly] Fix SEGFAULT when importing wrapped symbol (#169656)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 27 11:21:13 PST 2025
Author: Lukas Döllerer
Date: 2025-11-27T19:21:09Z
New Revision: 965c3d760de35753d97d41c6b69582cecff8819d
URL: https://github.com/llvm/llvm-project/commit/965c3d760de35753d97d41c6b69582cecff8819d
DIFF: https://github.com/llvm/llvm-project/commit/965c3d760de35753d97d41c6b69582cecff8819d.diff
LOG: [lld][WebAssembly] Fix SEGFAULT when importing wrapped symbol (#169656)
When wrapping a symbol `foo` via `-wrap=foo`, we create the symbol
`__wrap_foo` that replaces all mentions of `foo`. This feature was
implemented for wasm-ld in commit a5ca34e.
So far, no valid signature has been attached to the undefined symbol,
leading to a nullptr dereference in the logic for creating the import
section. This change adds the correct signature to the wrapped symbol,
enabling the generation of an import for it.
Added:
lld/test/wasm/wrap_import.s
Modified:
lld/wasm/Driver.cpp
lld/wasm/SyntheticSections.cpp
Removed:
################################################################################
diff --git a/lld/test/wasm/wrap_import.s b/lld/test/wasm/wrap_import.s
new file mode 100644
index 0000000000000..ce3b6f57f10c4
--- /dev/null
+++ b/lld/test/wasm/wrap_import.s
@@ -0,0 +1,32 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
+# RUN: wasm-ld -wrap nosuchsym -wrap foo -allow-undefined -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+.globl foo
+.globl _start
+
+foo:
+ .functype foo () -> ()
+ end_function
+
+_start:
+ .functype _start () -> ()
+ call foo
+ end_function
+
+# CHECK: - Type: IMPORT
+# CHECK-NEXT: Imports:
+# CHECK-NEXT: - Module: env
+# CHECK-NEXT: Field: __wrap_foo
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT SigIndex: 0
+
+# CHECK: - Type: CODE
+# CHECK-NEXT: Functions:
+# CHECK-NEXT: Index: 1
+
+# CHECK: FunctionNames:
+# CHECK-NEXT: - Index: 0
+# CHECK-NEXT: Name: __wrap_foo
+# CHECK-NEXT: - Index: 1
+# CHECK-NEXT: Name: _start
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index fac166587cb9b..97e50783985a8 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -1173,9 +1173,10 @@ struct WrappedSymbol {
Symbol *wrap;
};
-static Symbol *addUndefined(StringRef name) {
+static Symbol *addUndefined(StringRef name,
+ const WasmSignature *signature = nullptr) {
return symtab->addUndefinedFunction(name, std::nullopt, std::nullopt,
- WASM_SYMBOL_UNDEFINED, nullptr, nullptr,
+ WASM_SYMBOL_UNDEFINED, nullptr, signature,
false);
}
@@ -1198,7 +1199,8 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
continue;
Symbol *real = addUndefined(saver().save("__real_" + name));
- Symbol *wrap = addUndefined(saver().save("__wrap_" + name));
+ Symbol *wrap =
+ addUndefined(saver().save("__wrap_" + name), sym->getSignature());
v.push_back({sym, real, wrap});
// We want to tell LTO not to inline symbols to be overwritten
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 399a5084e6595..5e7b9c229f3ed 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -196,7 +196,9 @@ void ImportSection::addImport(Symbol *sym) {
StringRef module = sym->importModule.value_or(defaultModule);
StringRef name = sym->importName.value_or(sym->getName());
if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
- ImportKey<WasmSignature> key(*(f->getSignature()), module, name);
+ const WasmSignature *sig = f->getSignature();
+ assert(sig && "imported functions must have a signature");
+ ImportKey<WasmSignature> key(*sig, module, name);
auto entry = importedFunctions.try_emplace(key, numImportedFunctions);
if (entry.second) {
importedSymbols.emplace_back(sym);
More information about the llvm-commits
mailing list