[lld] r324157 - [WebAssembly] Refactor linker-generated symbols. NFC.

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 2 14:59:56 PST 2018


Author: sbc
Date: Fri Feb  2 14:59:56 2018
New Revision: 324157

URL: http://llvm.org/viewvc/llvm-project?rev=324157&view=rev
Log:
[WebAssembly] Refactor linker-generated symbols. NFC.

Group all synthetic symbols in the in single struct to match
the ELF linker.

This change is part of a larger change to add more linker
symbols such as `_end` and `_edata`.

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

Modified:
    lld/trunk/wasm/Config.h
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/MarkLive.cpp
    lld/trunk/wasm/Symbols.cpp
    lld/trunk/wasm/Symbols.h
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/wasm/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Config.h?rev=324157&r1=324156&r2=324157&view=diff
==============================================================================
--- lld/trunk/wasm/Config.h (original)
+++ lld/trunk/wasm/Config.h Fri Feb  2 14:59:56 2018
@@ -38,9 +38,6 @@ struct Configuration {
 
   llvm::StringSet<> AllowUndefinedSymbols;
   std::vector<llvm::StringRef> SearchPaths;
-  Symbol *StackPointerSymbol = nullptr;
-  Symbol *HeapBaseSymbol = nullptr;
-  Symbol *CtorSymbol = nullptr;
 };
 
 // The only instance of Configuration struct.

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=324157&r1=324156&r2=324157&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Fri Feb  2 14:59:56 2018
@@ -299,20 +299,11 @@ void LinkerDriver::link(ArrayRef<const c
     // Handle the `--undefined <sym>` options.
     for (auto* Arg : Args.filtered(OPT_undefined))
       Symtab->addUndefinedFunction(Arg->getValue(), nullptr);
-
-    // Create linker-synthetic symbols
-    // __wasm_call_ctors:
-    //    Function that directly calls all ctors in priority order.
-    // __stack_pointer:
-    //    Wasm global that holds the address of the top of the explict
-    //    value stack in linear memory.
-    // __dso_handle;
-    //    Global in calls to __cxa_atexit to determine current DLL
-    Config->CtorSymbol = Symtab->addDefinedFunction(
+    WasmSym::CallCtors = Symtab->addDefinedFunction(
         "__wasm_call_ctors", &Signature, WASM_SYMBOL_VISIBILITY_HIDDEN);
-    Config->StackPointerSymbol = Symtab->addDefinedGlobal("__stack_pointer");
-    Config->HeapBaseSymbol = Symtab->addDefinedGlobal("__heap_base");
-    Symtab->addDefinedGlobal("__dso_handle")->setVirtualAddress(0);
+    WasmSym::StackPointer = Symtab->addDefinedGlobal("__stack_pointer");
+    WasmSym::HeapBase = Symtab->addDefinedGlobal("__heap_base");
+    WasmSym::DsoHandle = Symtab->addDefinedGlobal("__dso_handle");
   }
 
   createFiles(Args);

Modified: lld/trunk/wasm/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/MarkLive.cpp?rev=324157&r1=324156&r2=324157&view=diff
==============================================================================
--- lld/trunk/wasm/MarkLive.cpp (original)
+++ lld/trunk/wasm/MarkLive.cpp Fri Feb  2 14:59:56 2018
@@ -52,7 +52,7 @@ void lld::wasm::markLive() {
   // Add GC root symbols.
   if (!Config->Entry.empty())
     Enqueue(Symtab->find(Config->Entry));
-  Enqueue(Config->CtorSymbol);
+  Enqueue(WasmSym::CallCtors);
 
   // By default we export all non-hidden, so they are gc roots too
   for (Symbol *Sym : Symtab->getSymbols())

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=324157&r1=324156&r2=324157&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Fri Feb  2 14:59:56 2018
@@ -22,6 +22,11 @@ using namespace llvm::wasm;
 using namespace lld;
 using namespace lld::wasm;
 
+Symbol *WasmSym::CallCtors;
+Symbol *WasmSym::DsoHandle;
+Symbol *WasmSym::HeapBase;
+Symbol *WasmSym::StackPointer;
+
 const WasmSignature &Symbol::getFunctionType() const {
   if (Chunk != nullptr)
     return dyn_cast<InputFunction>(Chunk)->Signature;

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=324157&r1=324156&r2=324157&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Fri Feb  2 14:59:56 2018
@@ -111,6 +111,25 @@ protected:
   const WasmSignature *FunctionType = nullptr;
 };
 
+// linker-generated symbols
+struct WasmSym {
+  // __stack_pointer
+  // Global that holds the address of the top of the explict  value stack
+  // in linear memory.
+  static Symbol *StackPointer;
+
+  // __heap_base
+  static Symbol *HeapBase;
+
+  // __wasm_call_ctors
+  // Function that directly calls all ctors in priority order.
+  static Symbol *CallCtors;
+
+  // __dso_handle
+  // Global used in calls to __cxa_atexit to determine current DLL
+  static Symbol *DsoHandle;
+};
+
 } // namespace wasm
 
 // Returns a symbol name for an error message.

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=324157&r1=324156&r2=324157&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Fri Feb  2 14:59:56 2018
@@ -237,7 +237,7 @@ void Writer::createGlobalSection() {
   for (const Symbol *Sym : DefinedGlobals) {
     WasmGlobal Global;
     Global.Type.Type = WASM_TYPE_I32;
-    Global.Type.Mutable = Sym == Config->StackPointerSymbol;
+    Global.Type.Mutable = Sym == WasmSym::StackPointer;
     Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
     Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
     writeGlobal(OS, Global);
@@ -520,6 +520,11 @@ void Writer::writeSections() {
 
 // Fix the memory layout of the output binary.  This assigns memory offsets
 // to each of the input data sections as well as the explicit stack region.
+// The memory layout is as follows, from low to high.
+//  - initialized data (starting at Config->GlobalBase)
+//  - BSS data (not currently implemented in llvm)
+//  - explicit stack (Config->ZStackSize)
+//  - heap start / unallocated
 void Writer::layoutMemory() {
   uint32_t MemoryPtr = 0;
   if (!Config->Relocatable) {
@@ -529,7 +534,11 @@ void Writer::layoutMemory() {
 
   createOutputSegments();
 
-  // Static data comes first
+  // Arbitrarily set __dso_handle handle to point to the start of the data
+  // segments.
+  if (WasmSym::DsoHandle)
+    WasmSym::DsoHandle->setVirtualAddress(MemoryPtr);
+
   for (OutputSegment *Seg : Segments) {
     MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
     Seg->StartVA = MemoryPtr;
@@ -538,12 +547,14 @@ void Writer::layoutMemory() {
     MemoryPtr += Seg->Size;
   }
 
+  // TODO: Add .bss space here.
+
   DataSize = MemoryPtr;
   if (!Config->Relocatable)
     DataSize -= Config->GlobalBase;
   debugPrint("mem: static data = %d\n", DataSize);
 
-  // Stack comes after static data
+  // Stack comes after static data and bss
   if (!Config->Relocatable) {
     MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
     if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
@@ -551,12 +562,12 @@ void Writer::layoutMemory() {
     debugPrint("mem: stack size  = %d\n", Config->ZStackSize);
     debugPrint("mem: stack base  = %d\n", MemoryPtr);
     MemoryPtr += Config->ZStackSize;
-    Config->StackPointerSymbol->setVirtualAddress(MemoryPtr);
+    WasmSym::StackPointer->setVirtualAddress(MemoryPtr);
     debugPrint("mem: stack top   = %d\n", MemoryPtr);
     // Set `__heap_base` to directly follow the end of the stack.  We don't
     // allocate any heap memory up front, but instead really on the malloc/brk
     // implementation growing the memory at runtime.
-    Config->HeapBaseSymbol->setVirtualAddress(MemoryPtr);
+    WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
     debugPrint("mem: heap base   = %d\n", MemoryPtr);
   }
 
@@ -619,6 +630,7 @@ void Writer::calculateImports() {
 void Writer::calculateExports() {
   bool ExportHidden = Config->Relocatable;
   StringSet<> UsedNames;
+
   auto BudgeLocalName = [&](const Symbol *Sym) {
     StringRef SymName = Sym->getName();
     // We can't budge non-local names.
@@ -638,9 +650,9 @@ void Writer::calculateExports() {
     }
   };
 
-  if (Config->CtorSymbol && (!Config->CtorSymbol->isHidden() || ExportHidden))
+  if (WasmSym::CallCtors && (!WasmSym::CallCtors->isHidden() || ExportHidden))
     ExportedSymbols.emplace_back(
-        WasmExportEntry{Config->CtorSymbol, Config->CtorSymbol->getName()});
+        WasmExportEntry{WasmSym::CallCtors, WasmSym::CallCtors->getName()});
 
   for (ObjFile *File : Symtab->ObjectFiles) {
     for (Symbol *Sym : File->getSymbols()) {
@@ -664,7 +676,7 @@ void Writer::calculateExports() {
     // Can't export the SP right now because its mutable, and mutuable globals
     // are yet supported in the official binary format.
     // TODO(sbc): Remove this if/when the "mutable global" proposal is accepted.
-    if (Sym == Config->StackPointerSymbol)
+    if (Sym == WasmSym::StackPointer)
       continue;
     ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)});
   }
@@ -712,23 +724,22 @@ void Writer::assignIndexes() {
   uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size();
   uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
 
-  if (Config->StackPointerSymbol) {
-    DefinedGlobals.emplace_back(Config->StackPointerSymbol);
-    Config->StackPointerSymbol->setOutputIndex(GlobalIndex++);
-  }
-
-  if (Config->HeapBaseSymbol) {
-    DefinedGlobals.emplace_back(Config->HeapBaseSymbol);
-    Config->HeapBaseSymbol->setOutputIndex(GlobalIndex++);
-  }
+  auto AddDefinedGlobal = [&](Symbol* Sym) {
+    if (Sym) {
+      DefinedGlobals.emplace_back(Sym);
+      Sym->setOutputIndex(GlobalIndex++);
+    }
+  };
+  AddDefinedGlobal(WasmSym::StackPointer);
+  AddDefinedGlobal(WasmSym::HeapBase);
 
   if (Config->Relocatable)
     DefinedGlobals.reserve(Symtab->getSymbols().size());
 
   uint32_t TableIndex = kInitialTableOffset;
 
-  for (ObjFile *File : Symtab->ObjectFiles) {
-    if (Config->Relocatable) {
+  if (Config->Relocatable) {
+    for (ObjFile *File : Symtab->ObjectFiles) {
       DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
       for (Symbol *Sym : File->getSymbols()) {
         // Create wasm globals for data symbols defined in this file
@@ -737,8 +748,7 @@ void Writer::assignIndexes() {
         if (Sym->isFunction())
           continue;
 
-        DefinedGlobals.emplace_back(Sym);
-        Sym->setOutputIndex(GlobalIndex++);
+        AddDefinedGlobal(Sym);
       }
     }
   }
@@ -822,7 +832,7 @@ static const int OPCODE_END = 0xb;
 // in input object.
 void Writer::createCtorFunction() {
   uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
-  Config->CtorSymbol->setOutputIndex(FunctionIndex);
+  WasmSym::CallCtors->setOutputIndex(FunctionIndex);
 
   // First write the body bytes to a string.
   std::string FunctionBody;
@@ -846,7 +856,7 @@ void Writer::createCtorFunction() {
       reinterpret_cast<const uint8_t *>(CtorFunctionBody.data()),
       CtorFunctionBody.size());
   CtorFunction = llvm::make_unique<SyntheticFunction>(
-      Signature, BodyArray, Config->CtorSymbol->getName());
+      Signature, BodyArray, WasmSym::CallCtors->getName());
   CtorFunction->setOutputIndex(FunctionIndex);
   DefinedFunctions.emplace_back(CtorFunction.get());
 }




More information about the llvm-commits mailing list