[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:
Sam Clegg 2019-02-01 02:29:57 +00:00
parent 13680223b9
commit 7cc0753118
9 changed files with 48 additions and 14 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -80,8 +80,8 @@ BitcodeCompiler::~BitcodeCompiler() = default;
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

View File

@ -22,6 +22,7 @@
#include "lld/Common/LLVM.h"
#include "llvm/ADT/SmallString.h"
#include "Writer.h"
#include <memory>
#include <vector>

View File

@ -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<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

View File

@ -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);

View File

@ -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 {

View File

@ -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<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;

View File

@ -14,6 +14,8 @@ namespace wasm {
void writeResult();
extern const char *kDefaultModule;
} // namespace wasm
} // namespace lld