From 2b3e6f680c5843877f6252bd3d85a20abe367da6 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Mon, 8 Jan 2024 16:15:28 +0100 Subject: [PATCH] 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. --- src/link/Wasm.zig | 12 +++--------- src/link/Wasm/Object.zig | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 9dbef326484580e3f4e623c3162348abc4314f98..34b0c62414dc95abcca4267d5dbce6adf866f854 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 f0c21b8c89c8a4fb84752a816f3a4a3fae02d5cf..aaa99292bc04ba3f74922c872aa974399225eaf1 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; } } -- 2.54.0