From 975049e96e2245022a90368360fe7f3617e5f194 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Tue, 11 Jan 2022 20:35:44 +0100 Subject: [PATCH] wasm-ld: Append `--stack-first` by default By placing the stack at the start of the memory section, we prevent the runtime from silently overwriting the global declarations and instead trap. We do however, allow users to overwrite this behavior by setting the global-base, which puts the stack at the end of the memory section and the static data at the base that was specified. The reason a user would want to do this, is when they are sure the stack will not overflow and they want to decrease the binary size as the offsets to the static memory are generally smaller. (Having the stack in front, means that accessing the memory after the stack has a bigger offset when loading/storing from memory). --- src/link/Wasm.zig | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 2dfe0dd5d9..99311b8441 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1243,6 +1243,12 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { if (self.base.options.global_base) |global_base| { const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base}); try argv.append(arg); + } else { + // We prepend it by default, so when a stack overflow happens the runtime will trap correctly, + // rather than silently overwrite all global declarations. See https://github.com/ziglang/zig/issues/4496 + // + // The user can overwrite this behavior by setting the global-base + try argv.append("--stack-first"); } var auto_export_symbols = true; @@ -1294,10 +1300,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}); try argv.append(arg); - // Put stack before globals so that stack overflow results in segfault immediately - // before corrupting globals. See https://github.com/ziglang/zig/issues/4496 - try argv.append("--stack-first"); - if (self.base.options.wasi_exec_model == .reactor) { // Reactor execution model does not have _start so lld doesn't look for it. try argv.append("--no-entry");