diff --git a/lld/test/wasm/import-module.ll b/lld/test/wasm/import-module.ll new file mode 100644 index 000000000000..9a473194ce2c --- /dev/null +++ b/lld/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 diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index 19018d280284..95aa26849497 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -378,7 +378,8 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) { 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 @@ static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym, 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); } diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 584893d75b82..0e76dc214eda 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -80,8 +80,8 @@ BitcodeCompiler::~BitcodeCompiler() = default; 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 diff --git a/lld/wasm/LTO.h b/lld/wasm/LTO.h index 57a273439321..37fea7ad6ee5 100644 --- a/lld/wasm/LTO.h +++ b/lld/wasm/LTO.h @@ -22,6 +22,7 @@ #include "lld/Common/LLVM.h" #include "llvm/ADT/SmallString.h" +#include "Writer.h" #include #include diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index f490d4c7191f..e45dc6bec715 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -315,8 +315,8 @@ Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, 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 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, 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 diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h index b721984e8411..f0bdd6cc01c8 100644 --- a/lld/wasm/SymbolTable.h +++ b/lld/wasm/SymbolTable.h @@ -58,8 +58,8 @@ public: 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); diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index 63c023935cbb..652d0a9ef6a3 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -155,13 +155,17 @@ public: 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 { diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index d8986c837385..a1b40971ea0c 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -41,6 +41,7 @@ using namespace lld::wasm; static constexpr int kStackAlignment = 16; static constexpr const char *kFunctionTableName = "__indirect_function_table"; +const char *lld::wasm::kDefaultModule = "env"; namespace { @@ -156,7 +157,7 @@ void Writer::createImportSection() { 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 @@ void Writer::createImportSection() { 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 @@ void Writer::createImportSection() { 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; diff --git a/lld/wasm/Writer.h b/lld/wasm/Writer.h index d83e4cbda628..cf3681ddf35d 100644 --- a/lld/wasm/Writer.h +++ b/lld/wasm/Writer.h @@ -14,6 +14,8 @@ namespace wasm { void writeResult(); +extern const char *kDefaultModule; + } // namespace wasm } // namespace lld