Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions lld/test/wasm/wrap_import.s
Original file line number Diff line number Diff line change
@@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right value here for the relocation? Shouldn't it be function zero (i.e. the __wrap_foo import) that is called here? It is this index 1 in the symbol table? If so you we should probably show the symbol table here too. (or just drop the Relocations and emit-relocs flag completely?)

Could be a bug in --emit-relocs maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just stepped through the code a bit and I think this is intended behavior.

  - Type:            CODE
    Relocations:
      - Type:            R_WASM_FUNCTION_INDEX_LEB
        Index:           1
        Offset:          0x4
    Functions:
      - Index:           1
        Locals:          []
        Body:            1080808080000B
  - Type:            CUSTOM
    Name:            linking
    Version:         2
    SymbolTable:
      - Index:           0
        Kind:            FUNCTION
        Name:            _start
        Flags:           [  ]
        Function:        1
      - Index:           1
        Kind:            FUNCTION
        Name:            __wrap_foo
        Flags:           [ UNDEFINED ]
        Function:        0
  - Type:            CUSTOM
    Name:            name
    FunctionNames:
      - Index:           0
        Name:            __wrap_foo
      - Index:           1
        Name:            _start

The symbol index is a different one than the function index. __wrap_foo has symbol index 1, which is why the relocation is emitted for index 1, while _start has function index 1, explaining why this function is shown.


# CHECK: FunctionNames:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: __wrap_foo
# CHECK-NEXT: - Index: 1
# CHECK-NEXT: Name: _start
8 changes: 5 additions & 3 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion lld/wasm/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down