[lld] Fix SEGFAULT in wasm-ld when importing wrapped symbol (PR #169656)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 26 06:24:32 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-wasm
Author: Lukas Döllerer (Lukasdoe)
<details>
<summary>Changes</summary>
When wrapping a symbol `foo` via `-wrap=foo`, we create the symbol `__wrap_foo` that replaces all mentions of `foo`.
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/169656.diff
3 Files Affected:
- (added) lld/test/wasm/wrap_import.s (+36)
- (modified) lld/wasm/Driver.cpp (+5-3)
- (modified) lld/wasm/SyntheticSections.cpp (+3-1)
``````````diff
diff --git a/lld/test/wasm/wrap_import.s b/lld/test/wasm/wrap_import.s
new file mode 100644
index 0000000000000..526c1f539a4fd
--- /dev/null
+++ b/lld/test/wasm/wrap_import.s
@@ -0,0 +1,36 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
+# RUN: wasm-ld -emit-relocs -wrap nosuchsym -wrap foo -allow-undefined -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+.globl foo
+.globl _start
+
+foo:
+ .functype foo () -> (i32)
+ i32.const 1
+ end_function
+
+_start:
+ .functype _start () -> ()
+ call foo
+ drop
+ 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: Relocations:
+# CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
+# CHECK-NEXT: Index: 1
+# CHECK-NEXT: Offset: 0x4
+
+# 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);
``````````
</details>
https://github.com/llvm/llvm-project/pull/169656
More information about the llvm-commits
mailing list