| 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 | 3260 | break :blk index; |
| 3261 | 3261 | }; |
| 3262 | 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 | 3264 | wasm.debug_ranges_index = index; |
| 3265 | 3265 | try wasm.appendDummySegment(); |
| 3266 | 3266 | break :blk index; |
| ... | ... | @@ -5301,14 +5301,8 @@ fn markReferences(wasm: *Wasm) !void { |
| 5301 | 5301 | const object = &wasm.objects.items[file]; |
| 5302 | 5302 | const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm); |
| 5303 | 5303 | const atom = wasm.getAtom(atom_index); |
| 5304 | for (atom.relocs.items) |reloc| { | |
| 5305 | const target_loc: SymbolLoc = .{ .index = reloc.index, .file = atom.file }; | |
| 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 | } | |
| 5304 | const atom_sym = atom.symbolLoc().getSymbol(wasm); | |
| 5305 | atom_sym.mark(); | |
| 5312 | 5306 | } |
| 5313 | 5307 | } |
| 5314 | 5308 | } |
src/link/Wasm/Object.zig+23-1| ... | ... | @@ -80,6 +80,9 @@ const RelocatableData = struct { |
| 80 | 80 | offset: u32, |
| 81 | 81 | /// Represents the index of the section it belongs to |
| 82 | 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 | 87 | const Tag = enum { data, code, custom }; |
| 85 | 88 | |
| ... | ... | @@ -753,6 +756,24 @@ fn Parser(comptime ReaderType: type) type { |
| 753 | 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 | 777 | parser.object.symtable = try symbols.toOwnedSlice(); |
| 757 | 778 | }, |
| 758 | 779 | } |
| ... | ... | @@ -791,9 +812,10 @@ fn Parser(comptime ReaderType: type) type { |
| 791 | 812 | .section => { |
| 792 | 813 | symbol.index = try leb.readULEB128(u32, reader); |
| 793 | 814 | const section_data = parser.object.relocatable_data.get(.custom).?; |
| 794 | for (section_data) |data| { | |
| 815 | for (section_data) |*data| { | |
| 795 | 816 | if (data.section_index == symbol.index) { |
| 796 | 817 | symbol.name = data.index; |
| 818 | data.represented = true; | |
| 797 | 819 | break; |
| 798 | 820 | } |
| 799 | 821 | } |