[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