Index: test/wasm/alias.ll =================================================================== --- test/wasm/alias.ll +++ test/wasm/alias.ll @@ -42,6 +42,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -53,6 +59,9 @@ ; CHECK-NEXT: - Name: start_alias ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: test/wasm/call-indirect.ll =================================================================== --- test/wasm/call-indirect.ll +++ test/wasm/call-indirect.ll @@ -71,6 +71,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -91,6 +97,9 @@ ; CHECK-NEXT: - Name: call_ptr ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/comdats.ll =================================================================== --- test/wasm/comdats.ll +++ test/wasm/comdats.ll @@ -20,6 +20,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -37,6 +43,9 @@ ; CHECK-NEXT: - Name: callInline2 ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 3 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/data-layout.ll =================================================================== --- test/wasm/data-layout.ll +++ test/wasm/data-layout.ll @@ -22,30 +22,36 @@ ; CHECK-NEXT: Mutable: false ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 1024 +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Index: 2 ; 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: - Index: 3 ; 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: - Index: 4 ; CHECK-NEXT: Type: I32 ; CHECK-NEXT: Mutable: false ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1048 +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 1052 ; CHECK: - Type: DATA ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 -; CHECK-NEXT: Index: 4 +; CHECK-NEXT: Index: 5 ; CHECK-NEXT: Offset: 0x0000001F ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 7 Index: test/wasm/export.ll =================================================================== --- test/wasm/export.ll +++ test/wasm/export.ll @@ -26,4 +26,7 @@ ; CHECK-NEXT: - Name: hidden_function ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE Index: test/wasm/load-undefined.ll =================================================================== --- test/wasm/load-undefined.ll +++ test/wasm/load-undefined.ll @@ -27,6 +27,9 @@ ; CHECK-NEXT: - Name: ret64 ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: Index: test/wasm/local-symbols.ll =================================================================== --- test/wasm/local-symbols.ll +++ test/wasm/local-symbols.ll @@ -47,6 +47,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -55,6 +61,9 @@ ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: test/wasm/stack-pointer.ll =================================================================== --- test/wasm/stack-pointer.ll +++ test/wasm/stack-pointer.ll @@ -41,6 +41,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -52,6 +58,9 @@ ; CHECK-NEXT: - Name: __wasm_call_ctors ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB Index: test/wasm/visibility-hidden.ll =================================================================== --- test/wasm/visibility-hidden.ll +++ test/wasm/visibility-hidden.ll @@ -43,4 +43,7 @@ ; CHECK-NEXT: - Name: objectDefault ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: Index: test/wasm/weak-alias-overide.ll =================================================================== --- test/wasm/weak-alias-overide.ll +++ test/wasm/weak-alias-overide.ll @@ -49,6 +49,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -75,6 +81,9 @@ ; CHECK-NEXT: - Name: call_direct_ptr ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 6 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/weak-alias.ll =================================================================== --- test/wasm/weak-alias.ll +++ test/wasm/weak-alias.ll @@ -46,6 +46,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -72,6 +78,9 @@ ; CHECK-NEXT: - Name: call_direct_ptr ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 5 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/weak-symbols.ll =================================================================== --- test/wasm/weak-symbols.ll +++ test/wasm/weak-symbols.ll @@ -46,6 +46,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -63,6 +69,9 @@ ; CHECK-NEXT: - Name: exportWeak2 ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/weak-undefined.ll =================================================================== --- test/wasm/weak-undefined.ll +++ test/wasm/weak-undefined.ll @@ -56,6 +56,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 69632 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -70,6 +76,9 @@ ; CHECK-NEXT: - Name: get_address_of_global_var ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __heap_base +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: wasm/Config.h =================================================================== --- wasm/Config.h +++ wasm/Config.h @@ -40,6 +40,7 @@ llvm::StringSet<> AllowUndefinedSymbols; std::vector SearchPaths; Symbol *StackPointerSymbol = nullptr; + Symbol *HeapBaseSymbol = nullptr; Symbol *CtorSymbol = nullptr; }; Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -310,6 +310,7 @@ Config->CtorSymbol = Symtab->addDefinedFunction( "__wasm_call_ctors", &Signature, WASM_SYMBOL_VISIBILITY_HIDDEN); Config->StackPointerSymbol = Symtab->addDefinedGlobal("__stack_pointer"); + Config->HeapBaseSymbol = Symtab->addDefinedGlobal("__heap_base"); Symtab->addDefinedGlobal("__dso_handle")->setVirtualAddress(0); } Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -572,6 +572,11 @@ MemoryPtr += Config->ZStackSize; Config->StackPointerSymbol->setVirtualAddress(MemoryPtr); debugPrint("mem: stack top = %d\n", MemoryPtr); + // Set `__heap_base` to directly follow the end of the stack. We don't + // allocate any heap memory up front, but instead really on the malloc/brk + // implementation growing the memory at runtime. + Config->HeapBaseSymbol->setVirtualAddress(MemoryPtr); + debugPrint("mem: heap base = %d\n", MemoryPtr); } uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize); @@ -669,6 +674,11 @@ Config->StackPointerSymbol->setOutputIndex(GlobalIndex++); } + if (Config->HeapBaseSymbol) { + DefinedGlobals.emplace_back(Config->HeapBaseSymbol); + Config->HeapBaseSymbol->setOutputIndex(GlobalIndex++); + } + if (Config->EmitRelocs) DefinedGlobals.reserve(Symtab->getSymbols().size());