From 8447d4fb1f5b628b3c0c9f2b1254d8ddc7801ab1 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Wed, 22 Nov 2023 06:51:50 +0100 Subject: [PATCH] wasm-linker: handle debug info during gc When we encounter a debug info symbol, we initially have to parse it into an atom to find its relocations. We then go through its relocations to find out if any of the target symbols are marked alive. When it finds an alive symbol, we also mark the debug symbol as alive to ensure this piece of debug info is emit to the binary. When it does not encounter any alive symbols, the debug symbol remains dead and will be garbage- collected during `allocateAtoms`. --- src/link/Wasm.zig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index ddd3329bd8..0ed32caf4c 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -5115,6 +5115,23 @@ fn markReferences(wasm: *Wasm) !void { if (sym.isExported(wasm.base.options.rdynamic) or sym.isNoStrip()) { try wasm.mark(sym_loc); } + + // Debug sections may require to be parsed and marked when it contains + // relocations to alive symbols. + if (sym.tag == .section and !wasm.base.options.strip) { + const file = sym_loc.file orelse continue; // Incremental debug info is done independently + 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()) { + sym.mark(); + continue; // Skip all other relocations as this debug atom is already marked now + } + } + } } }