Commit 4be3cd2754
Changed files (1)
src
link
src/link/Wasm.zig
@@ -1333,6 +1333,10 @@ pub fn deinit(wasm: *Wasm) void {
atom.deinit(gpa);
}
}
+ for (wasm.synthetic_functions.items) |atom_index| {
+ const atom = wasm.getAtomPtr(atom_index);
+ atom.deinit(gpa);
+ }
wasm.decls.deinit(gpa);
wasm.anon_decls.deinit(gpa);
@@ -1364,10 +1368,6 @@ pub fn deinit(wasm: *Wasm) void {
wasm.exports.deinit(gpa);
wasm.string_table.deinit(gpa);
- for (wasm.synthetic_functions.items) |atom_index| {
- const atom = wasm.getAtomPtr(atom_index);
- atom.deinit(gpa);
- }
wasm.synthetic_functions.deinit(gpa);
if (wasm.dwarf) |*dwarf| {
@@ -2134,9 +2134,13 @@ const Kind = union(enum) {
fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
const atom = wasm.getAtomPtr(atom_index);
const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm);
+ if (symbol.isDead()) {
+ // Prevent unreferenced symbols from being parsed.
+ return;
+ }
const final_index: u32 = switch (kind) {
.function => result: {
- const index = @as(u32, @intCast(wasm.functions.count() + wasm.imported_functions_count));
+ const index: u32 = @intCast(wasm.functions.count() + wasm.imported_functions_count);
const type_index = wasm.atom_types.get(atom_index).?;
try wasm.functions.putNoClobber(
wasm.base.allocator,
@@ -2147,7 +2151,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
symbol.index = index;
if (wasm.code_section_index == null) {
- wasm.code_section_index = @as(u32, @intCast(wasm.segments.items.len));
+ wasm.code_section_index = @intCast(wasm.segments.items.len);
try wasm.segments.append(wasm.base.allocator, .{
.alignment = atom.alignment,
.size = atom.size,
@@ -2185,12 +2189,12 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
const index = gop.value_ptr.*;
wasm.segments.items[index].size += atom.size;
- symbol.index = @as(u32, @intCast(wasm.segment_info.getIndex(index).?));
+ symbol.index = @intCast(wasm.segment_info.getIndex(index).?);
// segment info already exists, so free its memory
wasm.base.allocator.free(segment_name);
break :result index;
} else {
- const index = @as(u32, @intCast(wasm.segments.items.len));
+ const index: u32 = @intCast(wasm.segments.items.len);
var flags: u32 = 0;
if (wasm.base.options.shared_memory) {
flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE);
@@ -2203,7 +2207,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
});
gop.value_ptr.* = index;
- const info_index = @as(u32, @intCast(wasm.segment_info.count()));
+ const info_index: u32 = @intCast(wasm.segment_info.count());
try wasm.segment_info.put(wasm.base.allocator, index, segment_info);
symbol.index = info_index;
break :result index;
@@ -2318,8 +2322,10 @@ fn allocateAtoms(wasm: *Wasm) !void {
fn allocateVirtualAddresses(wasm: *Wasm) void {
for (wasm.resolved_symbols.keys()) |loc| {
const symbol = loc.getSymbol(wasm);
- if (symbol.tag != .data) {
- continue; // only data symbols have virtual addresses
+ if (symbol.tag != .data or symbol.isDead()) {
+ // Only data symbols have virtual addresses.
+ // Dead symbols do not get allocated, so we don't need to set their virtual address either.
+ continue;
}
const atom_index = wasm.symbol_atom.get(loc) orelse {
// synthetic symbol that does not contain an atom
@@ -2681,10 +2687,10 @@ fn setupImports(wasm: *Wasm) !void {
}
for (wasm.resolved_symbols.keys()) |symbol_loc| {
- if (symbol_loc.file == null) {
+ const file_index = symbol_loc.file orelse {
// imports generated by Zig code are already in the `import` section
continue;
- }
+ };
const symbol = symbol_loc.getSymbol(wasm);
if (symbol.isDead() or
@@ -2695,7 +2701,7 @@ fn setupImports(wasm: *Wasm) !void {
}
log.debug("Symbol '{s}' will be imported from the host", .{symbol_loc.getName(wasm)});
- const object = wasm.objects.items[symbol_loc.file.?];
+ const object = wasm.objects.items[file_index];
const import = object.findImport(symbol.tag.externalType(), symbol.index);
// We copy the import to a new import to ensure the names contain references
@@ -3092,6 +3098,11 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3
.offset = 0,
.flags = flags,
});
+ try wasm.segment_info.putNoClobber(wasm.base.allocator, index, .{
+ .name = try wasm.base.allocator.dupe(u8, segment_info.name),
+ .alignment = segment_info.alignment,
+ .flags = segment_info.flags,
+ });
return index;
} else return result.value_ptr.*;
},
@@ -3198,6 +3209,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {
.virtual_address = undefined,
};
symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
+ symbol.mark();
try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});
@@ -3230,6 +3242,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
.virtual_address = undefined,
};
names_symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
+ names_symbol.mark();
log.debug("Populating error names", .{});
@@ -3606,9 +3619,9 @@ 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.markReferences();
+ try wasm.setupErrorsLen();
try wasm.setupImports();
if (wasm.base.options.module) |mod| {
var decl_it = wasm.decls.iterator();
@@ -5152,14 +5165,15 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {
return;
}
- const file = loc.file orelse return; // Marking synthetic and Zig symbols is done seperately
- const object = &wasm.objects.items[file];
- const atom_index = try Object.parseSymbolIntoAtom(object, file, loc.index, wasm);
+ const atom_index = if (loc.file) |file_index| idx: {
+ const object = &wasm.objects.items[file_index];
+ const atom_index = try object.parseSymbolIntoAtom(file_index, loc.index, wasm);
+ break :idx atom_index;
+ } else wasm.symbol_atom.get(loc) orelse return;
const atom = wasm.getAtom(atom_index);
- const relocations: []const types.Relocation = atom.relocs.items;
- for (relocations) |reloc| {
- const target_loc: SymbolLoc = .{ .index = reloc.index, .file = file };
+ for (atom.relocs.items) |reloc| {
+ const target_loc: SymbolLoc = .{ .index = reloc.index, .file = loc.file };
try wasm.mark(target_loc.finalLoc(wasm));
}
}