[WebAssembly] Support imports from custom module names
Fixes: https://bugs.llvm.org/show_bug.cgi?id=37168 This is only a first pass at supporting these custom import modules. In the long run we most likely want to treat these kinds of symbols very differently. For example, it should not be possible to resolve such as symbol at static link type. Differential Revision: https://reviews.llvm.org/D45796 llvm-svn: 352828
This commit is contained in:
parent
13680223b9
commit
7cc0753118
|
@ -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
|
|
@ -378,7 +378,8 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
|
||||||
|
|
||||||
switch (Sym.Info.Kind) {
|
switch (Sym.Info.Kind) {
|
||||||
case WASM_SYMBOL_TYPE_FUNCTION:
|
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:
|
case WASM_SYMBOL_TYPE_DATA:
|
||||||
return Symtab->addUndefinedData(Name, Flags, this);
|
return Symtab->addUndefinedData(Name, Flags, this);
|
||||||
case WASM_SYMBOL_TYPE_GLOBAL:
|
case WASM_SYMBOL_TYPE_GLOBAL:
|
||||||
|
@ -446,7 +447,7 @@ static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym,
|
||||||
|
|
||||||
if (ObjSym.isUndefined()) {
|
if (ObjSym.isUndefined()) {
|
||||||
if (ObjSym.isExecutable())
|
if (ObjSym.isExecutable())
|
||||||
return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr);
|
return Symtab->addUndefinedFunction(Name, kDefaultModule, Flags, &F, nullptr);
|
||||||
return Symtab->addUndefinedData(Name, Flags, &F);
|
return Symtab->addUndefinedData(Name, Flags, &F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,8 @@ BitcodeCompiler::~BitcodeCompiler() = default;
|
||||||
|
|
||||||
static void undefine(Symbol *S) {
|
static void undefine(Symbol *S) {
|
||||||
if (auto F = dyn_cast<DefinedFunction>(S))
|
if (auto F = dyn_cast<DefinedFunction>(S))
|
||||||
replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
|
replaceSymbol<UndefinedFunction>(F, F->getName(), kDefaultModule, 0,
|
||||||
F->Signature);
|
F->getFile(), F->Signature);
|
||||||
else if (isa<DefinedData>(S))
|
else if (isa<DefinedData>(S))
|
||||||
replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
|
replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
|
||||||
else
|
else
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "lld/Common/LLVM.h"
|
#include "lld/Common/LLVM.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
#include "Writer.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
|
@ -315,8 +315,8 @@ Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
|
Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef Module,
|
||||||
InputFile *File,
|
uint32_t Flags, InputFile *File,
|
||||||
const WasmSignature *Sig) {
|
const WasmSignature *Sig) {
|
||||||
LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
|
LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
|
||||||
" [" << (Sig ? toString(*Sig) : "none") << "]\n");
|
" [" << (Sig ? toString(*Sig) : "none") << "]\n");
|
||||||
|
@ -326,7 +326,7 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
|
||||||
std::tie(S, WasInserted) = insert(Name, File);
|
std::tie(S, WasInserted) = insert(Name, File);
|
||||||
|
|
||||||
if (WasInserted)
|
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))
|
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
|
||||||
Lazy->fetch();
|
Lazy->fetch();
|
||||||
else
|
else
|
||||||
|
|
|
@ -58,8 +58,8 @@ public:
|
||||||
Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
|
Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
|
||||||
InputEvent *E);
|
InputEvent *E);
|
||||||
|
|
||||||
Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
|
Symbol *addUndefinedFunction(StringRef Name, StringRef Module, uint32_t Flags,
|
||||||
const WasmSignature *Signature);
|
InputFile *File, const WasmSignature *Signature);
|
||||||
Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File);
|
Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File);
|
||||||
Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
|
Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
|
||||||
const WasmGlobalType *Type);
|
const WasmGlobalType *Type);
|
||||||
|
|
|
@ -155,13 +155,17 @@ public:
|
||||||
|
|
||||||
class UndefinedFunction : public FunctionSymbol {
|
class UndefinedFunction : public FunctionSymbol {
|
||||||
public:
|
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)
|
const WasmSignature *Type = nullptr)
|
||||||
: FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {}
|
: FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type),
|
||||||
|
Module(Module) {}
|
||||||
|
|
||||||
static bool classof(const Symbol *S) {
|
static bool classof(const Symbol *S) {
|
||||||
return S->kind() == UndefinedFunctionKind;
|
return S->kind() == UndefinedFunctionKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringRef Module;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SectionSymbol : public Symbol {
|
class SectionSymbol : public Symbol {
|
||||||
|
|
|
@ -41,6 +41,7 @@ using namespace lld::wasm;
|
||||||
|
|
||||||
static constexpr int kStackAlignment = 16;
|
static constexpr int kStackAlignment = 16;
|
||||||
static constexpr const char *kFunctionTableName = "__indirect_function_table";
|
static constexpr const char *kFunctionTableName = "__indirect_function_table";
|
||||||
|
const char *lld::wasm::kDefaultModule = "env";
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ void Writer::createImportSection() {
|
||||||
|
|
||||||
if (Config->ImportMemory) {
|
if (Config->ImportMemory) {
|
||||||
WasmImport Import;
|
WasmImport Import;
|
||||||
Import.Module = "env";
|
Import.Module = kDefaultModule;
|
||||||
Import.Field = "memory";
|
Import.Field = "memory";
|
||||||
Import.Kind = WASM_EXTERNAL_MEMORY;
|
Import.Kind = WASM_EXTERNAL_MEMORY;
|
||||||
Import.Memory.Flags = 0;
|
Import.Memory.Flags = 0;
|
||||||
|
@ -173,7 +174,7 @@ void Writer::createImportSection() {
|
||||||
if (Config->ImportTable) {
|
if (Config->ImportTable) {
|
||||||
uint32_t TableSize = TableBase + IndirectFunctions.size();
|
uint32_t TableSize = TableBase + IndirectFunctions.size();
|
||||||
WasmImport Import;
|
WasmImport Import;
|
||||||
Import.Module = "env";
|
Import.Module = kDefaultModule;
|
||||||
Import.Field = kFunctionTableName;
|
Import.Field = kFunctionTableName;
|
||||||
Import.Kind = WASM_EXTERNAL_TABLE;
|
Import.Kind = WASM_EXTERNAL_TABLE;
|
||||||
Import.Table.ElemType = WASM_TYPE_FUNCREF;
|
Import.Table.ElemType = WASM_TYPE_FUNCREF;
|
||||||
|
@ -183,7 +184,11 @@ void Writer::createImportSection() {
|
||||||
|
|
||||||
for (const Symbol *Sym : ImportedSymbols) {
|
for (const Symbol *Sym : ImportedSymbols) {
|
||||||
WasmImport Import;
|
WasmImport Import;
|
||||||
Import.Module = "env";
|
if (auto *F = dyn_cast<UndefinedFunction>(Sym))
|
||||||
|
Import.Module = F->Module;
|
||||||
|
else
|
||||||
|
Import.Module = kDefaultModule;
|
||||||
|
|
||||||
Import.Field = Sym->getName();
|
Import.Field = Sym->getName();
|
||||||
if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
|
if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
|
||||||
Import.Kind = WASM_EXTERNAL_FUNCTION;
|
Import.Kind = WASM_EXTERNAL_FUNCTION;
|
||||||
|
|
|
@ -14,6 +14,8 @@ namespace wasm {
|
||||||
|
|
||||||
void writeResult();
|
void writeResult();
|
||||||
|
|
||||||
|
extern const char *kDefaultModule;
|
||||||
|
|
||||||
} // namespace wasm
|
} // namespace wasm
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue