Index: test/wasm/import-module.ll =================================================================== --- /dev/null +++ test/wasm/import-module.ll @@ -0,0 +1,21 @@ +; RUN: llc -filetype=obj %s -o %t.o +; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +target triple = "wasm32-unknown-unknown-wasm" + +define void @_start() { + call void @foo(); + ret void +} + +declare void @foo() #0 + +attributes #0 = { "wasm-import-module"="bar" } + +; CHECK: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: bar +; CHECK-NEXT: Field: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -363,12 +363,12 @@ // For now, since we don't actually use the start function as the // wasm start symbol, we don't need to care about it signature. if (!Config->Entry.empty()) - EntrySym = - Symtab->addUndefinedFunction(Config->Entry, 0, nullptr, nullptr); + EntrySym = Symtab->addUndefinedFunction(Config->Entry, kDefaultModule, 0, + nullptr, nullptr); // Handle the `--undefined ` options. for (auto *Arg : Args.filtered(OPT_undefined)) - Symtab->addUndefinedFunction(Arg->getValue(), 0, nullptr, nullptr); + Symtab->addUndefinedFunction(Arg->getValue(), kDefaultModule, 0, nullptr, nullptr); } createFiles(Args); Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -326,7 +326,8 @@ switch (Sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: - return Symtab->addUndefinedFunction(Name, Flags, this, Sym.FunctionType); + return Symtab->addUndefinedFunction(Name, Sym.Info.Module, Flags, this, + Sym.FunctionType); case WASM_SYMBOL_TYPE_DATA: return Symtab->addUndefinedData(Name, Flags, this); case WASM_SYMBOL_TYPE_GLOBAL: Index: wasm/SymbolTable.h =================================================================== --- wasm/SymbolTable.h +++ wasm/SymbolTable.h @@ -57,8 +57,8 @@ Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, InputGlobal *G); - Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, - const WasmSignature *Signature); + Symbol *addUndefinedFunction(StringRef Name, StringRef Module, uint32_t Flags, + InputFile *File, const WasmSignature *Signature); Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File); Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, const WasmGlobalType *Type); Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -228,8 +228,8 @@ return S; } -Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, - InputFile *File, +Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef Module, + uint32_t Flags, InputFile *File, const WasmSignature *Sig) { DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n"); @@ -238,7 +238,7 @@ std::tie(S, WasInserted) = insert(Name); if (WasInserted) - replaceSymbol(S, Name, Flags, File, Sig); + replaceSymbol(S, Name, Module, Flags, File, Sig); else if (auto *Lazy = dyn_cast(S)) Lazy->fetch(); else if (S->isDefined()) Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -148,13 +148,17 @@ class UndefinedFunction : public FunctionSymbol { public: - UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr, + UndefinedFunction(StringRef Name, StringRef Module, uint32_t Flags, + InputFile *File = nullptr, const WasmSignature *Type = nullptr) - : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {} + : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type), + Module(Module) {} static bool classof(const Symbol *S) { return S->kind() == UndefinedFunctionKind; } + + StringRef Module; }; class SectionSymbol : public Symbol { Index: wasm/Writer.h =================================================================== --- wasm/Writer.h +++ wasm/Writer.h @@ -15,6 +15,8 @@ void writeResult(); +extern const char *kDefaultModule; + } // namespace wasm } // namespace lld Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -41,6 +41,7 @@ static constexpr int kStackAlignment = 16; static constexpr int kInitialTableOffset = 1; static constexpr const char *kFunctionTableName = "__indirect_function_table"; +const char *lld::wasm::kDefaultModule = "env"; namespace { @@ -146,7 +147,7 @@ if (Config->ImportMemory) { WasmImport Import; - Import.Module = "env"; + Import.Module = kDefaultModule; Import.Field = "memory"; Import.Kind = WASM_EXTERNAL_MEMORY; Import.Memory.Flags = 0; @@ -161,7 +162,7 @@ if (Config->ImportTable) { uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size(); WasmImport Import; - Import.Module = "env"; + Import.Module = kDefaultModule; Import.Field = kFunctionTableName; Import.Kind = WASM_EXTERNAL_TABLE; Import.Table.ElemType = WASM_TYPE_ANYFUNC; @@ -171,7 +172,11 @@ for (const Symbol *Sym : ImportedSymbols) { WasmImport Import; - Import.Module = "env"; + if (auto *F = dyn_cast(Sym)) + Import.Module = F->Module; + else + Import.Module = kDefaultModule; + Import.Field = Sym->getName(); if (auto *FunctionSym = dyn_cast(Sym)) { Import.Kind = WASM_EXTERNAL_FUNCTION;