Skip to content

Commit 965c3d7

Browse files
authored
[lld][WebAssembly] Fix SEGFAULT when importing wrapped symbol (llvm#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.
1 parent ee45ba2 commit 965c3d7

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

lld/test/wasm/wrap_import.s

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
2+
# RUN: wasm-ld -wrap nosuchsym -wrap foo -allow-undefined -o %t.wasm %t.o
3+
# RUN: obj2yaml %t.wasm | FileCheck %s
4+
5+
.globl foo
6+
.globl _start
7+
8+
foo:
9+
.functype foo () -> ()
10+
end_function
11+
12+
_start:
13+
.functype _start () -> ()
14+
call foo
15+
end_function
16+
17+
# CHECK: - Type: IMPORT
18+
# CHECK-NEXT: Imports:
19+
# CHECK-NEXT: - Module: env
20+
# CHECK-NEXT: Field: __wrap_foo
21+
# CHECK-NEXT: Kind: FUNCTION
22+
# CHECK-NEXT SigIndex: 0
23+
24+
# CHECK: - Type: CODE
25+
# CHECK-NEXT: Functions:
26+
# CHECK-NEXT: Index: 1
27+
28+
# CHECK: FunctionNames:
29+
# CHECK-NEXT: - Index: 0
30+
# CHECK-NEXT: Name: __wrap_foo
31+
# CHECK-NEXT: - Index: 1
32+
# CHECK-NEXT: Name: _start

lld/wasm/Driver.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,9 +1173,10 @@ struct WrappedSymbol {
11731173
Symbol *wrap;
11741174
};
11751175

1176-
static Symbol *addUndefined(StringRef name) {
1176+
static Symbol *addUndefined(StringRef name,
1177+
const WasmSignature *signature = nullptr) {
11771178
return symtab->addUndefinedFunction(name, std::nullopt, std::nullopt,
1178-
WASM_SYMBOL_UNDEFINED, nullptr, nullptr,
1179+
WASM_SYMBOL_UNDEFINED, nullptr, signature,
11791180
false);
11801181
}
11811182

@@ -1198,7 +1199,8 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
11981199
continue;
11991200

12001201
Symbol *real = addUndefined(saver().save("__real_" + name));
1201-
Symbol *wrap = addUndefined(saver().save("__wrap_" + name));
1202+
Symbol *wrap =
1203+
addUndefined(saver().save("__wrap_" + name), sym->getSignature());
12021204
v.push_back({sym, real, wrap});
12031205

12041206
// We want to tell LTO not to inline symbols to be overwritten

lld/wasm/SyntheticSections.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ void ImportSection::addImport(Symbol *sym) {
196196
StringRef module = sym->importModule.value_or(defaultModule);
197197
StringRef name = sym->importName.value_or(sym->getName());
198198
if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
199-
ImportKey<WasmSignature> key(*(f->getSignature()), module, name);
199+
const WasmSignature *sig = f->getSignature();
200+
assert(sig && "imported functions must have a signature");
201+
ImportKey<WasmSignature> key(*sig, module, name);
200202
auto entry = importedFunctions.try_emplace(key, numImportedFunctions);
201203
if (entry.second) {
202204
importedSymbols.emplace_back(sym);

0 commit comments

Comments
 (0)