--- /dev/null
+; 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
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:
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);
}
static void undefine(Symbol *S) {
if (auto F = dyn_cast<DefinedFunction>(S))
- replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
- F->Signature);
+ replaceSymbol<UndefinedFunction>(F, F->getName(), kDefaultModule, 0,
+ F->getFile(), F->Signature);
else if (isa<DefinedData>(S))
replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
else
#include "lld/Common/LLVM.h"
#include "llvm/ADT/SmallString.h"
+#include "Writer.h"
#include <memory>
#include <vector>
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");
std::tie(S, WasInserted) = insert(Name, File);
if (WasInserted)
- replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
+ replaceSymbol<UndefinedFunction>(S, Name, Module, Flags, File, Sig);
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Lazy->fetch();
else
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);
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 {
static constexpr int kStackAlignment = 16;
static constexpr const char *kFunctionTableName = "__indirect_function_table";
+const char *lld::wasm::kDefaultModule = "env";
namespace {
if (Config->ImportMemory) {
WasmImport Import;
- Import.Module = "env";
+ Import.Module = kDefaultModule;
Import.Field = "memory";
Import.Kind = WASM_EXTERNAL_MEMORY;
Import.Memory.Flags = 0;
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;
for (const Symbol *Sym : ImportedSymbols) {
WasmImport Import;
- Import.Module = "env";
+ if (auto *F = dyn_cast<UndefinedFunction>(Sym))
+ Import.Module = F->Module;
+ else
+ Import.Module = kDefaultModule;
+
Import.Field = Sym->getName();
if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
Import.Kind = WASM_EXTERNAL_FUNCTION;
void writeResult();
+extern const char *kDefaultModule;
+
} // namespace wasm
} // namespace lld