From b2718e213ed7e7cd8bcd85bdf49d7ae33c857c58 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 2 Sep 2022 21:13:59 +0200 Subject: wasm-linker: use Atoms for zig debug info Previously we used single arraylists for each debug section for debug information that was generated from Zig code. (e.i. `Module` is available). This information is now stored in Atoms, similarly to debug information from object files. This will allow us to link them together and resolve debug relocations. --- src/link/Dwarf.zig | 45 +++++++++++++++++++++++++++--------------- src/link/Wasm.zig | 57 +++++++++++++++--------------------------------------- 2 files changed, 45 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 3ae151491f..e610d56df4 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -861,7 +861,9 @@ pub fn commitDeclState( }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - writeDbgLineNopsBuffered(wasm_file.debug_line.items, src_fn.off, 0, &.{}, src_fn.len); + const segment_index = wasm_file.debug_line_index.?; + const debug_line = wasm_file.atoms.get(segment_index).?.code; + writeDbgLineNopsBuffered(debug_line.items, src_fn.off, 0, &.{}, src_fn.len); }, else => unreachable, } @@ -972,9 +974,9 @@ pub fn commitDeclState( }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - const segment_index = try wasm_file.getDebugLineIndex(); + const segment_index = try wasm_file.getOrSetDebugIndex(&wasm_file.debug_line_index); const segment = &wasm_file.segments.items[segment_index]; - const debug_line = &wasm_file.debug_line; + const debug_line = &wasm_file.atoms.get(segment_index).?.code; if (needed_size != segment.size) { log.debug(" needed size does not equal allocated size: {d}", .{needed_size}); if (needed_size > segment.size) { @@ -1146,10 +1148,11 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u3 }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - const segment_index = try wasm_file.getDebugInfoIndex(); + const segment_index = try wasm_file.getOrSetDebugIndex(&wasm_file.debug_info_index); const segment = &wasm_file.segments.items[segment_index]; + const debug_info = &wasm_file.atoms.get(segment_index).?.code; const offset = segment.offset + atom.off; - try writeDbgInfoNopsToArrayList(gpa, &wasm_file.debug_info, offset, 0, &.{0}, atom.len, false); + try writeDbgInfoNopsToArrayList(gpa, debug_info, offset, 0, &.{0}, atom.len, false); }, else => unreachable, } @@ -1276,9 +1279,9 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - const segment_index = try wasm_file.getDebugInfoIndex(); + const segment_index = try wasm_file.getOrSetDebugIndex(&wasm_file.debug_info_index); const segment = &wasm_file.segments.items[segment_index]; - const debug_info = &wasm_file.debug_info; + const debug_info = &wasm_file.atoms.get(segment_index).?.code; if (needed_size != segment.size) { log.debug(" needed size does not equal allocated size: {d}", .{needed_size}); if (needed_size > segment.size) { @@ -1337,10 +1340,10 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl) }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - const segment_index = wasm_file.getDebugLineIndex() catch unreachable; + const segment_index = wasm_file.debug_line_index.?; const segment = wasm_file.segments.items[segment_index]; const offset = segment.offset + decl.fn_link.wasm.src_fn.off + self.getRelocDbgLineOff(); - mem.copy(u8, wasm_file.debug_line.items[offset..], &data); + mem.copy(u8, wasm_file.atoms.get(segment_index).?.code.items[offset..], &data); }, else => unreachable, } @@ -1576,8 +1579,10 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void { }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - try wasm_file.debug_abbrev.resize(wasm_file.base.allocator, needed_size); - mem.copy(u8, wasm_file.debug_abbrev.items, &abbrev_buf); + const segment_index = try wasm_file.getOrSetDebugIndex(&wasm_file.debug_abbrev_index); + const debug_abbrev = &wasm_file.atoms.get(segment_index).?.code; + try debug_abbrev.resize(wasm_file.base.allocator, needed_size); + mem.copy(u8, debug_abbrev.items, &abbrev_buf); }, else => unreachable, } @@ -1687,7 +1692,9 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6 }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - try writeDbgInfoNopsToArrayList(self.allocator, &wasm_file.debug_info, 0, 0, di_buf.items, jmp_amt, false); + const segment_index = wasm_file.debug_info_index.?; + const debug_info = &wasm_file.atoms.get(segment_index).?.code; + try writeDbgInfoNopsToArrayList(self.allocator, debug_info, 0, 0, di_buf.items, jmp_amt, false); }, else => unreachable, } @@ -2016,8 +2023,10 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void { }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - try wasm_file.debug_aranges.resize(wasm_file.base.allocator, needed_size); - mem.copy(u8, wasm_file.debug_aranges.items, di_buf.items); + const segment_index = try wasm_file.getOrSetDebugIndex(&wasm_file.debug_ranges_index); + const debug_ranges = &wasm_file.atoms.get(segment_index).?.code; + try debug_ranges.resize(wasm_file.base.allocator, needed_size); + mem.copy(u8, debug_ranges.items, di_buf.items); }, else => unreachable, } @@ -2139,7 +2148,9 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void { }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - writeDbgLineNopsBuffered(wasm_file.debug_line.items, 0, 0, di_buf.items, jmp_amt); + const segment_index = wasm_file.debug_line_index.?; + const debug_line = wasm_file.atoms.get(segment_index).?.code; + writeDbgLineNopsBuffered(debug_line.items, 0, 0, di_buf.items, jmp_amt); }, else => unreachable, } @@ -2287,7 +2298,9 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void { }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - mem.copy(u8, wasm_file.debug_info.items[reloc.atom.off + reloc.offset ..], &buf); + const segment_index = wasm_file.debug_info_index.?; + const debug_info = wasm_file.atoms.get(segment_index).?.code; + mem.copy(u8, debug_info.items[reloc.atom.off + reloc.offset ..], &buf); }, else => unreachable, } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 2ff631d9ba..7204182df2 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -103,16 +103,6 @@ string_table: StringTable = .{}, /// Debug information for wasm dwarf: ?Dwarf = null, -// *debug information* // -/// Contains all bytes for the '.debug_info' section -debug_info: std.ArrayListUnmanaged(u8) = .{}, -/// Contains all bytes for the '.debug_line' section -debug_line: std.ArrayListUnmanaged(u8) = .{}, -/// Contains all bytes for the '.debug_abbrev' section -debug_abbrev: std.ArrayListUnmanaged(u8) = .{}, -/// Contains all bytes for the '.debug_ranges' section -debug_aranges: std.ArrayListUnmanaged(u8) = .{}, - // Output sections /// Output type section func_types: std.ArrayListUnmanaged(wasm.Type) = .{}, @@ -716,11 +706,6 @@ pub fn deinit(self: *Wasm) void { if (self.dwarf) |*dwarf| { dwarf.deinit(); } - - self.debug_info.deinit(gpa); - self.debug_line.deinit(gpa); - self.debug_abbrev.deinit(gpa); - self.debug_aranges.deinit(gpa); } pub fn allocateDeclIndexes(self: *Wasm, decl_index: Module.Decl.Index) !void { @@ -1983,32 +1968,22 @@ fn populateErrorNameTable(self: *Wasm) !void { try self.parseAtom(names_atom, .{ .data = .read_only }); } -pub fn getDebugInfoIndex(self: *Wasm) !u32 { - assert(self.dwarf != null); - return self.debug_info_index orelse { - self.debug_info_index = @intCast(u32, self.segments.items.len); - const segment = try self.segments.addOne(self.base.allocator); - segment.* = .{ - .size = 0, - .offset = 0, - // debug sections always have alignment '1' - .alignment = 1, - }; - return self.debug_info_index.?; - }; -} - -pub fn getDebugLineIndex(self: *Wasm) !u32 { - assert(self.dwarf != null); - return self.debug_line_index orelse { - self.debug_line_index = @intCast(u32, self.segments.items.len); - const segment = try self.segments.addOne(self.base.allocator); - segment.* = .{ - .size = 0, - .offset = 0, - .alignment = 1, - }; - return self.debug_line_index.?; +/// From a given index variable, returns it value if set. +/// When not set, initialises a new segment, sets the index, +/// and returns it value. +/// When a new segment is initialised. It also creates an atom. +pub fn getOrSetDebugIndex(self: *Wasm, index: *?u32) !u32 { + return (index.*) orelse { + const new_index = @intCast(u32, self.segments.items.len); + index.* = new_index; + try self.appendDummySegment(); + + const atom = try self.base.allocator.create(Atom); + atom.* = Atom.empty; + atom.alignment = 1; // debug sections are always 1-byte-aligned + try self.managed_atoms.append(self.base.allocator, atom); + try self.atoms.put(self.base.allocator, new_index, atom); + return new_index; }; } -- cgit v1.2.3