| author | |
| committer | |
| log | 2b3e6f680c5843877f6252bd3d85a20abe367da6 |
| tree | e895655b3a7ca6ac29def54d6b0b8da968ce3552 |
| parent | 63de8a59891f2c342d1a51b808cf04a895ba54d6 |
| signature |
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 to | 81 | /// 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, | ||
| 83 | 86 | ||
| 84 | const Tag = enum { data, code, custom }; | 87 | const Tag = enum { data, code, custom }; |
| 85 | 88 | ||
| ... | @@ -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 | } |
| 755 | 758 | ||
| 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 | } |