[lld] r320001 - [WebAssembly] Fix symbol exports under -r/--relocatable

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 6 17:51:24 PST 2017


Author: sbc
Date: Wed Dec  6 17:51:24 2017
New Revision: 320001

URL: http://llvm.org/viewvc/llvm-project?rev=320001&view=rev
Log:
[WebAssembly] Fix symbol exports under -r/--relocatable

This change cleans up the way wasm exports and globals
are generated, particualrly for -r/--relocatable where
globals need to be created and exported in order for
output relocations which reference them.

Remove the need for a per file GlobalIndexOffset and
instead set the output index for each symbol directly.
This simplifies the code in several places.

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

Modified:
    lld/trunk/test/wasm/data-layout.ll
    lld/trunk/test/wasm/relocatable.ll
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/InputFiles.cpp
    lld/trunk/wasm/InputFiles.h
    lld/trunk/wasm/OutputSections.cpp
    lld/trunk/wasm/SymbolTable.cpp
    lld/trunk/wasm/SymbolTable.h
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/test/wasm/data-layout.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/data-layout.ll?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/test/wasm/data-layout.ll (original)
+++ lld/trunk/test/wasm/data-layout.ll Wed Dec  6 17:51:24 2017
@@ -23,27 +23,27 @@ target triple = "wasm32-unknown-unknown-
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           1024
+; CHECK-NEXT:           Value:           1052
 ; CHECK-NEXT:       - Type:            I32
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           1040
+; CHECK-NEXT:           Value:           1024
 ; CHECK-NEXT:       - Type:            I32
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           1048
+; CHECK-NEXT:           Value:           1040
 ; CHECK-NEXT:       - Type:            I32
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           1052
+; CHECK-NEXT:           Value:           1048
 
 ; CHECK:       - Type:            DATA
 ; CHECK-NEXT:     Relocations:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
-; CHECK-NEXT:         Index:           4
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000001F
 ; CHECK-NEXT:     Segments:
 ; CHECK-NEXT:       - SectionOffset:   7

Modified: lld/trunk/test/wasm/relocatable.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/relocatable.ll?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/test/wasm/relocatable.ll (original)
+++ lld/trunk/test/wasm/relocatable.ll Wed Dec  6 17:51:24 2017
@@ -93,6 +93,18 @@ declare i32 @foo_import() local_unnamed_
 ; CHECK-NEXT:       - Name:            my_func
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           3
+; CHECK-NEXT:       - Name:            hello_str
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:       - Name:            func_addr1
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            func_addr2
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           3
+; CHECK-NEXT:       - Name:            data_addr1
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           4
 ; CHECK-NEXT:   - Type:            ELEM
 ; CHECK-NEXT:     Segments:        
 ; CHECK-NEXT:       - Offset:          

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Wed Dec  6 17:51:24 2017
@@ -142,7 +142,6 @@ static Symbol* addSyntheticGlobal(String
   log("injecting global: " + Name);
   Symbol *S = Symtab->addDefinedGlobal(Name);
   S->setVirtualAddress(Value);
-  S->setOutputIndex(Config->SyntheticGlobals.size());
   Config->SyntheticGlobals.emplace_back(S);
   return S;
 }

Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Wed Dec  6 17:51:24 2017
@@ -47,7 +47,6 @@ void ObjFile::dumpInfo() const {
       "        FunctionIndexOffset : " + Twine(FunctionIndexOffset) + "\n" +
       "         NumFunctionImports : " + Twine(NumFunctionImports()) + "\n" +
       "           TableIndexOffset : " + Twine(TableIndexOffset) + "\n" +
-      "          GlobalIndexOffset : " + Twine(GlobalIndexOffset) + "\n" +
       "           NumGlobalImports : " + Twine(NumGlobalImports()) + "\n");
 }
 
@@ -68,15 +67,10 @@ uint32_t ObjFile::getRelocatedAddress(ui
 }
 
 uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
-  DEBUG(dbgs() << "relocateFunctionIndex: " << Original);
   const Symbol *Sym = getFunctionSymbol(Original);
-  uint32_t Index;
-  if (Sym)
-    Index = Sym->getOutputIndex();
-  else
-    Index = Original + FunctionIndexOffset;
-
-  DEBUG(dbgs() << " -> " << Index << "\n");
+  uint32_t Index = Sym->getOutputIndex();
+  DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
+               << Original << " -> " << Index << "\n");
   return Index;
 }
 
@@ -89,15 +83,10 @@ uint32_t ObjFile::relocateTableIndex(uin
 }
 
 uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
