Index: wasm/Config.h =================================================================== --- wasm/Config.h +++ wasm/Config.h @@ -39,7 +39,7 @@ llvm::StringSet<> AllowUndefinedSymbols; std::vector SearchPaths; - std::vector> SyntheticGlobals; + std::vector SyntheticGlobals; }; // The only instance of Configuration struct. Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -141,14 +141,8 @@ static void addSyntheticGlobal(StringRef Name, int32_t Value) { log("injecting global: " + Name); Symbol *S = Symtab->addDefinedGlobal(Name); - S->setOutputIndex(Config->SyntheticGlobals.size()); - - WasmGlobal Global; - Global.Mutable = true; - Global.Type = WASM_TYPE_I32; - Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; - Global.InitExpr.Value.Int32 = Value; - Config->SyntheticGlobals.emplace_back(S, Global); + S->setVirtualAddress(Value); + Config->SyntheticGlobals.emplace_back(S); } // Inject a new undefined symbol into the link. This will cause the link to @@ -285,7 +279,7 @@ static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; addSyntheticUndefinedFunction(Config->Entry, &Signature); - addSyntheticGlobal("__stack_pointer", 0); + addSyntheticGlobal(kStackPointer, 0); } createFiles(Args); Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -77,12 +77,14 @@ uint32_t getVirtualAddress() const; // Returns true if an output index has been set for this symbol - bool hasOutputIndex() { return OutputIndex.hasValue(); } + bool hasOutputIndex() const { return OutputIndex.hasValue(); } // Set the output index of the symbol (in the function or global index // space of the output object. void setOutputIndex(uint32_t Index); + void setVirtualAddress(uint32_t VA); + void update(Kind K, InputFile *F = nullptr, const WasmSymbol *Sym = nullptr, const InputSegment *Segment = nullptr, const WasmSignature *Sig = nullptr); @@ -105,6 +107,7 @@ const WasmSymbol *Sym = nullptr; const InputSegment *Segment = nullptr; llvm::Optional OutputIndex; + llvm::Optional VirtualAddress; const WasmSignature *FunctionType; }; Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -41,6 +41,8 @@ DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); if (isUndefined()) return UINT32_MAX; + if (VirtualAddress.hasValue()) + return VirtualAddress.getValue(); assert(Sym != nullptr); ObjFile *Obj = cast(File); @@ -57,6 +59,11 @@ return OutputIndex.getValue(); } +void Symbol::setVirtualAddress(uint32_t Value) { + DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); + VirtualAddress = Value; +} + void Symbol::setOutputIndex(uint32_t Index) { DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); assert(!hasOutputIndex()); Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -109,6 +109,7 @@ uint32_t NumElements = 0; uint32_t InitialTableOffset = 0; + Symbol *StackSymbol = nullptr; std::vector Types; DenseMap TypeIndices; std::vector FunctionImports; @@ -149,7 +150,7 @@ writeUleb128(OS, NumImports, "import count"); - for (Symbol *Sym : FunctionImports) { + for (const Symbol *Sym : FunctionImports) { WasmImport Import; Import.Module = "env"; Import.Field = Sym->getName(); @@ -169,7 +170,7 @@ writeImport(OS, Import); } - for (Symbol *Sym : GlobalImports) { + for (const Symbol *Sym : GlobalImports) { WasmImport Import; Import.Module = "env"; Import.Field = Sym->getName(); @@ -221,8 +222,12 @@ raw_ostream &OS = Section->getStream(); writeUleb128(OS, NumGlobals, "global count"); - for (auto &Pair : Config->SyntheticGlobals) { - WasmGlobal &Global = Pair.second; + for (const Symbol *Sym : Config->SyntheticGlobals) { + WasmGlobal Global; + Global.Type = WASM_TYPE_I32; + Global.Mutable = Sym == StackSymbol; + Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; + Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); writeGlobal(OS, Global); } @@ -507,7 +512,7 @@ debugPrint("mem: stack size = %d\n", Config->ZStackSize); debugPrint("mem: stack base = %d\n", MemoryPtr); MemoryPtr += Config->ZStackSize; - Config->SyntheticGlobals[0].second.InitExpr.Value.Int32 = MemoryPtr; + StackSymbol->setVirtualAddress(MemoryPtr); debugPrint("mem: stack top = %d\n", MemoryPtr); } @@ -693,8 +698,10 @@ } void Writer::run() { - if (!Config->Relocatable) + if (!Config->Relocatable) { + StackSymbol = Symtab->find(kStackPointer); InitialTableOffset = 1; + } log("-- calculateTypes"); calculateTypes(); Index: wasm/WriterUtils.h =================================================================== --- wasm/WriterUtils.h +++ wasm/WriterUtils.h @@ -30,6 +30,8 @@ namespace lld { namespace wasm { +static const char* kStackPointer = "__stack_pointer"; + struct OutputRelocation { llvm::wasm::WasmRelocation Reloc; uint32_t NewIndex;