[lld] r355988 - [WebAssembly] Handle undefined data symbols in shared libraries

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 12 14:53:23 PDT 2019


Author: sbc
Date: Tue Mar 12 14:53:23 2019
New Revision: 355988

URL: http://llvm.org/viewvc/llvm-project?rev=355988&view=rev
Log:
[WebAssembly] Handle undefined data symbols in shared libraries

When linking shared libraries, we import a mutable wasm global
to represent the address of each undefined data symbol.

This is a step towards supporting dynamic linking and shared
libraries.

Differential Revision: https://reviews.llvm.org/D59270

Modified:
    lld/trunk/test/wasm/shared.ll
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/Symbols.h
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/test/wasm/shared.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/shared.ll?rev=355988&r1=355987&r2=355988&view=diff
==============================================================================
--- lld/trunk/test/wasm/shared.ll (original)
+++ lld/trunk/test/wasm/shared.ll Tue Mar 12 14:53:23 2019
@@ -5,18 +5,18 @@
 target triple = "wasm32-unknown-unknown"
 
 @data = hidden global i32 2, align 4
- at indirect_func = local_unnamed_addr global void ()* @foo, align 4
+ at indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
 @indirect_func_external = local_unnamed_addr global void ()* @func_external, align 4
 
-define default void @foo() {
+define default i32 @foo() {
 entry:
   ; To ensure we use __stack_pointer
   %ptr = alloca i32
   %0 = load i32, i32* @data, align 4
   %1 = load i32, i32* @data_external, align 4
-  %2 = load void ()*, void ()** @indirect_func, align 4
-  call void %2()
-  ret void
+  %2 = load i32 ()*, i32 ()** @indirect_func, align 4
+  call i32 %2()
+  ret i32 %1
 }
 
 declare void @func_external()
@@ -60,6 +60,15 @@ declare void @func_external()
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         GlobalType:      I32
 ; CHECK-NEXT:         GlobalMutable:   false
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           data_external
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         GlobalType:      I32
+; CHECK-NEXT:         GlobalMutable:   true
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           func_external
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         SigIndex:        1
 
 ; check for elem segment initialized with __table_base global as offset
 

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=355988&r1=355987&r2=355988&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Tue Mar 12 14:53:23 2019
@@ -331,6 +331,7 @@ static void setConfigs(opt::InputArgList
       "--thinlto-cache-policy: invalid cache policy");
   Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
   errorHandler().Verbose = Args.hasArg(OPT_verbose);
+  LLVM_DEBUG(errorHandler().Verbose = true);
   ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
 
   Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0);

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=355988&r1=355987&r2=355988&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Tue Mar 12 14:53:23 2019
@@ -249,6 +249,21 @@ public:
   static bool classof(const Symbol *S) {
     return S->kind() == UndefinedDataKind;
   }
+
+  // Undefined data symbols are imported as wasm globals so also have a global
+  // index.
+  uint32_t getGlobalIndex() const {
+    assert(GlobalIndex != INVALID_INDEX);
+    return GlobalIndex;
+  }
+  void setGlobalIndex(uint32_t Index) {
+    assert(GlobalIndex == INVALID_INDEX);
+    GlobalIndex = Index;
+  }
+  bool hasGlobalIndex() const { return GlobalIndex != INVALID_INDEX; }
+
+protected:
+  uint32_t GlobalIndex = INVALID_INDEX;
 };
 
 class GlobalSymbol : public Symbol {

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=355988&r1=355987&r2=355988&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Tue Mar 12 14:53:23 2019
@@ -198,6 +198,9 @@ void Writer::createImportSection() {
     if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
       Import.Kind = WASM_EXTERNAL_FUNCTION;
       Import.SigIndex = lookupType(*FunctionSym->Signature);
+    } else if (auto *DataSym = dyn_cast<UndefinedData>(Sym)) {
+      Import.Kind = WASM_EXTERNAL_GLOBAL;
+      Import.Global = {WASM_TYPE_I32, true};
     } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) {
       Import.Kind = WASM_EXTERNAL_GLOBAL;
       Import.Global = *GlobalSym->getGlobalType();
@@ -851,14 +854,16 @@ void Writer::calculateImports() {
   for (Symbol *Sym : Symtab->getSymbols()) {
     if (!Sym->isUndefined())
       continue;
-    if (isa<DataSymbol>(Sym))
-      continue;
     if (Sym->isWeak() && !Config->Relocatable)
       continue;
     if (!Sym->isLive())
       continue;
     if (!Sym->IsUsedInRegularObj)
       continue;
+    // In relocatable output we don't generate imports for data symbols.
+    // These live only in the symbol table.
+    if (Config->Relocatable && isa<DataSymbol>(Sym))
+      continue;
 
     LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
     ImportedSymbols.emplace_back(Sym);
@@ -866,6 +871,8 @@ void Writer::calculateImports() {
       F->setFunctionIndex(NumImportedFunctions++);
     else if (auto *G = dyn_cast<GlobalSymbol>(Sym))
       G->setGlobalIndex(NumImportedGlobals++);
+    else if (auto *D = dyn_cast<UndefinedData>(Sym))
+      D->setGlobalIndex(NumImportedGlobals++);
     else
       cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++);
   }




More information about the llvm-commits mailing list