[lld] r322145 - [WebAssembly] Refactor symbol and symbol table to remove WasmSymbol references

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 9 16:52:21 PST 2018


Author: sbc
Date: Tue Jan  9 16:52:20 2018
New Revision: 322145

URL: http://llvm.org/viewvc/llvm-project?rev=322145&view=rev
Log:
[WebAssembly] Refactor symbol and symbol table to remove WasmSymbol references

This WasmSymbol types comes directly from the input objects
but we want to be able to represent synthetic symbols too.

This is more in line with how the ELF linker represents symbols.

This change also removes the logic from Symbol::getVirtualAddress
for finding the global address and instead has the InputFile
provide this.

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

Modified:
    lld/trunk/wasm/InputFiles.cpp
    lld/trunk/wasm/InputFiles.h
    lld/trunk/wasm/SymbolTable.cpp
    lld/trunk/wasm/SymbolTable.h
    lld/trunk/wasm/Symbols.cpp
    lld/trunk/wasm/Symbols.h

Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=322145&r1=322144&r2=322145&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Tue Jan  9 16:52:20 2018
@@ -134,6 +134,15 @@ static void copyRelocationsRange(std::ve
       To.push_back(R);
 }
 
+// Get the value stored in the wasm global represented by this symbol.
+// This represents the virtual address of the symbol in the input file.
+uint32_t ObjFile::getGlobalValue(const WasmSymbol &Sym) const {
+  const WasmGlobal &Global =
+      getWasmObj()->globals()[Sym.ElementIndex - NumGlobalImports];
+  assert(Global.Type == llvm::wasm::WASM_TYPE_I32);
+  return Global.InitExpr.Value.Int32;
+}
+
 // Get the signature for a given function symbol, either by looking
 // it up in function sections (for defined functions), of the imports section
 // (for imported functions).
@@ -190,16 +199,19 @@ void ObjFile::initializeSymbols() {
     Symbol *S;
     switch (WasmSym.Type) {
     case WasmSymbol::SymbolType::FUNCTION_IMPORT:
-      S = createUndefined(WasmSym, getFunctionSig(WasmSym));
+      S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind,
+                          getFunctionSig(WasmSym));
       break;
     case WasmSymbol::SymbolType::GLOBAL_IMPORT:
-      S = createUndefined(WasmSym);
+      S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind);
       break;
     case WasmSymbol::SymbolType::GLOBAL_EXPORT:
-      S = createDefined(WasmSym, getSegment(WasmSym), nullptr);
+      S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind,
+                        getSegment(WasmSym), nullptr, getGlobalValue(WasmSym));
       break;
     case WasmSymbol::SymbolType::FUNCTION_EXPORT:
-      S = createDefined(WasmSym, nullptr, getFunction(WasmSym));
+      S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, nullptr,
+                        getFunction(WasmSym));
       break;
     case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
       // These are for debugging only, no need to create linker symbols for them
@@ -249,28 +261,22 @@ void ObjFile::initializeSymbols() {
   DEBUG(dbgs() << "Globals     : " << GlobalSymbols.size() << "\n");
 }
 
-Symbol *ObjFile::createUndefined(const WasmSymbol &Sym,
+Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
                                  const WasmSignature *Signature) {
-  return Symtab->addUndefined(this, &Sym, Signature);
+  return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this, Signature);
 }
 
-Symbol *ObjFile::createDefined(const WasmSymbol &Sym,
+Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
                                const InputSegment *Segment,
-                               InputFunction *Function) {
+                               InputFunction *Function, uint32_t Address) {
   Symbol *S;
   if (Sym.isLocal()) {
     S = make<Symbol>(Sym.Name, true);
-    Symbol::Kind Kind;
-    if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT)
-      Kind = Symbol::Kind::DefinedFunctionKind;
-    else if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT)
-      Kind = Symbol::Kind::DefinedGlobalKind;
-    else
-      llvm_unreachable("invalid local symbol type");
-    S->update(Kind, this, &Sym, Segment, Function);
+    S->update(Kind, this, Sym.Flags, Segment, Function, Address);
     return S;
   }
