diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-04-23 15:39:36 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-23 15:39:36 -0700 |
| commit | 2dbcc03fb80e0688bba651821db6488cf950404c (patch) | |
| tree | 9d5bfa6e85d587d8373bc99a8153c75093ae1a90 /src/link | |
| parent | 42ee364e7b698822a69cba4cd2bda17868657e05 (diff) | |
| parent | 6c1ab376ddcdbb05610487e5b813d42ff37da40d (diff) | |
| download | zig-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.zig | 43 |
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| { |
