[WebAssembly] Support imports from custom module names
authorSam Clegg <sbc@chromium.org>
Fri, 1 Feb 2019 02:29:57 +0000 (02:29 +0000)
committerSam Clegg <sbc@chromium.org>
Fri, 1 Feb 2019 02:29:57 +0000 (02:29 +0000)
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

lld/test/wasm/import-module.ll [new file with mode: 0644]
lld/wasm/InputFiles.cpp
lld/wasm/LTO.cpp
lld/wasm/LTO.h
lld/wasm/SymbolTable.cpp
lld/wasm/SymbolTable.h
lld/wasm/Symbols.h
lld/wasm/Writer.cpp
lld/wasm/Writer.h

diff --git a/lld/test/wasm/import-module.ll b/lld/test/wasm/import-module.ll
new file mode 100644 (file)
index 0000000..9a47319
--- /dev/null
@@ -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 19018d2..95aa268 100644 (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);
   }
 
index 584893d..0e76dc2 100644 (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
index 57a2734..37fea7a 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "lld/Common/LLVM.h"
 #include "llvm/ADT/SmallString.h"
+#include "Writer.h"
 #include <memory>
 #include <vector>
 
index f490d4c..e45dc6b 100644 (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
index b721984..f0bdd6c 100644 (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);
index 63c0239..652d0a9 100644 (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 {
index d8986c8..a1b4097 100644 (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;
index d83e4cb..cf3681d 100644 (file)
@@ -14,6 +14,8 @@ namespace wasm {
 
 void writeResult();
 
+extern const char *kDefaultModule;
+
 } // namespace wasm
 } // namespace lld