Commit 2b3e6f680c

Luuk de Gram <luuk@degram.dev>
2024-01-08 16:15:28
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.
1 parent 63de8a5
Changed files (2)
src
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;
                         }
                     }
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();
         }
     }
 }