mirror of
https://github.com/ziglang/zig.git
synced 2026-02-10 19:41:16 +00:00
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.
This commit is contained in:
parent
46c932a2c9
commit
b2718e213e
@ -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,
|
||||
}
|
||||
|
||||
@ -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.?;
|
||||
};
|
||||
}
|
||||
/// 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();
|
||||
|
||||
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.?;
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user