Index: test/wasm/import-module.ll =================================================================== --- test/wasm/import-module.ll +++ 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/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -378,7 +378,8 @@ switch (Sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: - return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature); + return Symtab->addUndefinedFunction(Name, Sym.Info.Module, Flags, this, + Sym.Signature); case WASM_SYMBOL_TYPE_DATA: return Symtab->addUndefinedData(Name, Flags, this); case WASM_SYMBOL_TYPE_GLOBAL: @@ -446,7 +447,7 @@ if (ObjSym.isUndefined()) { if (ObjSym.isExecutable()) - return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr); + return Symtab->addUndefinedFunction(Name, kDefaultModule, Flags, &F, nullptr); return Symtab->addUndefinedData(Name, Flags, &F); } Index: wasm/LTO.h =================================================================== --- wasm/LTO.h +++ wasm/LTO.h @@ -22,6 +22,7 @@ #include "lld/Common/LLVM.h" #include "llvm/ADT/SmallString.h" +#include "Writer.h" #include #include Index: wasm/LTO.cpp =================================================================== --- wasm/LTO.cpp +++ wasm/LTO.cpp @@ -80,8 +80,8 @@ static void undefine(Symbol *S) { if (auto F = dyn_cast(S)) - replaceSymbol(F, F->getName(), 0, F->getFile(), - F->Signature); + replaceSymbol(F, F->getName(), kDefaultModule, 0, + F->getFile(), F->Signature); else if (isa(S)) replaceSymbol(S, S->getName(), 0, S->getFile()); else Index: wasm/SymbolTable.h =================================================================== --- wasm/SymbolTable.h +++ wasm/SymbolTable.h @@ -58,8 +58,8 @@ Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, InputEvent *E); - 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 @@ -315,8 +315,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) { LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " [" << (Sig ? toString(*Sig) : "none") << "]\n"); @@ -326,7 +326,7 @@ std::tie(S, WasInserted) = insert(Name, File); 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 Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -155,13 +155,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 @@ -14,6 +14,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 const char *kFunctionTableName = "__indirect_function_table"; +const char *lld::wasm::kDefaultModule = "env"; namespace { @@ -156,7 +157,7 @@ if (Config->ImportMemory) { WasmImport Import; - Import.Module = "env"; + Import.Module = kDefaultModule; Import.Field = "memory"; Import.Kind = WASM_EXTERNAL_MEMORY; Import.Memory.Flags = 0; @@ -173,7 +174,7 @@ if (Config->ImportTable) { uint32_t TableSize = TableBase + IndirectFunctions.size(); WasmImport Import; - Import.Module = "env"; + Import.Module = kDefaultModule; Import.Field = kFunctionTableName; Import.Kind = WASM_EXTERNAL_TABLE; Import.Table.ElemType = WASM_TYPE_FUNCREF; @@ -183,7 +184,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;