[WebAssembly] Seal imports section before counting imports
authorSam Clegg <sbc@chromium.org>
Thu, 23 May 2019 09:41:03 +0000 (09:41 +0000)
committerSam Clegg <sbc@chromium.org>
Thu, 23 May 2019 09:41:03 +0000 (09:41 +0000)
Summary:
Before we can assign entries in the function of global index space
we need to know the total number of function and global imports
respectively.

To avoid programmer error this change seals that imports section before
assigned function and global index space.  Any attempt to add an import
after the section is sealed will assert.

The lack this such as check caused  https://reviews.llvm.org/D61876
to be reverted.  I'm also trying to craft a test case the this
failure.

Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits

Tags: #llvm

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

llvm-svn: 361470

lld/wasm/SyntheticSections.cpp
lld/wasm/SyntheticSections.h
lld/wasm/Writer.cpp

index 6dd68f6f10a1b6e2ee0f9b7e17698fe8fdbc4bad..198e6dbdffee198347c06030e06c8b66157b8013 100644 (file)
@@ -92,6 +92,7 @@ void TypeSection::writeBody() {
 }
 
 uint32_t ImportSection::numImports() const {
+  assert(IsSealed);
   uint32_t NumImports = ImportedSymbols.size() + GOTSymbols.size();
   if (Config->ImportMemory)
     ++NumImports;
@@ -101,6 +102,7 @@ uint32_t ImportSection::numImports() const {
 }
 
 void ImportSection::addGOTEntry(Symbol *Sym) {
+  assert(!IsSealed);
   if (Sym->hasGOTIndex())
     return;
   Sym->setGOTIndex(NumImportedGlobals++);
@@ -108,6 +110,7 @@ void ImportSection::addGOTEntry(Symbol *Sym) {
 }
 
 void ImportSection::addImport(Symbol *Sym) {
+  assert(!IsSealed);
   ImportedSymbols.emplace_back(Sym);
   if (auto *F = dyn_cast<FunctionSymbol>(Sym))
     F->setFunctionIndex(NumImportedFunctions++);
@@ -202,7 +205,7 @@ void FunctionSection::addFunction(InputFunction *Func) {
   if (!Func->Live)
     return;
   uint32_t FunctionIndex =
-      Out.ImportSec->NumImportedFunctions + InputFunctions.size();
+      Out.ImportSec->numImportedFunctions() + InputFunctions.size();
   InputFunctions.emplace_back(Func);
   Func->setFunctionIndex(FunctionIndex);
 }
@@ -251,7 +254,7 @@ void GlobalSection::addGlobal(InputGlobal *Global) {
   if (!Global->Live)
     return;
   uint32_t GlobalIndex =
-      Out.ImportSec->NumImportedGlobals + InputGlobals.size();
+      Out.ImportSec->numImportedGlobals() + InputGlobals.size();
   LLVM_DEBUG(dbgs() << "addGlobal: " << GlobalIndex << "\n");
   Global->setGlobalIndex(GlobalIndex);
   Out.GlobalSec->InputGlobals.push_back(Global);
@@ -270,7 +273,7 @@ void EventSection::writeBody() {
 void EventSection::addEvent(InputEvent *Event) {
   if (!Event->Live)
     return;
-  uint32_t EventIndex = Out.ImportSec->NumImportedEvents + InputEvents.size();
+  uint32_t EventIndex = Out.ImportSec->numImportedEvents() + InputEvents.size();
   LLVM_DEBUG(dbgs() << "addEvent: " << EventIndex << "\n");
   Event->setEventIndex(EventIndex);
   InputEvents.push_back(Event);
@@ -457,7 +460,7 @@ void LinkingSection::addToSymtab(Symbol *Sym) {
 }
 
 unsigned NameSection::numNames() const {
-  unsigned NumNames = Out.ImportSec->NumImportedFunctions;
+  unsigned NumNames = Out.ImportSec->numImportedFunctions();
   for (const InputFunction *F : Out.FunctionSec->InputFunctions)
     if (!F->getName().empty() || !F->getDebugName().empty())
       ++NumNames;
index c897132c35532454937fef6ee1fc5a5c60b55040..ccd66326a2461f56e6627a962063674eaa1c5c08 100644 (file)
@@ -101,14 +101,28 @@ public:
   void writeBody() override;
   void addImport(Symbol *Sym);
   void addGOTEntry(Symbol *Sym);
+  void seal() { IsSealed = true; }
   uint32_t numImports() const;
+  uint32_t numImportedGlobals() const {
+    assert(IsSealed);
+    return NumImportedGlobals;
+  }
+  uint32_t numImportedFunctions() const {
+    assert(IsSealed);
+    return NumImportedFunctions;
+  }
+  uint32_t numImportedEvents() const {
+    assert(IsSealed);
+    return NumImportedEvents;
+  }
 
-  unsigned NumImportedGlobals = 0;
-  unsigned NumImportedFunctions = 0;
-  unsigned NumImportedEvents = 0;
   std::vector<const Symbol *> ImportedSymbols;
 
 protected:
+  bool IsSealed = false;
+  unsigned NumImportedGlobals = 0;
+  unsigned NumImportedFunctions = 0;
+  unsigned NumImportedEvents = 0;
   std::vector<const Symbol *> GOTSymbols;
 };
 
index eb567ecf5c55eb310ce596f9532fbd41fb7ece0b..01dbd82dc3549b9268195245799d33a9fb4c7cda 100644 (file)
@@ -439,7 +439,7 @@ void Writer::calculateExports() {
         WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});
 
   unsigned FakeGlobalIndex =
-      Out.ImportSec->NumImportedGlobals + Out.GlobalSec->InputGlobals.size();
+      Out.ImportSec->numImportedGlobals() + Out.GlobalSec->InputGlobals.size();
 
   for (Symbol *Sym : Symtab->getSymbols()) {
     if (!Sym->isExported())
@@ -532,7 +532,9 @@ static void scanRelocations() {
 }
 
 void Writer::assignIndexes() {
-  assert(Out.FunctionSec->InputFunctions.empty());
+  // Seal the import section, since other index spaces such as function and
+  // global are effected by the number of imports.
+  Out.ImportSec->seal();
 
   for (InputFunction *Func : Symtab->SyntheticFunctions)
     Out.FunctionSec->addFunction(Func);
@@ -543,8 +545,6 @@ void Writer::assignIndexes() {
       Out.FunctionSec->addFunction(Func);
   }
 
-  scanRelocations();
-
   for (InputGlobal *Global : Symtab->SyntheticGlobals)
     Out.GlobalSec->addGlobal(Global);
 
@@ -724,6 +724,8 @@ void Writer::run() {
   populateTargetFeatures();
   log("-- calculateImports");
   calculateImports();
+  log("-- scanRelocations");
+  scanRelocations();
   log("-- assignIndexes");
   assignIndexes();
   log("-- calculateInitFunctions");
@@ -750,9 +752,9 @@ void Writer::run() {
     log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size()));
     log("Defined Globals  : " + Twine(Out.GlobalSec->InputGlobals.size()));
     log("Defined Events   : " + Twine(Out.EventSec->InputEvents.size()));
-    log("Function Imports : " + Twine(Out.ImportSec->NumImportedFunctions));
-    log("Global Imports   : " + Twine(Out.ImportSec->NumImportedGlobals));
-    log("Event Imports    : " + Twine(Out.ImportSec->NumImportedEvents));
+    log("Function Imports : " + Twine(Out.ImportSec->numImportedFunctions()));
+    log("Global Imports   : " + Twine(Out.ImportSec->numImportedGlobals()));
+    log("Event Imports    : " + Twine(Out.ImportSec->numImportedEvents()));
     for (ObjFile *File : Symtab->ObjectFiles)
       File->dumpInfo();
   }