Skip to content

Commit

Permalink
[lld][WebAssembly] Add symbols marking start/end of stack region
Browse files Browse the repository at this point in the history
Currently emscripten is make assumptions about that memory layout,
assuming the stack is between `__data_end` and `__heap_base`:

https://github.com/emscripten-core/emscripten/blob/af961ad5c4c278ec510f0b7f7d522a95ee5a90f8/system/lib/compiler-rt/stack_limits.S#L42-L61

With this change we can be more precise:

emscripten-core/emscripten#18057

Differential Revision: https://reviews.llvm.org/D135910
  • Loading branch information
sbc100 committed Oct 13, 2022
1 parent f7cd3fc commit 1532be9
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 11 deletions.
14 changes: 10 additions & 4 deletions lld/test/wasm/export-all.s
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ foo:
# CHECK-NEXT: - Name: __data_end
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 2
# CHECK-NEXT: - Name: __global_base
# CHECK-NEXT: - Name: __stack_low
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 3
# CHECK-NEXT: - Name: __heap_base
# CHECK-NEXT: - Name: __stack_high
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 4
# CHECK-NEXT: - Name: __memory_base
# CHECK-NEXT: - Name: __global_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 5
# CHECK-NEXT: - Name: __table_base
# CHECK-NEXT: - Name: __heap_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 6
# CHECK-NEXT: - Name: __memory_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 7
# CHECK-NEXT: - Name: __table_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: Index: 8
14 changes: 10 additions & 4 deletions lld/test/wasm/mutable-global-exports.s
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,24 @@ _start:
# CHECK-ALL-NEXT: - Name: __data_end
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 3
# CHECK-ALL-NEXT: - Name: __global_base
# CHECK-ALL-NEXT: - Name: __stack_low
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 4
# CHECK-ALL-NEXT: - Name: __heap_base
# CHECK-ALL-NEXT: - Name: __stack_high
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 5
# CHECK-ALL-NEXT: - Name: __memory_base
# CHECK-ALL-NEXT: - Name: __global_base
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 6
# CHECK-ALL-NEXT: - Name: __table_base
# CHECK-ALL-NEXT: - Name: __heap_base
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 7
# CHECK-ALL-NEXT: - Name: __memory_base
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 8
# CHECK-ALL-NEXT: - Name: __table_base
# CHECK-ALL-NEXT: Kind: GLOBAL
# CHECK-ALL-NEXT: Index: 9
# CHECK-ALL-NEXT: - Type: CODE

# CHECK-ALL: Name: target_features
Expand Down
2 changes: 2 additions & 0 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,8 @@ static void createOptionalSymbols() {
WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");

if (!config->isPic) {
WasmSym::stackLow = symtab->addOptionalDataSymbol("__stack_low");
WasmSym::stackHigh = symtab->addOptionalDataSymbol("__stack_high");
WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
Expand Down
2 changes: 2 additions & 0 deletions lld/wasm/Symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ DefinedData *WasmSym::globalBase;
DefinedData *WasmSym::heapBase;
DefinedData *WasmSym::initMemoryFlag;
GlobalSymbol *WasmSym::stackPointer;
DefinedData *WasmSym::stackLow;
DefinedData *WasmSym::stackHigh;
GlobalSymbol *WasmSym::tlsBase;
GlobalSymbol *WasmSym::tlsSize;
GlobalSymbol *WasmSym::tlsAlign;
Expand Down
9 changes: 6 additions & 3 deletions lld/wasm/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,13 @@ struct WasmSym {
// Symbol marking the start of the global section.
static DefinedData *globalBase;

// __stack_pointer
// Global that holds the address of the top of the explicit value stack in
// linear memory.
// __stack_pointer/__stack_low/__stack_high
// Global that holds current value of stack pointer and data symbols marking
// the start and end of the stack region. stackPointer is initialized to
// stackHigh and grows downwards towards stackLow
static GlobalSymbol *stackPointer;
static DefinedData *stackLow;
static DefinedData *stackHigh;

// __tls_base
// Global that holds the address of the base of the current thread's
Expand Down
4 changes: 4 additions & 0 deletions lld/wasm/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,16 @@ void Writer::layoutMemory() {
if (config->relocatable || config->isPic)
return;
memoryPtr = alignTo(memoryPtr, stackAlignment);
if (WasmSym::stackLow)
WasmSym::stackLow->setVA(memoryPtr);
if (config->zStackSize != alignTo(config->zStackSize, stackAlignment))
error("stack size must be " + Twine(stackAlignment) + "-byte aligned");
log("mem: stack size = " + Twine(config->zStackSize));
log("mem: stack base = " + Twine(memoryPtr));
memoryPtr += config->zStackSize;
setGlobalPtr(cast<DefinedGlobal>(WasmSym::stackPointer), memoryPtr);
if (WasmSym::stackHigh)
WasmSym::stackHigh->setVA(memoryPtr);
log("mem: stack top = " + Twine(memoryPtr));
};

Expand Down

0 comments on commit 1532be9

Please sign in to comment.