-  return Symtab->addDefined(this, &Sym, Segment, Function);
+  return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Segment, Function,
+                            Address);
 }
 
 void ArchiveFile::parse() {

Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=322145&r1=322144&r2=322145&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Tue Jan  9 16:52:20 2018
@@ -17,6 +17,7 @@
 #include "llvm/Object/Wasm.h"
 #include "llvm/Support/MemoryBuffer.h"
 
+#include "Symbols.h"
 #include "WriterUtils.h"
 
 #include <vector>
@@ -31,7 +32,6 @@ using llvm::wasm::WasmSignature;
 namespace lld {
 namespace wasm {
 
-class Symbol;
 class InputFunction;
 class InputSegment;
 
@@ -97,8 +97,6 @@ public:
   uint32_t relocateTableIndex(uint32_t Original) const;
   uint32_t getRelocatedAddress(uint32_t Index) const;
 
-  size_t getNumGlobalImports() const { return NumGlobalImports; }
-
   const WasmSection *CodeSection = nullptr;
 
   std::vector<uint32_t> TypeMap;
@@ -109,14 +107,16 @@ public:
   ArrayRef<Symbol *> getTableSymbols() { return TableSymbols; }
 
 private:
-  Symbol *createDefined(const WasmSymbol &Sym,
+  Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
                         const InputSegment *Segment = nullptr,
-                        InputFunction *Function = nullptr);
-  Symbol *createUndefined(const WasmSymbol &Sym,
+                        InputFunction *Function = nullptr,
+                        uint32_t Address = UINT32_MAX);
+  Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
                           const WasmSignature *Signature = nullptr);
   void initializeSymbols();
   InputSegment *getSegment(const WasmSymbol &WasmSym) const;
   const WasmSignature *getFunctionSig(const WasmSymbol &Sym) const;
+  uint32_t getGlobalValue(const WasmSymbol &Sym) const;
   InputFunction *getFunction(const WasmSymbol &Sym) const;
 
   // List of all symbols referenced or defined by this file.

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=322145&r1=322144&r2=322145&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Tue Jan  9 16:52:20 2018
@@ -20,6 +20,7 @@
 #define DEBUG_TYPE "lld"
 
 using namespace llvm;
+using namespace llvm::wasm;
 using namespace lld;
 using namespace lld::wasm;
 
@@ -80,18 +81,17 @@ void SymbolTable::reportDuplicate(Symbol
 // Check the type of new symbol matches that of the symbol is replacing.
 // For functions this can also involve verifying that the signatures match.
 static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
-                             const WasmSymbol &New,
-                             const WasmSignature *NewSig) {
+                             Symbol::Kind Kind, const WasmSignature *NewSig) {
   if (Existing.isLazy())
     return;
 
-  bool NewIsFunction = New.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT ||
-                       New.Type == WasmSymbol::SymbolType::FUNCTION_IMPORT;
+  bool NewIsFunction = Kind == Symbol::Kind::UndefinedFunctionKind ||
+                       Kind == Symbol::Kind::DefinedFunctionKind;
 
   // First check the symbol types match (i.e. either both are function
   // symbols or both are data symbols).
   if (Existing.isFunction() != NewIsFunction) {
-    error("symbol type mismatch: " + New.Name + "\n>>> defined as " +
+    error("symbol type mismatch: " + Existing.getName() + "\n>>> defined as " +
           (Existing.isFunction() ? "Function" : "Global") + " in " +
           toString(Existing.getFile()) + "\n>>> defined as " +
           (NewIsFunction ? "Function" : "Global") + " in " + F.getName());
@@ -106,16 +106,17 @@ static void checkSymbolTypes(const Symbo
   if (!Existing.hasFunctionType())
     return;
 
-  DEBUG(dbgs() << "checkSymbolTypes: " << New.Name << "\n");
+  DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() << "\n");
   assert(NewSig);
 
   const WasmSignature &OldSig = Existing.getFunctionType();
   if (*NewSig == OldSig)
     return;
 
-  error("function signature mismatch: " + New.Name + "\n>>> defined as " +
-        toString(OldSig) + " in " + toString(Existing.getFile()) +
-        "\n>>> defined as " + toString(*NewSig) + " in " + F.getName());
+  error("function signature mismatch: " + Existing.getName() +
+        "\n>>> defined as " + toString(OldSig) + " in " +
+        toString(Existing.getFile()) + "\n>>> defined as " + toString(*NewSig) +
+        " in " + F.getName());
 }
 
 Symbol *SymbolTable::addDefinedGlobal(StringRef Name) {
@@ -130,40 +131,37 @@ Symbol *SymbolTable::addDefinedGlobal(St
   return S;
 }
 
-Symbol *SymbolTable::addDefined(InputFile *F, const WasmSymbol *Sym,
+Symbol *SymbolTable::addDefined(StringRef Name, Symbol::Kind Kind,
+                                uint32_t Flags, InputFile *F,
                                 const InputSegment *Segment,
-                                InputFunction *Function) {
-  DEBUG(dbgs() << "addDefined: " << Sym->Name << "\n");
+                                InputFunction *Function, uint32_t Address) {
+  DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address << "\n");
   Symbol *S;
   bool WasInserted;
-  Symbol::Kind Kind = Symbol::DefinedFunctionKind;
-  if (Sym->Type == WasmSymbol::SymbolType::GLOBAL_EXPORT)
-    Kind = Symbol::DefinedGlobalKind;
 
-  std::tie(S, WasInserted) = insert(Sym->Name);
+  std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
-    S->update(Kind, F, Sym, Segment, Function);
+    S->update(Kind, F, Flags, Segment, Function, Address);
   } else if (S->isLazy()) {
     // The existing symbol is lazy. Replace it without checking types since
     // lazy symbols don't have any type information.
-    DEBUG(dbgs() << "replacing existing lazy symbol: " << Sym->Name << "\n");
-    S->update(Kind, F, Sym, Segment, Function);
+    DEBUG(dbgs() << "replacing existing lazy symbol: " << Name << "\n");
+    S->update(Kind, F, Flags, Segment, Function, Address);
   } else if (!S->isDefined()) {
     // The existing symbol table entry is undefined. The new symbol replaces
     // it, after checking the type matches
-    DEBUG(dbgs() << "resolving existing undefined symbol: " << Sym->Name
-                 << "\n");
-    checkSymbolTypes(*S, *F, *Sym, Function ? &Function->Signature : nullptr);
-    S->update(Kind, F, Sym, Segment, Function);
-  } else if (Sym->isWeak()) {
+    DEBUG(dbgs() << "resolving existing undefined symbol: " << Name << "\n");
+    checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr);
+    S->update(Kind, F, Flags, Segment, Function, Address);
+  } else if ((Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
     // the new symbol is weak we can ignore it
     DEBUG(dbgs() << "existing symbol takes precedence\n");
   } else if (S->isWeak()) {
     // the new symbol is not weak and the existing symbol is, so we replace
     // it
     DEBUG(dbgs() << "replacing existing weak symbol\n");
-    checkSymbolTypes(*S, *F, *Sym, Function ? &Function->Signature : nullptr);
-    S->update(Kind, F, Sym, Segment, Function);
+    checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr);
+    S->update(Kind, F, Flags, Segment, Function, Address);
   } else {
     // neither symbol is week. They conflict.
     reportDuplicate(S, F);
@@ -185,17 +183,15 @@ Symbol *SymbolTable::addUndefinedFunctio
   return S;
 }
 
-Symbol *SymbolTable::addUndefined(InputFile *F, const WasmSymbol *Sym,
+Symbol *SymbolTable::addUndefined(StringRef Name, Symbol::Kind Kind,
+                                  uint32_t Flags, InputFile *F,
                                   const WasmSignature *Type) {
-  DEBUG(dbgs() << "addUndefined: " << Sym->Name << "\n");
+  DEBUG(dbgs() << "addUndefined: " << Name << "\n");
   Symbol *S;
   bool WasInserted;
-  Symbol::Kind Kind = Symbol::UndefinedFunctionKind;
-  if (Sym->Type == WasmSymbol::SymbolType::GLOBAL_IMPORT)
-    Kind = Symbol::UndefinedGlobalKind;
-  std::tie(S, WasInserted) = insert(Sym->Name);
+  std::tie(S, WasInserted) = insert(Name);
   if (WasInserted) {
-    S->update(Kind, F, Sym);
+    S->update(Kind, F, Flags);
     if (Type)
       S->setFunctionType(Type);
   } else if (S->isLazy()) {
@@ -204,7 +200,7 @@ Symbol *SymbolTable::addUndefined(InputF
     AF->addMember(&S->getArchiveSymbol());
   } else if (S->isDefined()) {
     DEBUG(dbgs() << "resolved by existing\n");
-    checkSymbolTypes(*S, *F, *Sym, Type);
+    checkSymbolTypes(*S, *F, Kind, Type);
   }
   return S;
 }

Modified: lld/trunk/wasm/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=322145&r1=322144&r2=322145&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.h (original)
+++ lld/trunk/wasm/SymbolTable.h Tue Jan  9 16:52:20 2018
@@ -17,7 +17,6 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/raw_ostream.h"
 
-using llvm::object::WasmSymbol;
 using llvm::wasm::WasmSignature;
 
 namespace lld {
@@ -49,11 +48,11 @@ public:
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
   Symbol *find(StringRef Name);
 
-  Symbol *addDefined(InputFile *F, const WasmSymbol *Sym,
-                     const InputSegment *Segment = nullptr,
-                     InputFunction *Function = nullptr);
-  Symbol *addUndefined(InputFile *F, const WasmSymbol *Sym,
-                       const WasmSignature *Signature = nullptr);
+  Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
+                     InputFile *F, const InputSegment *Segment = nullptr,
+                     InputFunction *Function = nullptr, uint32_t Address = 0);
+  Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
+                       InputFile *F, const WasmSignature *Signature = nullptr);
   Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type);
   Symbol *addDefinedGlobal(StringRef Name);
   void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=322145&r1=322144&r2=322145&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Tue Jan  9 16:52:20 2018
@@ -19,6 +19,7 @@
 #define DEBUG_TYPE "lld"
 
 using namespace llvm;
+using namespace llvm::wasm;
 using namespace lld;
 using namespace lld::wasm;
 
@@ -39,19 +40,7 @@ void Symbol::setFunctionType(const WasmS
 uint32_t Symbol::getVirtualAddress() const {
   assert(isGlobal());
   DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
-  if (isUndefined())
-    return 0;
-  if (VirtualAddress.hasValue())
-    return VirtualAddress.getValue();
-
-  ObjFile *Obj = cast<ObjFile>(File);
-  assert(Sym != nullptr);
-  const WasmGlobal &Global =
-      Obj->getWasmObj()
-          ->globals()[Sym->ElementIndex - Obj->getNumGlobalImports()];
-  assert(Global.Type == llvm::wasm::WASM_TYPE_I32);
-  assert(Segment);
-  return Segment->translateVA(Global.InitExpr.Value.Int32);
+  return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress;
 }
 
 bool Symbol::hasOutputIndex() const {
@@ -68,7 +57,7 @@ uint32_t Symbol::getOutputIndex() const
 
 void Symbol::setVirtualAddress(uint32_t Value) {
   DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
-  assert(!VirtualAddress.hasValue());
+  assert(isGlobal());
   VirtualAddress = Value;
 }
 
@@ -85,18 +74,29 @@ void Symbol::setTableIndex(uint32_t Inde
   TableIndex = Index;
 }
 
-void Symbol::update(Kind K, InputFile *F, const WasmSymbol *WasmSym,
-                    const InputSegment *Seg, const InputFunction *Func) {
+void Symbol::update(Kind K, InputFile *F, uint32_t Flags_,
+                    const InputSegment *Seg, const InputFunction *Func,
+                    uint32_t Address) {
   SymbolKind = K;
   File = F;
-  Sym = WasmSym;
+  Flags = Flags_;
   Segment = Seg;
   Function = Func;
+  if (Address != UINT32_MAX)
+    setVirtualAddress(Address);
 }
 
-bool Symbol::isWeak() const { return Sym && Sym->isWeak(); }
+bool Symbol::isWeak() const {
+  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
+}
 
-bool Symbol::isHidden() const { return Sym && Sym->isHidden(); }
+bool Symbol::isLocal() const {
+  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
+}
+
+bool Symbol::isHidden() const {
+  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
+}
 
 std::string lld::toString(const wasm::Symbol &Sym) {
   if (Config->Demangle)

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=322145&r1=322144&r2=322145&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Tue Jan  9 16:52:20 2018
@@ -15,9 +15,6 @@
 #include "llvm/Object/Wasm.h"
 
 using llvm::object::Archive;
-using llvm::object::WasmSymbol;
-using llvm::wasm::WasmExport;
-using llvm::wasm::WasmImport;
 using llvm::wasm::WasmSignature;
 
 namespace lld {
@@ -41,8 +38,8 @@ public:
     InvalidKind,
   };
 
-  Symbol(StringRef Name, bool IsLocal)
-      : WrittenToSymtab(0), WrittenToNameSec(0), IsLocal(IsLocal), Name(Name) {}
+  Symbol(StringRef Name, uint32_t Flags)
+      : WrittenToSymtab(0), WrittenToNameSec(0), Flags(Flags), Name(Name) {}
 
   Kind getKind() const { return SymbolKind; }
 
@@ -57,7 +54,7 @@ public:
            SymbolKind == UndefinedFunctionKind;
   }
   bool isGlobal() const { return !isFunction(); }
-  bool isLocal() const { return IsLocal; }
+  bool isLocal() const;
   bool isWeak() const;
   bool isHidden() const;
 
@@ -94,9 +91,10 @@ public:
 
   void setVirtualAddress(uint32_t VA);
 
-  void update(Kind K, InputFile *F = nullptr, const WasmSymbol *Sym = nullptr,
+  void update(Kind K, InputFile *F = nullptr, uint32_t Flags = 0,
               const InputSegment *Segment = nullptr,
-              const InputFunction *Function = nullptr);
+              const InputFunction *Function = nullptr,
+              uint32_t Address = UINT32_MAX);
 
   void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; }
   const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; }
@@ -107,18 +105,17 @@ public:
   unsigned WrittenToNameSec : 1;
 
 protected:
-  unsigned IsLocal : 1;
+  uint32_t Flags;
+  uint32_t VirtualAddress = 0;
 
   StringRef Name;
   Archive::Symbol ArchiveSymbol = {nullptr, 0, 0};
   Kind SymbolKind = InvalidKind;
   InputFile *File = nullptr;
-  const WasmSymbol *Sym = nullptr;
   const InputSegment *Segment = nullptr;
   const InputFunction *Function = nullptr;
   llvm::Optional<uint32_t> OutputIndex;
   llvm::Optional<uint32_t> TableIndex;
-  llvm::Optional<uint32_t> VirtualAddress;
   const WasmSignature *FunctionType = nullptr;
 };
 




More information about the llvm-commits mailing list