aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2024-01-08 16:15:28 +0100
committerLuuk de Gram <luuk@degram.dev>2024-01-12 14:57:32 +0100
commit2b3e6f680c5843877f6252bd3d85a20abe367da6 (patch)
treee895655b3a7ca6ac29def54d6b0b8da968ce3552 /src/link
parent63de8a59891f2c342d1a51b808cf04a895ba54d6 (diff)
downloadzig-2b3e6f680c5843877f6252bd3d85a20abe367da6.tar.gz
zig-2b3e6f680c5843877f6252bd3d85a20abe367da6.zip
wasm-linker: ensure custom sections are parsed
Not all custom sections are represented by a symbol, which means the section will not be parsed by the lazy parsing and therefore get garbage- collected. This is problematic as it may contain debug information that should not be garbage-collected. To resolve this, we manually create local symbols for those sections and also ensure they do not get garbage- collected.
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Wasm.zig12
-rw-r--r--src/link/Wasm/Object.zig24
2 files changed, 26 insertions, 10 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 9dbef32648..34b0c62414 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -3260,7 +3260,7 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3
break :blk index;
};
} else if (mem.eql(u8, section_name, ".debug_ranges")) {
- return wasm.debug_line_index orelse blk: {
+ return wasm.debug_ranges_index orelse blk: {
wasm.debug_ranges_index = index;
try wasm.appendDummySegment();
break :blk index;
@@ -5301,14 +5301,8 @@ fn markReferences(wasm: *Wasm) !void {
const object = &wasm.objects.items[file];
const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm);
const atom = wasm.getAtom(atom_index);
- for (atom.relocs.items) |reloc| {
- const target_loc: SymbolLoc = .{ .index = reloc.index, .file = atom.file };
- const target_sym = target_loc.getSymbol(wasm);
- if (target_sym.isAlive() or !do_garbage_collect) {
- sym.mark();
- continue; // Skip all other relocations as this debug atom is already marked now
- }
- }
+ const atom_sym = atom.symbolLoc().getSymbol(wasm);
+ atom_sym.mark();
}
}
}
diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig
index f0c21b8c89..aaa99292bc 100644
--- a/src/link/Wasm/Object.zig
+++ b/src/link/Wasm/Object.zig
@@ -80,6 +80,9 @@ const RelocatableData = struct {
offset: u32,
/// Represents the index of the section it belongs to
section_index: u32,
+ /// Whether the relocatable section is represented by a symbol or not.
+ /// Can only be `true` for custom sections.
+ represented: bool = false,
const Tag = enum { data, code, custom };
@@ -753,6 +756,24 @@ fn Parser(comptime ReaderType: type) type {
log.debug("Found legacy indirect function table. Created symbol", .{});
}
+ // Not all debug sections may be represented by a symbol, for those sections
+ // we manually create a symbol.
+ if (parser.object.relocatable_data.get(.custom)) |custom_sections| {
+ for (custom_sections) |*data| {
+ if (!data.represented) {
+ try symbols.append(.{
+ .name = data.index,
+ .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
+ .tag = .section,
+ .virtual_address = 0,
+ .index = data.section_index,
+ });
+ data.represented = true;
+ log.debug("Created synthetic custom section symbol for '{s}'", .{parser.object.string_table.get(data.index)});
+ }
+ }
+ }
+
parser.object.symtable = try symbols.toOwnedSlice();
},
}
@@ -791,9 +812,10 @@ fn Parser(comptime ReaderType: type) type {
.section => {
symbol.index = try leb.readULEB128(u32, reader);
const section_data = parser.object.relocatable_data.get(.custom).?;
- for (section_data) |data| {
+ for (section_data) |*data| {
if (data.section_index == symbol.index) {
symbol.name = data.index;
+ data.represented = true;
break;
}
}