authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-08 16:15:28+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-12 14:57:32+01:00
log2b3e6f680c5843877f6252bd3d85a20abe367da6
treee895655b3a7ca6ac29def54d6b0b8da968ce3552
parent63de8a59891f2c342d1a51b808cf04a895ba54d6
signaturelock-open Commit is signed but in an unrecognized format.

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.

2 files changed, 26 insertions(+), 10 deletions(-)

src/link/Wasm.zig+3-9
...@@ -3260,7 +3260,7 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3...@@ -3260,7 +3260,7 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3
3260 break :blk index;3260 break :blk index;
3261 };3261 };
3262 } else if (mem.eql(u8, section_name, ".debug_ranges")) {3262 } else if (mem.eql(u8, section_name, ".debug_ranges")) {
3263 return wasm.debug_line_index orelse blk: {3263 return wasm.debug_ranges_index orelse blk: {
3264 wasm.debug_ranges_index = index;3264 wasm.debug_ranges_index = index;
3265 try wasm.appendDummySegment();3265 try wasm.appendDummySegment();
3266 break :blk index;3266 break :blk index;
...@@ -5301,14 +5301,8 @@ fn markReferences(wasm: *Wasm) !void {...@@ -5301,14 +5301,8 @@ fn markReferences(wasm: *Wasm) !void {
5301 const object = &wasm.objects.items[file];5301 const object = &wasm.objects.items[file];
5302 const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm);5302 const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm);
5303 const atom = wasm.getAtom(atom_index);5303 const atom = wasm.getAtom(atom_index);
5304 for (atom.relocs.items) |reloc| {5304 const atom_sym = atom.symbolLoc().getSymbol(wasm);
5305 const target_loc: SymbolLoc = .{ .index = reloc.index, .file = atom.file };5305 atom_sym.mark();
5306 const target_sym = target_loc.getSymbol(wasm);
5307 if (target_sym.isAlive() or !do_garbage_collect) {
5308 sym.mark();
5309 continue; // Skip all other relocations as this debug atom is already marked now
5310 }
5311 }
5312 }5306 }
5313 }5307 }
5314}5308}
src/link/Wasm/Object.zig+23-1
...@@ -80,6 +80,9 @@ const RelocatableData = struct {...@@ -80,6 +80,9 @@ const RelocatableData = struct {
80 offset: u32,80 offset: u32,
81 /// Represents the index of the section it belongs to81 /// Represents the index of the section it belongs to
82 section_index: u32,82 section_index: u32,
83 /// Whether the relocatable section is represented by a symbol or not.
84 /// Can only be `true` for custom sections.
85 represented: bool = false,
8386
84 const Tag = enum { data, code, custom };87 const Tag = enum { data, code, custom };
8588
...@@ -753,6 +756,24 @@ fn Parser(comptime ReaderType: type) type {...@@ -753,6 +756,24 @@ fn Parser(comptime ReaderType: type) type {
753 log.debug("Found legacy indirect function table. Created symbol", .{});756 log.debug("Found legacy indirect function table. Created symbol", .{});
754 }757 }
755758
759 // Not all debug sections may be represented by a symbol, for those sections
760 // we manually create a symbol.
761 if (parser.object.relocatable_data.get(.custom)) |custom_sections| {
762 for (custom_sections) |*data| {
763 if (!data.represented) {
764 try symbols.append(.{
765 .name = data.index,
766 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
767 .tag = .section,
768 .virtual_address = 0,
769 .index = data.section_index,
770 });
771 data.represented = true;
772 log.debug("Created synthetic custom section symbol for '{s}'", .{parser.object.string_table.get(data.index)});
773 }
774 }
775 }
776
756 parser.object.symtable = try symbols.toOwnedSlice();777 parser.object.symtable = try symbols.toOwnedSlice();
757 },778 },
758 }779 }
...@@ -791,9 +812,10 @@ fn Parser(comptime ReaderType: type) type {...@@ -791,9 +812,10 @@ fn Parser(comptime ReaderType: type) type {
791 .section => {812 .section => {
792 symbol.index = try leb.readULEB128(u32, reader);813 symbol.index = try leb.readULEB128(u32, reader);
793 const section_data = parser.object.relocatable_data.get(.custom).?;814 const section_data = parser.object.relocatable_data.get(.custom).?;
794 for (section_data) |data| {815 for (section_data) |*data| {
795 if (data.section_index == symbol.index) {816 if (data.section_index == symbol.index) {
796 symbol.name = data.index;817 symbol.name = data.index;
818 data.represented = true;
797 break;819 break;
798 }820 }
799 }821 }