aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-04-23 15:39:36 -0700
committerGitHub <noreply@github.com>2023-04-23 15:39:36 -0700
commit2dbcc03fb80e0688bba651821db6488cf950404c (patch)
tree9d5bfa6e85d587d8373bc99a8153c75093ae1a90 /src/link
parent42ee364e7b698822a69cba4cd2bda17868657e05 (diff)
parent6c1ab376ddcdbb05610487e5b813d42ff37da40d (diff)
downloadzig-2dbcc03fb80e0688bba651821db6488cf950404c.tar.gz
zig-2dbcc03fb80e0688bba651821db6488cf950404c.zip
Merge pull request #15405 from Luukdegram/wasm
wasm: implement more runtime safety checks
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Wasm.zig43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 2125a8faaa..0fe9ec5e3b 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -1209,6 +1209,11 @@ fn resolveLazySymbols(wasm: *Wasm) !void {
try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
}
}
+ if (wasm.undefs.fetchSwapRemove("__zig_errors_len")) |kv| {
+ const loc = try wasm.createSyntheticSymbol("__zig_errors_len", .data);
+ try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
+ _ = wasm.resolved_symbols.swapRemove(kv.value);
+ }
}
// Tries to find a global symbol by its name. Returns null when not found,
@@ -2185,6 +2190,43 @@ fn setupInitFunctions(wasm: *Wasm) !void {
std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);
}
+/// Generates an atom containing the global error set' size.
+/// This will only be generated if the symbol exists.
+fn setupErrorsLen(wasm: *Wasm) !void {
+ const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return;
+
+ const errors_len = wasm.base.options.module.?.global_error_set.count();
+ // overwrite existing atom if it already exists (maybe the error set has increased)
+ // if not, allcoate a new atom.
+ const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {
+ const atom = wasm.getAtomPtr(index);
+ if (atom.next) |next_atom_index| {
+ const next_atom = wasm.getAtomPtr(next_atom_index);
+ next_atom.prev = atom.prev;
+ atom.next = null;
+ }
+ if (atom.prev) |prev_index| {
+ const prev_atom = wasm.getAtomPtr(prev_index);
+ prev_atom.next = atom.next;
+ atom.prev = null;
+ }
+ atom.deinit(wasm);
+ break :blk index;
+ } else new_atom: {
+ const atom_index = @intCast(Atom.Index, wasm.managed_atoms.items.len);
+ try wasm.symbol_atom.put(wasm.base.allocator, loc, atom_index);
+ try wasm.managed_atoms.append(wasm.base.allocator, undefined);
+ break :new_atom atom_index;
+ };
+ const atom = wasm.getAtomPtr(atom_index);
+ atom.* = Atom.empty;
+ atom.sym_index = loc.index;
+ atom.size = 2;
+ try atom.code.writer(wasm.base.allocator).writeIntLittle(u16, @intCast(u16, errors_len));
+
+ try wasm.parseAtom(atom_index, .{ .data = .read_only });
+}
+
/// Creates a function body for the `__wasm_call_ctors` symbol.
/// Loops over all constructors found in `init_funcs` and calls them
/// respectively based on their priority which was sorted by `setupInitFunctions`.
@@ -3317,6 +3359,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
// So we can rebuild the binary file on each incremental update
defer wasm.resetState();
try wasm.setupInitFunctions();
+ try wasm.setupErrorsLen();
try wasm.setupStart();
try wasm.setupImports();
if (wasm.base.options.module) |mod| {