authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-11 20:35:44+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-11 20:35:44+01:00
log975049e96e2245022a90368360fe7f3617e5f194
tree3622e219db6c2ffa73f0541f4ec1fe101ab0cbb4
parentf767f8e3dc158a74debdd288884458b860d2ebc9
signaturelock-open Commit is signed but in an unrecognized format.

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).

1 files changed, 6 insertions(+), 4 deletions(-)

src/link/Wasm.zig+6-4
...@@ -1243,6 +1243,12 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {...@@ -1243,6 +1243,12 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
1243 if (self.base.options.global_base) |global_base| {1243 if (self.base.options.global_base) |global_base| {
1244 const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});1244 const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});
1245 try argv.append(arg);1245 try argv.append(arg);
1246 } else {
1247 // We prepend it by default, so when a stack overflow happens the runtime will trap correctly,
1248 // rather than silently overwrite all global declarations. See https://github.com/ziglang/zig/issues/4496
1249 //
1250 // The user can overwrite this behavior by setting the global-base
1251 try argv.append("--stack-first");
1246 }1252 }
12471253
1248 var auto_export_symbols = true;1254 var auto_export_symbols = true;
...@@ -1294,10 +1300,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {...@@ -1294,10 +1300,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
1294 const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size});1300 const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size});
1295 try argv.append(arg);1301 try argv.append(arg);
12961302
1297 // Put stack before globals so that stack overflow results in segfault immediately
1298 // before corrupting globals. See https://github.com/ziglang/zig/issues/4496
1299 try argv.append("--stack-first");
1300
1301 if (self.base.options.wasi_exec_model == .reactor) {1303 if (self.base.options.wasi_exec_model == .reactor) {
1302 // Reactor execution model does not have _start so lld doesn't look for it.1304 // Reactor execution model does not have _start so lld doesn't look for it.
1303 try argv.append("--no-entry");1305 try argv.append("--no-entry");