-  DEBUG(dbgs() << "relocateGlobalIndex: " << Original);
-  uint32_t Index;
   const Symbol *Sym = getGlobalSymbol(Original);
-  if (Sym)
-    Index = Sym->getOutputIndex();
-  else
-    Index = Original + GlobalIndexOffset;
-
-  DEBUG(dbgs() << " -> " << Index << "\n");
+  uint32_t Index = Sym->getOutputIndex();
+  DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
+               << " -> " << Index << "\n");
   return Index;
 }
 

Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Wed Dec  6 17:51:24 2017
@@ -103,7 +103,6 @@ public:
   size_t NumGlobalImports() const { return GlobalImports; }
 
   int32_t FunctionIndexOffset = 0;
-  int32_t GlobalIndexOffset = 0;
   int32_t TableIndexOffset = 0;
   const WasmSection *CodeSection = nullptr;
   std::vector<OutputRelocation> CodeRelocations;

Modified: lld/trunk/wasm/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSections.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSections.cpp (original)
+++ lld/trunk/wasm/OutputSections.cpp Wed Dec  6 17:51:24 2017
@@ -72,9 +72,8 @@ std::string lld::toString(OutputSection
 
 static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) {
   DEBUG(dbgs() << "write reloc: type=" << Reloc.Reloc.Type
-               << " index=" << Reloc.Reloc.Index << " new=" << Reloc.NewIndex
-               << " value=" << Reloc.Value << " offset=" << Reloc.Reloc.Offset
-               << "\n");
+               << " index=" << Reloc.Reloc.Index << " value=" << Reloc.Value
+               << " offset=" << Reloc.Reloc.Offset << "\n");
   Buf += Reloc.Reloc.Offset;
   int64_t ExistingValue;
   switch (Reloc.Reloc.Type) {
@@ -149,15 +148,18 @@ static void calcRelocations(const ObjFil
                             int32_t OutputOffset) {
   log("calcRelocations: " + File.getName() + " offset=" + Twine(OutputOffset));
   for (const WasmRelocation &Reloc : Relocs) {
-    int64_t NewIndex = calcNewIndex(File, Reloc);
     OutputRelocation NewReloc;
     NewReloc.Reloc = Reloc;
     NewReloc.Reloc.Offset += OutputOffset;
-    NewReloc.NewIndex = NewIndex;
     DEBUG(dbgs() << "reloc: type=" << Reloc.Type << " index=" << Reloc.Index
-                 << " offset=" << Reloc.Offset << " new=" << NewIndex
+                 << " offset=" << Reloc.Offset
                  << " newOffset=" << NewReloc.Reloc.Offset << "\n");
 
+    if (Config->EmitRelocs)
+      NewReloc.NewIndex = calcNewIndex(File, Reloc);
+    else
+      NewReloc.NewIndex = UINT32_MAX;
+
     switch (Reloc.Type) {
     case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
     case R_WEBASSEMBLY_MEMORY_ADDR_I32:
@@ -167,7 +169,8 @@ static void calcRelocations(const ObjFil
         NewReloc.Value += Reloc.Addend;
       break;
     default:
-      NewReloc.Value = NewIndex;
+      NewReloc.Value = calcNewIndex(File, Reloc);
+      break;
     }
 
     OutputRelocs.emplace_back(NewReloc);

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Wed Dec  6 17:51:24 2017
@@ -34,8 +34,7 @@ void SymbolTable::addFile(InputFile *Fil
 
 void SymbolTable::reportRemainingUndefines() {
   std::unordered_set<Symbol *> Undefs;
-  for (auto &I : SymMap) {
-    Symbol *Sym = I.second;
+  for (Symbol *Sym : SymVector) {
     if (Sym->isUndefined() && !Sym->isWeak() &&
         Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) {
       Undefs.insert(Sym);
@@ -67,6 +66,7 @@ std::pair<Symbol *, bool> SymbolTable::i
   if (Sym)
     return {Sym, false};
   Sym = make<Symbol>(Name, false);
+  SymVector.emplace_back(Sym);
   return {Sym, true};
 }
 

Modified: lld/trunk/wasm/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.h (original)
+++ lld/trunk/wasm/SymbolTable.h Wed Dec  6 17:51:24 2017
@@ -47,6 +47,7 @@ public:
   void reportDuplicate(Symbol *Existing, InputFile *NewFile);
   void reportRemainingUndefines();
 
+  ArrayRef<Symbol *> getSymbols() const { return SymVector; }
   Symbol *find(StringRef Name);
 
   Symbol *addDefined(InputFile *F, const WasmSymbol *Sym,
@@ -60,6 +61,7 @@ private:
   std::pair<Symbol *, bool> insert(StringRef Name);
 
   llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
+  std::vector<Symbol *> SymVector;
 };
 
 extern SymbolTable *Symtab;

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=320001&r1=320000&r2=320001&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Wed Dec  6 17:51:24 2017
@@ -111,8 +111,9 @@ private:
 
   std::vector<const WasmSignature *> Types;
   DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
-  std::vector<Symbol *> FunctionImports;
-  std::vector<Symbol *> GlobalImports;
+  std::vector<const Symbol *> FunctionImports;
+  std::vector<const Symbol *> GlobalImports;
+  std::vector<const Symbol *> DefinedGlobals;
 
   // Elements that are used to construct the final output
   std::string Header;
@@ -217,11 +218,14 @@ void Writer::createMemorySection() {
 }
 
 void Writer::createGlobalSection() {
+  if (DefinedGlobals.empty())
+    return;
+
   SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
   raw_ostream &OS = Section->getStream();
 
-  writeUleb128(OS, NumGlobals, "global count");
-  for (const Symbol *Sym : Config->SyntheticGlobals) {
+  writeUleb128(OS, DefinedGlobals.size(), "global count");
+  for (const Symbol *Sym : DefinedGlobals) {
     WasmGlobal Global;
     Global.Type = WASM_TYPE_I32;
     Global.Mutable = Sym == Config->StackPointerSymbol;
@@ -229,24 +233,6 @@ void Writer::createGlobalSection() {
     Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
     writeGlobal(OS, Global);
   }
-
-  if (Config->EmitRelocs) {
-    for (ObjFile *File : Symtab->ObjectFiles) {
-      uint32_t GlobalIndex = File->NumGlobalImports();
-      for (const WasmGlobal &Global : File->getWasmObj()->globals()) {
-        WasmGlobal RelocatedGlobal(Global);
-        if (Global.Type != WASM_TYPE_I32)
-          fatal("unsupported global type: " + Twine(Global.Type));
-        if (Global.InitExpr.Opcode != WASM_OPCODE_I32_CONST)
-          fatal("unsupported global init opcode: " +
-                Twine(Global.InitExpr.Opcode));
-        RelocatedGlobal.InitExpr.Value.Int32 =
-            File->getRelocatedAddress(GlobalIndex);
-        writeGlobal(OS, RelocatedGlobal);
-        ++GlobalIndex;
-      }
-    }
-  }
 }
 
 void Writer::createTableSection() {
@@ -261,35 +247,36 @@ void Writer::createTableSection() {
 }
 
 void Writer::createExportSection() {
-  // Memory is and main function are exported for executables.
   bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
-  bool ExportOther = true; // ??? TODO Config->Relocatable;
-  bool ExportHidden = Config->Relocatable;
   Symbol *EntrySym = Symtab->find(Config->Entry);
   bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
+  bool ExportHidden = Config->EmitRelocs;
 
-  uint32_t NumExports = 0;
-
-  if (ExportMemory)
-    ++NumExports;
+  uint32_t NumExports = ExportMemory ? 1 : 0;
 
+  std::vector<const Symbol *> SymbolExports;
   if (ExportEntry)
-    ++NumExports;
+    SymbolExports.emplace_back(EntrySym);
 
-  if (ExportOther) {
-    for (ObjFile *File : Symtab->ObjectFiles) {
-      for (Symbol *Sym : File->getSymbols()) {
-        if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
-            (Sym->isHidden() && !ExportHidden) || Sym->WrittenToSymtab)
-          continue;
-        if (Sym == EntrySym)
-          continue;
-        Sym->WrittenToSymtab = true;
-        ++NumExports;
-      }
-    }
+  for (const Symbol *Sym : Symtab->getSymbols()) {
+    if (Sym->isUndefined() || Sym->isGlobal())
+      continue;
+    if (Sym->isHidden() && !ExportHidden)
+      continue;
+    if (ExportEntry && Sym == EntrySym)
+      continue;
+    SymbolExports.emplace_back(Sym);
+  }
+
+  for (const Symbol *Sym : DefinedGlobals) {
+    // Can't export the SP right now because it mutable and mutable globals
+    // connot be exported.
+    if (Sym == Config->StackPointerSymbol)
+      continue;
+    SymbolExports.emplace_back(Sym);
   }
 
+  NumExports += SymbolExports.size();
   if (!NumExports)
     return;
 
@@ -306,34 +293,16 @@ void Writer::createExportSection() {
     writeExport(OS, MemoryExport);
   }
 
-  if (ExportEntry) {
-    WasmExport EntryExport;
-    EntryExport.Name = Config->Entry;
-    EntryExport.Kind = WASM_EXTERNAL_FUNCTION;
-    EntryExport.Index = EntrySym->getOutputIndex();
-    writeExport(OS, EntryExport);
-  }
-
-  if (ExportOther) {
-    for (ObjFile *File : Symtab->ObjectFiles) {
-      for (Symbol *Sym : File->getSymbols()) {
-        if (!Sym->isFunction() || Sym->isLocal() || Sym->isUndefined() ||
-            (Sym->isHidden() && !ExportHidden) || !Sym->WrittenToSymtab)
-          continue;
-        if (Sym == EntrySym)
-          continue;
-        Sym->WrittenToSymtab = false;
-        log("Export: " + Sym->getName());
-        WasmExport Export;
-        Export.Name = Sym->getName();
-        Export.Index = Sym->getOutputIndex();
-        if (Sym->isFunction())
-          Export.Kind = WASM_EXTERNAL_FUNCTION;
-        else
-          Export.Kind = WASM_EXTERNAL_GLOBAL;
-        writeExport(OS, Export);
-      }
-    }
+  for (const Symbol *Sym : SymbolExports) {
+    log("Export: " + Sym->getName());
+    WasmExport Export;
+    Export.Name = Sym->getName();
+    Export.Index = Sym->getOutputIndex();
+    if (Sym->isFunction())
+      Export.Kind = WASM_EXTERNAL_FUNCTION;
+    else
+      Export.Kind = WASM_EXTERNAL_GLOBAL;
+    writeExport(OS, Export);
   }
 }
 
@@ -557,7 +526,6 @@ void Writer::createSections() {
 }
 
 void Writer::calculateOffsets() {
-  NumGlobals = Config->SyntheticGlobals.size();
   NumTableElems = InitialTableOffset;
 
   for (ObjFile *File : Symtab->ObjectFiles) {
@@ -568,13 +536,6 @@ void Writer::calculateOffsets() {
         FunctionImports.size() - File->NumFunctionImports() + NumFunctions;
     NumFunctions += WasmFile->functions().size();
 
-    // Global Index
-    if (Config->EmitRelocs) {
-      File->GlobalIndexOffset =
-          GlobalImports.size() - File->NumGlobalImports() + NumGlobals;
-      NumGlobals += WasmFile->globals().size();
-    }
-
     // Memory
     if (WasmFile->memories().size()) {
       if (WasmFile->memories().size() > 1) {
@@ -640,19 +601,31 @@ void Writer::calculateTypes() {
 }
 
 void Writer::assignSymbolIndexes() {
+  uint32_t GlobalIndex = GlobalImports.size();
+
+  if (Config->StackPointerSymbol) {
+    DefinedGlobals.emplace_back(Config->StackPointerSymbol);
+    Config->StackPointerSymbol->setOutputIndex(GlobalIndex++);
+  }
+
+  if (Config->EmitRelocs)
+    DefinedGlobals.reserve(Symtab->getSymbols().size());
+
   for (ObjFile *File : Symtab->ObjectFiles) {
     DEBUG(dbgs() << "assignSymbolIndexes: " << File->getName() << "\n");
     for (Symbol *Sym : File->getSymbols()) {
       if (Sym->hasOutputIndex() || !Sym->isDefined())
         continue;
 
-      if (Sym->getFile() && isa<ObjFile>(Sym->getFile())) {
-        auto *Obj = cast<ObjFile>(Sym->getFile());
-        if (Sym->isFunction())
+      if (Sym->isFunction()) {
+        if (Sym->getFile() && isa<ObjFile>(Sym->getFile())) {
+          auto *Obj = cast<ObjFile>(Sym->getFile());
           Sym->setOutputIndex(Obj->FunctionIndexOffset +
                               Sym->getFunctionIndex());
-        else
-          Sym->setOutputIndex(Obj->GlobalIndexOffset + Sym->getGlobalIndex());
+        }
+      } else if (Config->EmitRelocs) {
+        DefinedGlobals.emplace_back(Sym);
+        Sym->setOutputIndex(GlobalIndex++);
       }
     }
   }




More information about the llvm-commits mailing list