Index: wasm/Config.h =================================================================== --- wasm/Config.h +++ wasm/Config.h @@ -39,7 +39,8 @@ llvm::StringSet<> AllowUndefinedSymbols; std::vector SearchPaths; - std::vector> SyntheticGlobals; + std::vector SyntheticGlobals; + Symbol *StackPointerSymbol = nullptr; }; // The only instance of Configuration struct. Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -138,17 +138,12 @@ // Wasm global are used in relocatable object files to model symbol imports // and exports. In the final executable the only use of wasm globals is // for the exlicit stack pointer (__stack_pointer). -static void addSyntheticGlobal(StringRef Name, int32_t Value) { +static Symbol* 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); + return S; } // Inject a new undefined symbol into the link. This will cause the link to @@ -285,7 +280,7 @@ static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; addSyntheticUndefinedFunction(Config->Entry, &Signature); - addSyntheticGlobal("__stack_pointer", 0); + Config->StackPointerSymbol = 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 @@ -149,7 +149,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 +169,7 @@ writeImport(OS, Import); } - for (Symbol *Sym : GlobalImports) { + for (const Symbol *Sym : GlobalImports) { WasmImport Import; Import.Module = "env"; Import.Field = Sym->getName(); @@ -221,8 +221,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 == Config->StackPointerSymbol; + Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; + Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); writeGlobal(OS, Global); } @@ -507,7 +511,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; + Config->StackPointerSymbol->setVirtualAddress(MemoryPtr); debugPrint("mem: stack top = %d\n", MemoryPtr); } 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;