Index: test/wasm/alias.ll =================================================================== --- test/wasm/alias.ll +++ test/wasm/alias.ll @@ -47,6 +47,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -61,6 +67,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; 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 @@ -82,6 +82,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1036 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -105,6 +111,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/comdats.ll =================================================================== --- test/wasm/comdats.ll +++ test/wasm/comdats.ll @@ -28,6 +28,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1027 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -48,6 +54,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/export.ll =================================================================== --- test/wasm/export.ll +++ test/wasm/export.ll @@ -31,4 +31,7 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: CODE Index: test/wasm/load-undefined.test =================================================================== --- test/wasm/load-undefined.test +++ test/wasm/load-undefined.test @@ -25,6 +25,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: Index: test/wasm/local-symbols.ll =================================================================== --- test/wasm/local-symbols.ll +++ test/wasm/local-symbols.ll @@ -57,6 +57,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1032 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -68,6 +74,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: test/wasm/locals-duplicate.test =================================================================== --- test/wasm/locals-duplicate.test +++ test/wasm/locals-duplicate.test @@ -42,6 +42,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66592 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1048 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -92,6 +98,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/visibility-hidden.ll =================================================================== --- test/wasm/visibility-hidden.ll +++ test/wasm/visibility-hidden.ll @@ -48,4 +48,7 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: Index: test/wasm/weak-alias-overide.ll =================================================================== --- test/wasm/weak-alias-overide.ll +++ test/wasm/weak-alias-overide.ll @@ -57,6 +57,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -86,6 +92,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; 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 @@ -54,6 +54,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -83,6 +89,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; 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 @@ -54,6 +54,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1032 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -74,6 +80,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; 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 @@ -64,6 +64,12 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -81,6 +87,9 @@ ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: __data_end +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -304,6 +304,7 @@ WasmSym::StackPointer = Symtab->addDefinedGlobal("__stack_pointer"); WasmSym::HeapBase = Symtab->addDefinedGlobal("__heap_base"); WasmSym::DsoHandle = Symtab->addDefinedGlobal("__dso_handle"); + WasmSym::DataEnd = Symtab->addDefinedGlobal("__data_end"); } createFiles(Args); Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -114,11 +114,18 @@ // linker-generated symbols struct WasmSym { // __stack_pointer - // Global that holds the address of the top of the explict value stack - // in linear memory. + // Global that holds the address of the top of the explicit value stack in + // linear memory. static Symbol *StackPointer; + // __data_end + // Symbol marking the end of the data and bss. + static Symbol *DataEnd; + // __heap_base + // Symbol marking the end of the data, bss and explicit stack. Any linear + // memory following this address is not used by the linked code and can + // therefore be used as a backing store for brk()/malloc() implementations. static Symbol *HeapBase; // __wasm_call_ctors Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -24,6 +24,7 @@ Symbol *WasmSym::CallCtors; Symbol *WasmSym::DsoHandle; +Symbol *WasmSym::DataEnd; Symbol *WasmSym::HeapBase; Symbol *WasmSym::StackPointer; Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -548,6 +548,8 @@ } // TODO: Add .bss space here. + if (WasmSym::DataEnd) + WasmSym::DataEnd->setVirtualAddress(MemoryPtr); DataSize = MemoryPtr; if (!Config->Relocatable) @@ -732,6 +734,7 @@ }; AddDefinedGlobal(WasmSym::StackPointer); AddDefinedGlobal(WasmSym::HeapBase); + AddDefinedGlobal(WasmSym::DataEnd); if (Config->Relocatable) DefinedGlobals.reserve(Symtab->getSymbols().size());