authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-06 19:29:23+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 09:24:25+01:00
logf5c764d8923d301bb7e46b50cb034285640fcca2
treee573f5faca2995d766b56e1e001989a343ff08b3
parent4c4821d9939447d65966b897a5780e39eb22334b

dwarf: track source files via *const Module.File pointers


5 files changed, 162 insertions(+), 152 deletions(-)

src/link/Dwarf.zig+141-126
...@@ -22,7 +22,7 @@ const Value = @import("../value.zig").Value;...@@ -22,7 +22,7 @@ const Value = @import("../value.zig").Value;
22const Type = @import("../type.zig").Type;22const Type = @import("../type.zig").Type;
2323
24allocator: Allocator,24allocator: Allocator,
25tag: File.Tag,25bin_file: *File,
26ptr_width: PtrWidth,26ptr_width: PtrWidth,
27target: std.Target,27target: std.Target,
2828
...@@ -44,10 +44,9 @@ abbrev_table_offset: ?u64 = null,...@@ -44,10 +44,9 @@ abbrev_table_offset: ?u64 = null,
44/// Table of debug symbol names.44/// Table of debug symbol names.
45strtab: std.ArrayListUnmanaged(u8) = .{},45strtab: std.ArrayListUnmanaged(u8) = .{},
4646
47file_names_buffer: std.ArrayListUnmanaged(u8) = .{},47di_files: std.ArrayListUnmanaged(DIFile) = .{},
48file_names: std.ArrayListUnmanaged(u32) = .{},48di_files_free_list: std.ArrayListUnmanaged(u28) = .{},
49file_names_free_list: std.ArrayListUnmanaged(u28) = .{},49di_files_lookup: std.AutoHashMapUnmanaged(*const Module.File, u28) = .{},
50file_names_lookup: std.AutoHashMapUnmanaged(*Module.File, u28) = .{},
5150
52/// List of atoms that are owned directly by the DWARF module.51/// List of atoms that are owned directly by the DWARF module.
53/// TODO convert links in DebugInfoAtom into indices and make52/// TODO convert links in DebugInfoAtom into indices and make
...@@ -56,6 +55,15 @@ managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},...@@ -56,6 +55,15 @@ managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},
5655
57global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},56global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
5857
58const DIFile = struct {
59 file_source: *const Module.File,
60 ref_count: u32,
61
62 fn getFullPath(dif: DIFile, allocator: Allocator) ![]const u8 {
63 return dif.file_source.fullPath(allocator);
64 }
65};
66
59pub const Atom = struct {67pub const Atom = struct {
60 /// Previous/next linked list pointers.68 /// Previous/next linked list pointers.
61 /// This is the linked list node for this Decl's corresponding .debug_info tag.69 /// This is the linked list node for this Decl's corresponding .debug_info tag.
...@@ -892,7 +900,7 @@ const min_nop_size = 2;...@@ -892,7 +900,7 @@ const min_nop_size = 2;
892/// actual_capacity + (actual_capacity / ideal_factor)900/// actual_capacity + (actual_capacity / ideal_factor)
893const ideal_factor = 3;901const ideal_factor = 3;
894902
895pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf {903pub fn init(allocator: Allocator, bin_file: *File, target: std.Target) Dwarf {
896 const ptr_width: PtrWidth = switch (target.cpu.arch.ptrBitWidth()) {904 const ptr_width: PtrWidth = switch (target.cpu.arch.ptrBitWidth()) {
897 0...32 => .p32,905 0...32 => .p32,
898 33...64 => .p64,906 33...64 => .p64,
...@@ -900,7 +908,7 @@ pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf {...@@ -900,7 +908,7 @@ pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf {
900 };908 };
901 return Dwarf{909 return Dwarf{
902 .allocator = allocator,910 .allocator = allocator,
903 .tag = tag,911 .bin_file = bin_file,
904 .ptr_width = ptr_width,912 .ptr_width = ptr_width,
905 .target = target,913 .target = target,
906 };914 };
...@@ -911,10 +919,9 @@ pub fn deinit(self: *Dwarf) void {...@@ -911,10 +919,9 @@ pub fn deinit(self: *Dwarf) void {
911 self.dbg_line_fn_free_list.deinit(gpa);919 self.dbg_line_fn_free_list.deinit(gpa);
912 self.atom_free_list.deinit(gpa);920 self.atom_free_list.deinit(gpa);
913 self.strtab.deinit(gpa);921 self.strtab.deinit(gpa);
914 self.file_names_buffer.deinit(gpa);922 self.di_files.deinit(gpa);
915 self.file_names.deinit(gpa);923 self.di_files_free_list.deinit(gpa);
916 self.file_names_free_list.deinit(gpa);924 self.di_files_lookup.deinit(gpa);
917 self.file_names_lookup.deinit(gpa);
918 self.global_abbrev_relocs.deinit(gpa);925 self.global_abbrev_relocs.deinit(gpa);
919926
920 for (self.managed_atoms.items) |atom| {927 for (self.managed_atoms.items) |atom| {
...@@ -977,7 +984,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -977,7 +984,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
977 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);984 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
978 // Once we support more than one source file, this will have the ability to be more985 // Once we support more than one source file, this will have the ability to be more
979 // than one possible value.986 // than one possible value.
980 const file_index = try self.addFileName(mod, decl_index);987 const file_index = try self.addDIFile(mod, decl_index);
981 leb128.writeUnsignedFixed(988 leb128.writeUnsignedFixed(
982 4,989 4,
983 dbg_line_buffer.addManyAsArrayAssumeCapacity(4),990 dbg_line_buffer.addManyAsArrayAssumeCapacity(4),
...@@ -1008,7 +1015,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -1008,7 +1015,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
1008 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data41015 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
1009 //1016 //
1010 if (fn_ret_has_bits) {1017 if (fn_ret_has_bits) {
1011 const atom = getDbgInfoAtom(self.tag, mod, decl_index);1018 const atom = getDbgInfoAtom(self.bin_file.tag, mod, decl_index);
1012 try decl_state.addTypeRelocGlobal(atom, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));1019 try decl_state.addTypeRelocGlobal(atom, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len));
1013 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref41020 dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4
1014 }1021 }
...@@ -1026,7 +1033,6 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -1026,7 +1033,6 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
10261033
1027pub fn commitDeclState(1034pub fn commitDeclState(
1028 self: *Dwarf,1035 self: *Dwarf,
1029 file: *File,
1030 module: *Module,1036 module: *Module,
1031 decl_index: Module.Decl.Index,1037 decl_index: Module.Decl.Index,
1032 sym_addr: u64,1038 sym_addr: u64,
...@@ -1082,7 +1088,7 @@ pub fn commitDeclState(...@@ -1082,7 +1088,7 @@ pub fn commitDeclState(
1082 // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for1088 // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for
1083 // `TextBlock` and the .debug_info. If you are editing this logic, you1089 // `TextBlock` and the .debug_info. If you are editing this logic, you
1084 // probably need to edit that logic too.1090 // probably need to edit that logic too.
1085 const src_fn = switch (self.tag) {1091 const src_fn = switch (self.bin_file.tag) {
1086 .elf => &decl.fn_link.elf,1092 .elf => &decl.fn_link.elf,
1087 .macho => &decl.fn_link.macho,1093 .macho => &decl.fn_link.macho,
1088 .wasm => &decl.fn_link.wasm.src_fn,1094 .wasm => &decl.fn_link.wasm.src_fn,
...@@ -1103,22 +1109,22 @@ pub fn commitDeclState(...@@ -1103,22 +1109,22 @@ pub fn commitDeclState(
1103 next.prev = src_fn.prev;1109 next.prev = src_fn.prev;
1104 src_fn.next = null;1110 src_fn.next = null;
1105 // Populate where it used to be with NOPs.1111 // Populate where it used to be with NOPs.
1106 switch (self.tag) {1112 switch (self.bin_file.tag) {
1107 .elf => {1113 .elf => {
1108 const elf_file = file.cast(File.Elf).?;1114 const elf_file = self.bin_file.cast(File.Elf).?;
1109 const debug_line_sect = &elf_file.sections.items[elf_file.debug_line_section_index.?];1115 const debug_line_sect = &elf_file.sections.items[elf_file.debug_line_section_index.?];
1110 const file_pos = debug_line_sect.sh_offset + src_fn.off;1116 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1111 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);1117 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1112 },1118 },
1113 .macho => {1119 .macho => {
1114 const macho_file = file.cast(File.MachO).?;1120 const macho_file = self.bin_file.cast(File.MachO).?;
1115 const d_sym = &macho_file.d_sym.?;1121 const d_sym = &macho_file.d_sym.?;
1116 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];1122 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];
1117 const file_pos = debug_line_sect.offset + src_fn.off;1123 const file_pos = debug_line_sect.offset + src_fn.off;
1118 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);1124 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1119 },1125 },
1120 .wasm => {1126 .wasm => {
1121 const wasm_file = file.cast(File.Wasm).?;1127 const wasm_file = self.bin_file.cast(File.Wasm).?;
1122 const debug_line = wasm_file.debug_line_atom.?.code;1128 const debug_line = wasm_file.debug_line_atom.?.code;
1123 writeDbgLineNopsBuffered(debug_line.items, src_fn.off, 0, &.{}, src_fn.len);1129 writeDbgLineNopsBuffered(debug_line.items, src_fn.off, 0, &.{}, src_fn.len);
1124 },1130 },
...@@ -1156,9 +1162,9 @@ pub fn commitDeclState(...@@ -1156,9 +1162,9 @@ pub fn commitDeclState(
11561162
1157 // We only have support for one compilation unit so far, so the offsets are directly1163 // We only have support for one compilation unit so far, so the offsets are directly
1158 // from the .debug_line section.1164 // from the .debug_line section.
1159 switch (self.tag) {1165 switch (self.bin_file.tag) {
1160 .elf => {1166 .elf => {
1161 const elf_file = file.cast(File.Elf).?;1167 const elf_file = self.bin_file.cast(File.Elf).?;
1162 const debug_line_sect = &elf_file.sections.items[elf_file.debug_line_section_index.?];1168 const debug_line_sect = &elf_file.sections.items[elf_file.debug_line_section_index.?];
1163 if (needed_size != debug_line_sect.sh_size) {1169 if (needed_size != debug_line_sect.sh_size) {
1164 if (needed_size > elf_file.allocatedSize(debug_line_sect.sh_offset)) {1170 if (needed_size > elf_file.allocatedSize(debug_line_sect.sh_offset)) {
...@@ -1193,7 +1199,7 @@ pub fn commitDeclState(...@@ -1193,7 +1199,7 @@ pub fn commitDeclState(
1193 },1199 },
11941200
1195 .macho => {1201 .macho => {
1196 const macho_file = file.cast(File.MachO).?;1202 const macho_file = self.bin_file.cast(File.MachO).?;
1197 const d_sym = &macho_file.d_sym.?;1203 const d_sym = &macho_file.d_sym.?;
1198 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];1204 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];
1199 if (needed_size != debug_line_sect.size) {1205 if (needed_size != debug_line_sect.size) {
...@@ -1228,7 +1234,7 @@ pub fn commitDeclState(...@@ -1228,7 +1234,7 @@ pub fn commitDeclState(
1228 },1234 },
12291235
1230 .wasm => {1236 .wasm => {
1231 const wasm_file = file.cast(File.Wasm).?;1237 const wasm_file = self.bin_file.cast(File.Wasm).?;
1232 const atom = wasm_file.debug_line_atom.?;1238 const atom = wasm_file.debug_line_atom.?;
1233 const debug_line = &atom.code;1239 const debug_line = &atom.code;
1234 const segment_size = debug_line.items.len;1240 const segment_size = debug_line.items.len;
...@@ -1261,7 +1267,7 @@ pub fn commitDeclState(...@@ -1261,7 +1267,7 @@ pub fn commitDeclState(
1261 if (dbg_info_buffer.items.len == 0)1267 if (dbg_info_buffer.items.len == 0)
1262 return;1268 return;
12631269
1264 const atom = getDbgInfoAtom(self.tag, module, decl_index);1270 const atom = getDbgInfoAtom(self.bin_file.tag, module, decl_index);
1265 if (decl_state.abbrev_table.items.len > 0) {1271 if (decl_state.abbrev_table.items.len > 0) {
1266 // Now we emit the .debug_info types of the Decl. These will count towards the size of1272 // Now we emit the .debug_info types of the Decl. These will count towards the size of
1267 // the buffer, so we have to do it before computing the offset, and we can't perform the actual1273 // the buffer, so we have to do it before computing the offset, and we can't perform the actual
...@@ -1288,7 +1294,7 @@ pub fn commitDeclState(...@@ -1288,7 +1294,7 @@ pub fn commitDeclState(
1288 }1294 }
12891295
1290 log.debug("updateDeclDebugInfoAllocation for '{s}'", .{decl.name});1296 log.debug("updateDeclDebugInfoAllocation for '{s}'", .{decl.name});
1291 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));1297 try self.updateDeclDebugInfoAllocation(atom, @intCast(u32, dbg_info_buffer.items.len));
12921298
1293 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {1299 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
1294 if (reloc.target) |target| {1300 if (reloc.target) |target| {
...@@ -1333,9 +1339,9 @@ pub fn commitDeclState(...@@ -1333,9 +1339,9 @@ pub fn commitDeclState(
1333 }1339 }
13341340
1335 while (decl_state.exprloc_relocs.popOrNull()) |reloc| {1341 while (decl_state.exprloc_relocs.popOrNull()) |reloc| {
1336 switch (self.tag) {1342 switch (self.bin_file.tag) {
1337 .macho => {1343 .macho => {
1338 const macho_file = file.cast(File.MachO).?;1344 const macho_file = self.bin_file.cast(File.MachO).?;
1339 const d_sym = &macho_file.d_sym.?;1345 const d_sym = &macho_file.d_sym.?;
1340 try d_sym.relocs.append(d_sym.allocator, .{1346 try d_sym.relocs.append(d_sym.allocator, .{
1341 .type = switch (reloc.type) {1347 .type = switch (reloc.type) {
...@@ -1353,10 +1359,10 @@ pub fn commitDeclState(...@@ -1353,10 +1359,10 @@ pub fn commitDeclState(
1353 }1359 }
13541360
1355 log.debug("writeDeclDebugInfo for '{s}", .{decl.name});1361 log.debug("writeDeclDebugInfo for '{s}", .{decl.name});
1356 try self.writeDeclDebugInfo(file, atom, dbg_info_buffer.items);1362 try self.writeDeclDebugInfo(atom, dbg_info_buffer.items);
1357}1363}
13581364
1359fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u32) !void {1365fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {
1360 const tracy = trace(@src());1366 const tracy = trace(@src());
1361 defer tracy.end();1367 defer tracy.end();
13621368
...@@ -1379,22 +1385,22 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u3...@@ -1379,22 +1385,22 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u3
1379 next.prev = atom.prev;1385 next.prev = atom.prev;
1380 atom.next = null;1386 atom.next = null;
1381 // Populate where it used to be with NOPs.1387 // Populate where it used to be with NOPs.
1382 switch (self.tag) {1388 switch (self.bin_file.tag) {
1383 .elf => {1389 .elf => {
1384 const elf_file = file.cast(File.Elf).?;1390 const elf_file = self.bin_file.cast(File.Elf).?;
1385 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];1391 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];
1386 const file_pos = debug_info_sect.sh_offset + atom.off;1392 const file_pos = debug_info_sect.sh_offset + atom.off;
1387 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);1393 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1388 },1394 },
1389 .macho => {1395 .macho => {
1390 const macho_file = file.cast(File.MachO).?;1396 const macho_file = self.bin_file.cast(File.MachO).?;
1391 const d_sym = &macho_file.d_sym.?;1397 const d_sym = &macho_file.d_sym.?;
1392 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];1398 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];
1393 const file_pos = debug_info_sect.offset + atom.off;1399 const file_pos = debug_info_sect.offset + atom.off;
1394 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);1400 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1395 },1401 },
1396 .wasm => {1402 .wasm => {
1397 const wasm_file = file.cast(File.Wasm).?;1403 const wasm_file = self.bin_file.cast(File.Wasm).?;
1398 const debug_info = &wasm_file.debug_info_atom.?.code;1404 const debug_info = &wasm_file.debug_info_atom.?.code;
1399 try writeDbgInfoNopsToArrayList(gpa, debug_info, atom.off, 0, &.{0}, atom.len, false);1405 try writeDbgInfoNopsToArrayList(gpa, debug_info, atom.off, 0, &.{0}, atom.len, false);
1400 },1406 },
...@@ -1425,7 +1431,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u3...@@ -1425,7 +1431,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u3
1425 }1431 }
1426}1432}
14271433
1428fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []const u8) !void {1434fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void {
1429 const tracy = trace(@src());1435 const tracy = trace(@src());
1430 defer tracy.end();1436 defer tracy.end();
14311437
...@@ -1445,9 +1451,9 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co...@@ -1445,9 +1451,9 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co
14451451
1446 // We only have support for one compilation unit so far, so the offsets are directly1452 // We only have support for one compilation unit so far, so the offsets are directly
1447 // from the .debug_info section.1453 // from the .debug_info section.
1448 switch (self.tag) {1454 switch (self.bin_file.tag) {
1449 .elf => {1455 .elf => {
1450 const elf_file = file.cast(File.Elf).?;1456 const elf_file = self.bin_file.cast(File.Elf).?;
1451 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];1457 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];
1452 if (needed_size != debug_info_sect.sh_size) {1458 if (needed_size != debug_info_sect.sh_size) {
1453 if (needed_size > elf_file.allocatedSize(debug_info_sect.sh_offset)) {1459 if (needed_size > elf_file.allocatedSize(debug_info_sect.sh_offset)) {
...@@ -1483,7 +1489,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co...@@ -1483,7 +1489,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co
1483 },1489 },
14841490
1485 .macho => {1491 .macho => {
1486 const macho_file = file.cast(File.MachO).?;1492 const macho_file = self.bin_file.cast(File.MachO).?;
1487 const d_sym = &macho_file.d_sym.?;1493 const d_sym = &macho_file.d_sym.?;
1488 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];1494 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];
1489 if (needed_size != debug_info_sect.size) {1495 if (needed_size != debug_info_sect.size) {
...@@ -1519,7 +1525,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co...@@ -1519,7 +1525,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co
1519 },1525 },
15201526
1521 .wasm => {1527 .wasm => {
1522 const wasm_file = file.cast(File.Wasm).?;1528 const wasm_file = self.bin_file.cast(File.Wasm).?;
1523 const info_atom = wasm_file.debug_info_atom.?;1529 const info_atom = wasm_file.debug_info_atom.?;
1524 const debug_info = &info_atom.code;1530 const debug_info = &info_atom.code;
1525 const segment_size = debug_info.items.len;1531 const segment_size = debug_info.items.len;
...@@ -1549,7 +1555,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co...@@ -1549,7 +1555,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co
1549 }1555 }
1550}1556}
15511557
1552pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl) !void {1558pub fn updateDeclLineNumber(self: *Dwarf, decl: *const Module.Decl) !void {
1553 const tracy = trace(@src());1559 const tracy = trace(@src());
1554 defer tracy.end();1560 defer tracy.end();
15551561
...@@ -1563,22 +1569,22 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl)...@@ -1563,22 +1569,22 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl)
1563 var data: [4]u8 = undefined;1569 var data: [4]u8 = undefined;
1564 leb128.writeUnsignedFixed(4, &data, line);1570 leb128.writeUnsignedFixed(4, &data, line);
15651571
1566 switch (self.tag) {1572 switch (self.bin_file.tag) {
1567 .elf => {1573 .elf => {
1568 const elf_file = file.cast(File.Elf).?;1574 const elf_file = self.bin_file.cast(File.Elf).?;
1569 const shdr = elf_file.sections.items[elf_file.debug_line_section_index.?];1575 const shdr = elf_file.sections.items[elf_file.debug_line_section_index.?];
1570 const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff();1576 const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff();
1571 try elf_file.base.file.?.pwriteAll(&data, file_pos);1577 try elf_file.base.file.?.pwriteAll(&data, file_pos);
1572 },1578 },
1573 .macho => {1579 .macho => {
1574 const macho_file = file.cast(File.MachO).?;1580 const macho_file = self.bin_file.cast(File.MachO).?;
1575 const d_sym = macho_file.d_sym.?;1581 const d_sym = macho_file.d_sym.?;
1576 const sect = d_sym.sections.items[d_sym.debug_line_section_index.?];1582 const sect = d_sym.sections.items[d_sym.debug_line_section_index.?];
1577 const file_pos = sect.offset + decl.fn_link.macho.off + self.getRelocDbgLineOff();1583 const file_pos = sect.offset + decl.fn_link.macho.off + self.getRelocDbgLineOff();
1578 try d_sym.file.pwriteAll(&data, file_pos);1584 try d_sym.file.pwriteAll(&data, file_pos);
1579 },1585 },
1580 .wasm => {1586 .wasm => {
1581 const wasm_file = file.cast(File.Wasm).?;1587 const wasm_file = self.bin_file.cast(File.Wasm).?;
1582 const offset = decl.fn_link.wasm.src_fn.off + self.getRelocDbgLineOff();1588 const offset = decl.fn_link.wasm.src_fn.off + self.getRelocDbgLineOff();
1583 const atom = wasm_file.debug_line_atom.?;1589 const atom = wasm_file.debug_line_atom.?;
1584 mem.copy(u8, atom.code.items[offset..], &data);1590 mem.copy(u8, atom.code.items[offset..], &data);
...@@ -1615,7 +1621,7 @@ pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void {...@@ -1615,7 +1621,7 @@ pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void {
1615 // TODO make this logic match freeTextBlock. Maybe abstract the logic out since the same thing1621 // TODO make this logic match freeTextBlock. Maybe abstract the logic out since the same thing
1616 // is desired for both.1622 // is desired for both.
1617 const gpa = self.allocator;1623 const gpa = self.allocator;
1618 const fn_link = switch (self.tag) {1624 const fn_link = switch (self.bin_file.tag) {
1619 .elf => &decl.fn_link.elf,1625 .elf => &decl.fn_link.elf,
1620 .macho => &decl.fn_link.macho,1626 .macho => &decl.fn_link.macho,
1621 .wasm => &decl.fn_link.wasm.src_fn,1627 .wasm => &decl.fn_link.wasm.src_fn,
...@@ -1641,9 +1647,19 @@ pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void {...@@ -1641,9 +1647,19 @@ pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void {
1641 if (self.dbg_line_fn_last == fn_link) {1647 if (self.dbg_line_fn_last == fn_link) {
1642 self.dbg_line_fn_last = fn_link.prev;1648 self.dbg_line_fn_last = fn_link.prev;
1643 }1649 }
1650
1651 const file_source = decl.getFileScope();
1652 if (self.di_files_lookup.get(file_source)) |dif_index| {
1653 const dif = &self.di_files.items[dif_index];
1654 dif.ref_count -= 1;
1655 if (dif.ref_count == 0) {
1656 self.di_files_free_list.append(gpa, dif_index) catch {};
1657 }
1658 _ = self.di_files_lookup.remove(file_source);
1659 }
1644}1660}
16451661
1646pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {1662pub fn writeDbgAbbrev(self: *Dwarf) !void {
1647 // These are LEB encoded but since the values are all less than 1271663 // These are LEB encoded but since the values are all less than 127
1648 // we can simply append these bytes.1664 // we can simply append these bytes.
1649 const abbrev_buf = [_]u8{1665 const abbrev_buf = [_]u8{
...@@ -1777,9 +1793,9 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1777,9 +1793,9 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1777 self.abbrev_table_offset = abbrev_offset;1793 self.abbrev_table_offset = abbrev_offset;
17781794
1779 const needed_size = abbrev_buf.len;1795 const needed_size = abbrev_buf.len;
1780 switch (self.tag) {1796 switch (self.bin_file.tag) {
1781 .elf => {1797 .elf => {
1782 const elf_file = file.cast(File.Elf).?;1798 const elf_file = self.bin_file.cast(File.Elf).?;
1783 const debug_abbrev_sect = &elf_file.sections.items[elf_file.debug_abbrev_section_index.?];1799 const debug_abbrev_sect = &elf_file.sections.items[elf_file.debug_abbrev_section_index.?];
1784 const allocated_size = elf_file.allocatedSize(debug_abbrev_sect.sh_offset);1800 const allocated_size = elf_file.allocatedSize(debug_abbrev_sect.sh_offset);
1785 if (needed_size > allocated_size) {1801 if (needed_size > allocated_size) {
...@@ -1796,7 +1812,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1796,7 +1812,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1796 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);1812 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1797 },1813 },
1798 .macho => {1814 .macho => {
1799 const macho_file = file.cast(File.MachO).?;1815 const macho_file = self.bin_file.cast(File.MachO).?;
1800 const d_sym = &macho_file.d_sym.?;1816 const d_sym = &macho_file.d_sym.?;
1801 const dwarf_segment = d_sym.segments.items[d_sym.dwarf_segment_cmd_index.?];1817 const dwarf_segment = d_sym.segments.items[d_sym.dwarf_segment_cmd_index.?];
1802 const debug_abbrev_sect = &d_sym.sections.items[d_sym.debug_abbrev_section_index.?];1818 const debug_abbrev_sect = &d_sym.sections.items[d_sym.debug_abbrev_section_index.?];
...@@ -1816,7 +1832,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1816,7 +1832,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1816 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);1832 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);
1817 },1833 },
1818 .wasm => {1834 .wasm => {
1819 const wasm_file = file.cast(File.Wasm).?;1835 const wasm_file = self.bin_file.cast(File.Wasm).?;
1820 const debug_abbrev = &wasm_file.debug_abbrev_atom.?.code;1836 const debug_abbrev = &wasm_file.debug_abbrev_atom.?.code;
1821 try debug_abbrev.resize(wasm_file.base.allocator, needed_size);1837 try debug_abbrev.resize(wasm_file.base.allocator, needed_size);
1822 mem.copy(u8, debug_abbrev.items, &abbrev_buf);1838 mem.copy(u8, debug_abbrev.items, &abbrev_buf);
...@@ -1830,7 +1846,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize {...@@ -1830,7 +1846,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize {
1830 return 120;1846 return 120;
1831}1847}
18321848
1833pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u64, high_pc: u64) !void {1849pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u64) !void {
1834 // If this value is null it means there is an error in the module;1850 // If this value is null it means there is an error in the module;
1835 // leave debug_info_header_dirty=true.1851 // leave debug_info_header_dirty=true.
1836 const first_dbg_info_off = self.getDebugInfoOff() orelse return;1852 const first_dbg_info_off = self.getDebugInfoOff() orelse return;
...@@ -1842,7 +1858,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6...@@ -1842,7 +1858,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
1842 defer di_buf.deinit();1858 defer di_buf.deinit();
18431859
1844 const target_endian = self.target.cpu.arch.endian();1860 const target_endian = self.target.cpu.arch.endian();
1845 const init_len_size: usize = if (self.tag == .macho)1861 const init_len_size: usize = if (self.bin_file.tag == .macho)
1846 41862 4
1847 else switch (self.ptr_width) {1863 else switch (self.ptr_width) {
1848 .p32 => @as(usize, 4),1864 .p32 => @as(usize, 4),
...@@ -1856,7 +1872,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6...@@ -1856,7 +1872,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
1856 // +1 for the final 0 that ends the compilation unit children.1872 // +1 for the final 0 that ends the compilation unit children.
1857 const dbg_info_end = self.getDebugInfoEnd().? + 1;1873 const dbg_info_end = self.getDebugInfoEnd().? + 1;
1858 const init_len = dbg_info_end - after_init_len;1874 const init_len = dbg_info_end - after_init_len;
1859 if (self.tag == .macho) {1875 if (self.bin_file.tag == .macho) {
1860 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len));1876 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len));
1861 } else switch (self.ptr_width) {1877 } else switch (self.ptr_width) {
1862 .p32 => {1878 .p32 => {
...@@ -1869,7 +1885,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6...@@ -1869,7 +1885,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
1869 }1885 }
1870 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // DWARF version1886 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 4, target_endian); // DWARF version
1871 const abbrev_offset = self.abbrev_table_offset.?;1887 const abbrev_offset = self.abbrev_table_offset.?;
1872 if (self.tag == .macho) {1888 if (self.bin_file.tag == .macho) {
1873 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, abbrev_offset));1889 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, abbrev_offset));
1874 di_buf.appendAssumeCapacity(8); // address size1890 di_buf.appendAssumeCapacity(8); // address size
1875 } else switch (self.ptr_width) {1891 } else switch (self.ptr_width) {
...@@ -1888,7 +1904,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6...@@ -1888,7 +1904,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
1888 const producer_strp = try self.makeString(link.producer_string);1904 const producer_strp = try self.makeString(link.producer_string);
18891905
1890 di_buf.appendAssumeCapacity(@enumToInt(AbbrevKind.compile_unit));1906 di_buf.appendAssumeCapacity(@enumToInt(AbbrevKind.compile_unit));
1891 if (self.tag == .macho) {1907 if (self.bin_file.tag == .macho) {
1892 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset1908 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset
1893 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);1909 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);
1894 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc);1910 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc);
...@@ -1913,22 +1929,22 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6...@@ -1913,22 +1929,22 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
1913 @panic("TODO: handle .debug_info header exceeding its padding");1929 @panic("TODO: handle .debug_info header exceeding its padding");
1914 }1930 }
1915 const jmp_amt = first_dbg_info_off - di_buf.items.len;1931 const jmp_amt = first_dbg_info_off - di_buf.items.len;
1916 switch (self.tag) {1932 switch (self.bin_file.tag) {
1917 .elf => {1933 .elf => {
1918 const elf_file = file.cast(File.Elf).?;1934 const elf_file = self.bin_file.cast(File.Elf).?;
1919 const debug_info_sect = elf_file.sections.items[elf_file.debug_info_section_index.?];1935 const debug_info_sect = elf_file.sections.items[elf_file.debug_info_section_index.?];
1920 const file_pos = debug_info_sect.sh_offset;1936 const file_pos = debug_info_sect.sh_offset;
1921 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);1937 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
1922 },1938 },
1923 .macho => {1939 .macho => {
1924 const macho_file = file.cast(File.MachO).?;1940 const macho_file = self.bin_file.cast(File.MachO).?;
1925 const d_sym = &macho_file.d_sym.?;1941 const d_sym = &macho_file.d_sym.?;
1926 const debug_info_sect = d_sym.sections.items[d_sym.debug_info_section_index.?];1942 const debug_info_sect = d_sym.sections.items[d_sym.debug_info_section_index.?];
1927 const file_pos = debug_info_sect.offset;1943 const file_pos = debug_info_sect.offset;
1928 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);1944 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
1929 },1945 },
1930 .wasm => {1946 .wasm => {
1931 const wasm_file = file.cast(File.Wasm).?;1947 const wasm_file = self.bin_file.cast(File.Wasm).?;
1932 const debug_info = &wasm_file.debug_info_atom.?.code;1948 const debug_info = &wasm_file.debug_info_atom.?.code;
1933 try writeDbgInfoNopsToArrayList(self.allocator, debug_info, 0, 0, di_buf.items, jmp_amt, false);1949 try writeDbgInfoNopsToArrayList(self.allocator, debug_info, 0, 0, di_buf.items, jmp_amt, false);
1934 },1950 },
...@@ -2158,9 +2174,9 @@ fn writeDbgInfoNopsToArrayList(...@@ -2158,9 +2174,9 @@ fn writeDbgInfoNopsToArrayList(
2158 }2174 }
2159}2175}
21602176
2161pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {2177pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
2162 const target_endian = self.target.cpu.arch.endian();2178 const target_endian = self.target.cpu.arch.endian();
2163 const init_len_size: usize = if (self.tag == .macho)2179 const init_len_size: usize = if (self.bin_file.tag == .macho)
2164 42180 4
2165 else switch (self.ptr_width) {2181 else switch (self.ptr_width) {
2166 .p32 => @as(usize, 4),2182 .p32 => @as(usize, 4),
...@@ -2182,7 +2198,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -2182,7 +2198,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
2182 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 2, target_endian); // version2198 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), 2, target_endian); // version
2183 // When more than one compilation unit is supported, this will be the offset to it.2199 // When more than one compilation unit is supported, this will be the offset to it.
2184 // For now it is always at offset 0 in .debug_info.2200 // For now it is always at offset 0 in .debug_info.
2185 if (self.tag == .macho) {2201 if (self.bin_file.tag == .macho) {
2186 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // __debug_info offset2202 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // __debug_info offset
2187 } else {2203 } else {
2188 self.writeAddrAssumeCapacity(&di_buf, 0); // .debug_info offset2204 self.writeAddrAssumeCapacity(&di_buf, 0); // .debug_info offset
...@@ -2205,7 +2221,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -2205,7 +2221,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
22052221
2206 // Go back and populate the initial length.2222 // Go back and populate the initial length.
2207 const init_len = di_buf.items.len - after_init_len;2223 const init_len = di_buf.items.len - after_init_len;
2208 if (self.tag == .macho) {2224 if (self.bin_file.tag == .macho) {
2209 mem.writeIntLittle(u32, di_buf.items[init_len_index..][0..4], @intCast(u32, init_len));2225 mem.writeIntLittle(u32, di_buf.items[init_len_index..][0..4], @intCast(u32, init_len));
2210 } else switch (self.ptr_width) {2226 } else switch (self.ptr_width) {
2211 .p32 => {2227 .p32 => {
...@@ -2220,9 +2236,9 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -2220,9 +2236,9 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
2220 }2236 }
22212237
2222 const needed_size = di_buf.items.len;2238 const needed_size = di_buf.items.len;
2223 switch (self.tag) {2239 switch (self.bin_file.tag) {
2224 .elf => {2240 .elf => {
2225 const elf_file = file.cast(File.Elf).?;2241 const elf_file = self.bin_file.cast(File.Elf).?;
2226 const debug_aranges_sect = &elf_file.sections.items[elf_file.debug_aranges_section_index.?];2242 const debug_aranges_sect = &elf_file.sections.items[elf_file.debug_aranges_section_index.?];
2227 const allocated_size = elf_file.allocatedSize(debug_aranges_sect.sh_offset);2243 const allocated_size = elf_file.allocatedSize(debug_aranges_sect.sh_offset);
2228 if (needed_size > allocated_size) {2244 if (needed_size > allocated_size) {
...@@ -2238,7 +2254,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -2238,7 +2254,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
2238 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);2254 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2239 },2255 },
2240 .macho => {2256 .macho => {
2241 const macho_file = file.cast(File.MachO).?;2257 const macho_file = self.bin_file.cast(File.MachO).?;
2242 const d_sym = &macho_file.d_sym.?;2258 const d_sym = &macho_file.d_sym.?;
2243 const dwarf_seg = d_sym.segments.items[d_sym.dwarf_segment_cmd_index.?];2259 const dwarf_seg = d_sym.segments.items[d_sym.dwarf_segment_cmd_index.?];
2244 const debug_aranges_sect = &d_sym.sections.items[d_sym.debug_aranges_section_index.?];2260 const debug_aranges_sect = &d_sym.sections.items[d_sym.debug_aranges_section_index.?];
...@@ -2258,7 +2274,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -2258,7 +2274,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
2258 try d_sym.file.pwriteAll(di_buf.items, file_pos);2274 try d_sym.file.pwriteAll(di_buf.items, file_pos);
2259 },2275 },
2260 .wasm => {2276 .wasm => {
2261 const wasm_file = file.cast(File.Wasm).?;2277 const wasm_file = self.bin_file.cast(File.Wasm).?;
2262 const debug_ranges = &wasm_file.debug_ranges_atom.?.code;2278 const debug_ranges = &wasm_file.debug_ranges_atom.?.code;
2263 try debug_ranges.resize(wasm_file.base.allocator, needed_size);2279 try debug_ranges.resize(wasm_file.base.allocator, needed_size);
2264 mem.copy(u8, debug_ranges.items, di_buf.items);2280 mem.copy(u8, debug_ranges.items, di_buf.items);
...@@ -2267,10 +2283,10 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -2267,10 +2283,10 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
2267 }2283 }
2268}2284}
22692285
2270pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {2286pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
2271 const ptr_width_bytes: u8 = self.ptrWidthBytes();2287 const ptr_width_bytes: u8 = self.ptrWidthBytes();
2272 const target_endian = self.target.cpu.arch.endian();2288 const target_endian = self.target.cpu.arch.endian();
2273 const init_len_size: usize = if (self.tag == .macho)2289 const init_len_size: usize = if (self.bin_file.tag == .macho)
2274 42290 4
2275 else switch (self.ptr_width) {2291 else switch (self.ptr_width) {
2276 .p32 => @as(usize, 4),2292 .p32 => @as(usize, 4),
...@@ -2293,7 +2309,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2293,7 +2309,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2293 // not including the initial length itself.2309 // not including the initial length itself.
2294 const after_init_len = di_buf.items.len + init_len_size;2310 const after_init_len = di_buf.items.len + init_len_size;
2295 const init_len = dbg_line_prg_end - after_init_len;2311 const init_len = dbg_line_prg_end - after_init_len;
2296 if (self.tag == .macho) {2312 if (self.bin_file.tag == .macho) {
2297 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len));2313 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, init_len));
2298 } else switch (self.ptr_width) {2314 } else switch (self.ptr_width) {
2299 .p32 => {2315 .p32 => {
...@@ -2312,7 +2328,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2312,7 +2328,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2312 // Therefore we rely on the NOP jump at the beginning of the Line Number Program for2328 // Therefore we rely on the NOP jump at the beginning of the Line Number Program for
2313 // padding rather than this field.2329 // padding rather than this field.
2314 const before_header_len = di_buf.items.len;2330 const before_header_len = di_buf.items.len;
2315 di_buf.items.len += if (self.tag == .macho) @sizeOf(u32) else ptr_width_bytes; // We will come back and write this.2331 di_buf.items.len += if (self.bin_file.tag == .macho) @sizeOf(u32) else ptr_width_bytes; // We will come back and write this.
2316 const after_header_len = di_buf.items.len;2332 const after_header_len = di_buf.items.len;
23172333
2318 const opcode_base = DW.LNS.set_isa + 1;2334 const opcode_base = DW.LNS.set_isa + 1;
...@@ -2340,20 +2356,12 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2340,20 +2356,12 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2340 1, // `DW.LNS.set_isa`2356 1, // `DW.LNS.set_isa`
2341 0, // include_directories (none except the compilation unit cwd)2357 0, // include_directories (none except the compilation unit cwd)
2342 });2358 });
2343 // // file_names[0]2359
2344 // di_buf.appendSliceAssumeCapacity(module.root_pkg.root_src_path); // relative path name2360 for (self.di_files.items) |dif, i| {
2345 // di_buf.appendSliceAssumeCapacity(&[_]u8{2361 const full_path = try dif.getFullPath(self.allocator);
2346 // 0, // null byte for the relative path name2362 defer self.allocator.free(full_path);
2347 // 0, // directory_index2363 log.debug("adding new file name at {d} of '{s}'", .{ i + 1, full_path });
2348 // 0, // mtime (TODO supply this)2364 di_buf.appendSliceAssumeCapacity(full_path);
2349 // 0, // file size bytes (TODO supply this)
2350 // 0, // file_names sentinel
2351 // });
2352
2353 for (self.file_names.items) |off, i| {
2354 const file_name = self.getFileName(off);
2355 log.debug("file_name[{d}] = {s}", .{ i + 1, file_name });
2356 di_buf.appendSliceAssumeCapacity(file_name);
2357 di_buf.appendSliceAssumeCapacity(&[_]u8{2365 di_buf.appendSliceAssumeCapacity(&[_]u8{
2358 0, // null byte for the relative path name2366 0, // null byte for the relative path name
2359 0, // directory_index2367 0, // directory_index
...@@ -2364,7 +2372,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2364,7 +2372,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2364 di_buf.appendAssumeCapacity(0); // file names sentinel2372 di_buf.appendAssumeCapacity(0); // file names sentinel
23652373
2366 const header_len = di_buf.items.len - after_header_len;2374 const header_len = di_buf.items.len - after_header_len;
2367 if (self.tag == .macho) {2375 if (self.bin_file.tag == .macho) {
2368 mem.writeIntLittle(u32, di_buf.items[before_header_len..][0..4], @intCast(u32, header_len));2376 mem.writeIntLittle(u32, di_buf.items[before_header_len..][0..4], @intCast(u32, header_len));
2369 } else switch (self.ptr_width) {2377 } else switch (self.ptr_width) {
2370 .p32 => {2378 .p32 => {
...@@ -2381,22 +2389,22 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2381,22 +2389,22 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2381 @panic("TODO: handle .debug_line header exceeding its padding");2389 @panic("TODO: handle .debug_line header exceeding its padding");
2382 }2390 }
2383 const jmp_amt = dbg_line_prg_off - di_buf.items.len;2391 const jmp_amt = dbg_line_prg_off - di_buf.items.len;
2384 switch (self.tag) {2392 switch (self.bin_file.tag) {
2385 .elf => {2393 .elf => {
2386 const elf_file = file.cast(File.Elf).?;2394 const elf_file = self.bin_file.cast(File.Elf).?;
2387 const debug_line_sect = elf_file.sections.items[elf_file.debug_line_section_index.?];2395 const debug_line_sect = elf_file.sections.items[elf_file.debug_line_section_index.?];
2388 const file_pos = debug_line_sect.sh_offset;2396 const file_pos = debug_line_sect.sh_offset;
2389 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);2397 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2390 },2398 },
2391 .macho => {2399 .macho => {
2392 const macho_file = file.cast(File.MachO).?;2400 const macho_file = self.bin_file.cast(File.MachO).?;
2393 const d_sym = &macho_file.d_sym.?;2401 const d_sym = &macho_file.d_sym.?;
2394 const debug_line_sect = d_sym.sections.items[d_sym.debug_line_section_index.?];2402 const debug_line_sect = d_sym.sections.items[d_sym.debug_line_section_index.?];
2395 const file_pos = debug_line_sect.offset;2403 const file_pos = debug_line_sect.offset;
2396 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);2404 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2397 },2405 },
2398 .wasm => {2406 .wasm => {
2399 const wasm_file = file.cast(File.Wasm).?;2407 const wasm_file = self.bin_file.cast(File.Wasm).?;
2400 const debug_line = wasm_file.debug_line_atom.?.code;2408 const debug_line = wasm_file.debug_line_atom.?.code;
2401 writeDbgLineNopsBuffered(debug_line.items, 0, 0, di_buf.items, jmp_amt);2409 writeDbgLineNopsBuffered(debug_line.items, 0, 0, di_buf.items, jmp_amt);
2402 },2410 },
...@@ -2436,15 +2444,21 @@ fn dbgLineNeededHeaderBytes(self: Dwarf, module: *Module) u32 {...@@ -2436,15 +2444,21 @@ fn dbgLineNeededHeaderBytes(self: Dwarf, module: *Module) u32 {
2436 const directory_entry_format_count = 1;2444 const directory_entry_format_count = 1;
2437 const file_name_entry_format_count = 1;2445 const file_name_entry_format_count = 1;
2438 const directory_count = 1;2446 const directory_count = 1;
2439 const file_name_count = self.file_names.items.len;2447 const file_name_count = self.di_files.items.len;
2440 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."2448 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."
24412449
2450 var file_names_len: usize = 0;
2451 for (self.di_files.items) |dif| {
2452 const dir_path = dif.file_source.pkg.root_src_directory.path orelse ".";
2453 file_names_len += dir_path.len + dif.file_source.sub_file_path.len + 1;
2454 }
2455
2442 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +2456 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
2443 directory_count * 8 + file_name_count * 8 +2457 directory_count * 8 + file_name_count * 8 +
2444 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like2458 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like
2445 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.2459 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
2446 root_src_dir_path_len +2460 root_src_dir_path_len +
2447 self.file_names_buffer.items.len);2461 file_names_len);
2448}2462}
24492463
2450/// The reloc offset for the line offset of a function from the previous function's line.2464/// The reloc offset for the line offset of a function from the previous function's line.
...@@ -2476,7 +2490,7 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {...@@ -2476,7 +2490,7 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
2476 std.math.maxInt(@TypeOf(actual_size));2490 std.math.maxInt(@TypeOf(actual_size));
2477}2491}
24782492
2479pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {2493pub fn flushModule(self: *Dwarf, module: *Module) !void {
2480 if (self.global_abbrev_relocs.items.len > 0) {2494 if (self.global_abbrev_relocs.items.len > 0) {
2481 const gpa = self.allocator;2495 const gpa = self.allocator;
2482 var arena_alloc = std.heap.ArenaAllocator.init(gpa);2496 var arena_alloc = std.heap.ArenaAllocator.init(gpa);
...@@ -2507,19 +2521,19 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2507,19 +2521,19 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {
25072521
2508 try self.managed_atoms.append(gpa, atom);2522 try self.managed_atoms.append(gpa, atom);
2509 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});2523 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
2510 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));2524 try self.updateDeclDebugInfoAllocation(atom, @intCast(u32, dbg_info_buffer.items.len));
2511 log.debug("writeDeclDebugInfo in flushModule", .{});2525 log.debug("writeDeclDebugInfo in flushModule", .{});
2512 try self.writeDeclDebugInfo(file, atom, dbg_info_buffer.items);2526 try self.writeDeclDebugInfo(atom, dbg_info_buffer.items);
25132527
2514 const file_pos = blk: {2528 const file_pos = blk: {
2515 switch (self.tag) {2529 switch (self.bin_file.tag) {
2516 .elf => {2530 .elf => {
2517 const elf_file = file.cast(File.Elf).?;2531 const elf_file = self.bin_file.cast(File.Elf).?;
2518 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];2532 const debug_info_sect = &elf_file.sections.items[elf_file.debug_info_section_index.?];
2519 break :blk debug_info_sect.sh_offset;2533 break :blk debug_info_sect.sh_offset;
2520 },2534 },
2521 .macho => {2535 .macho => {
2522 const macho_file = file.cast(File.MachO).?;2536 const macho_file = self.bin_file.cast(File.MachO).?;
2523 const d_sym = &macho_file.d_sym.?;2537 const d_sym = &macho_file.d_sym.?;
2524 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];2538 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];
2525 break :blk debug_info_sect.offset;2539 break :blk debug_info_sect.offset;
...@@ -2534,18 +2548,18 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2534,18 +2548,18 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {
2534 mem.writeInt(u32, &buf, atom.off, self.target.cpu.arch.endian());2548 mem.writeInt(u32, &buf, atom.off, self.target.cpu.arch.endian());
25352549
2536 while (self.global_abbrev_relocs.popOrNull()) |reloc| {2550 while (self.global_abbrev_relocs.popOrNull()) |reloc| {
2537 switch (self.tag) {2551 switch (self.bin_file.tag) {
2538 .elf => {2552 .elf => {
2539 const elf_file = file.cast(File.Elf).?;2553 const elf_file = self.bin_file.cast(File.Elf).?;
2540 try elf_file.base.file.?.pwriteAll(&buf, file_pos + reloc.atom.off + reloc.offset);2554 try elf_file.base.file.?.pwriteAll(&buf, file_pos + reloc.atom.off + reloc.offset);
2541 },2555 },
2542 .macho => {2556 .macho => {
2543 const macho_file = file.cast(File.MachO).?;2557 const macho_file = self.bin_file.cast(File.MachO).?;
2544 const d_sym = &macho_file.d_sym.?;2558 const d_sym = &macho_file.d_sym.?;
2545 try d_sym.file.pwriteAll(&buf, file_pos + reloc.atom.off + reloc.offset);2559 try d_sym.file.pwriteAll(&buf, file_pos + reloc.atom.off + reloc.offset);
2546 },2560 },
2547 .wasm => {2561 .wasm => {
2548 const wasm_file = file.cast(File.Wasm).?;2562 const wasm_file = self.bin_file.cast(File.Wasm).?;
2549 const debug_info = wasm_file.debug_info_atom.?.code;2563 const debug_info = wasm_file.debug_info_atom.?.code;
2550 mem.copy(u8, debug_info.items[reloc.atom.off + reloc.offset ..], &buf);2564 mem.copy(u8, debug_info.items[reloc.atom.off + reloc.offset ..], &buf);
2551 },2565 },
...@@ -2555,17 +2569,17 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2555,17 +2569,17 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {
2555 }2569 }
2556}2570}
25572571
2558fn allocateFileIndex(self: *Dwarf) !u28 {2572fn allocateDIFileIndex(self: *Dwarf) !u28 {
2559 try self.file_names.ensureUnusedCapacity(self.allocator, 1);2573 try self.di_files.ensureUnusedCapacity(self.allocator, 1);
25602574
2561 const index = blk: {2575 const index = blk: {
2562 if (self.file_names_free_list.popOrNull()) |index| {2576 if (self.di_files_free_list.popOrNull()) |index| {
2563 log.debug(" (reusing file name index {d})", .{index});2577 log.debug(" (reusing DIFile index {d})", .{index});
2564 break :blk index;2578 break :blk index;
2565 } else {2579 } else {
2566 const index = @intCast(u28, self.file_names.items.len);2580 const index = @intCast(u28, self.di_files.items.len);
2567 log.debug(" (allocating file name index {d})", .{index});2581 log.debug(" (allocating DIFile index {d})", .{index});
2568 _ = self.file_names.addOneAssumeCapacity();2582 _ = self.di_files.addOneAssumeCapacity();
2569 break :blk index;2583 break :blk index;
2570 }2584 }
2571 };2585 };
...@@ -2573,27 +2587,28 @@ fn allocateFileIndex(self: *Dwarf) !u28 {...@@ -2573,27 +2587,28 @@ fn allocateFileIndex(self: *Dwarf) !u28 {
2573 return index;2587 return index;
2574}2588}
25752589
2576fn addFileName(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {2590fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {
2577 const decl = mod.declPtr(decl_index);2591 const decl = mod.declPtr(decl_index);
2578 const file_scope = decl.getFileScope();2592 const file_scope = decl.getFileScope();
2579 if (self.file_names_lookup.get(file_scope)) |file_index| {2593 const gop = try self.di_files_lookup.getOrPut(self.allocator, file_scope);
2580 return file_index;2594 if (!gop.found_existing) {
2581 }2595 gop.value_ptr.* = try self.allocateDIFileIndex();
2582 const index = try self.allocateFileIndex();2596 self.di_files.items[gop.value_ptr.*] = .{
2583 const file_name = try file_scope.fullPath(self.allocator);2597 .file_source = file_scope,
2584 defer self.allocator.free(file_name);2598 .ref_count = 1,
2585 try self.file_names_buffer.ensureUnusedCapacity(self.allocator, file_name.len + 1);2599 };
2586 const off = @intCast(u32, self.file_names_buffer.items.len);
2587 self.file_names_buffer.appendSliceAssumeCapacity(file_name);
2588 self.file_names_buffer.appendAssumeCapacity(0);
2589 self.file_names.items[index] = off;
2590 try self.file_names_lookup.putNoClobber(self.allocator, file_scope, index);
2591 return index;
2592}
25932600
2594fn getFileName(self: Dwarf, off: u32) []const u8 {2601 switch (self.bin_file.tag) {
2595 assert(off < self.file_names_buffer.items.len);2602 .elf => self.bin_file.cast(File.Elf).?.debug_line_header_dirty = true,
2596 return mem.sliceTo(@ptrCast([*:0]const u8, self.file_names_buffer.items.ptr) + off, 0);2603 .macho => self.bin_file.cast(File.MachO).?.d_sym.?.debug_line_header_dirty = true,
2604 .wasm => {},
2605 else => unreachable,
2606 }
2607 } else {
2608 const dif = &self.di_files.items[gop.value_ptr.*];
2609 dif.ref_count += 1;
2610 }
2611 return gop.value_ptr.*;
2597}2612}
25982613
2599fn addDbgInfoErrorSet(2614fn addDbgInfoErrorSet(
src/link/Elf.zig+7-9
...@@ -312,7 +312,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {...@@ -312,7 +312,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
312 };312 };
313313
314 var dwarf: ?Dwarf = if (!options.strip and options.module != null)314 var dwarf: ?Dwarf = if (!options.strip and options.module != null)
315 Dwarf.init(gpa, .elf, options.target)315 Dwarf.init(gpa, &self.base, options.target)
316 else316 else
317 null;317 null;
318318
...@@ -972,7 +972,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -972,7 +972,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
972 const foreign_endian = target_endian != builtin.cpu.arch.endian();972 const foreign_endian = target_endian != builtin.cpu.arch.endian();
973973
974 if (self.dwarf) |*dw| {974 if (self.dwarf) |*dw| {
975 try dw.flushModule(&self.base, module);975 try dw.flushModule(module);
976 }976 }
977977
978 {978 {
...@@ -1020,7 +1020,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1020,7 +1020,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10201020
1021 if (self.dwarf) |*dw| {1021 if (self.dwarf) |*dw| {
1022 if (self.debug_abbrev_section_dirty) {1022 if (self.debug_abbrev_section_dirty) {
1023 try dw.writeDbgAbbrev(&self.base);1023 try dw.writeDbgAbbrev();
1024 if (!self.shdr_table_dirty) {1024 if (!self.shdr_table_dirty) {
1025 // Then it won't get written with the others and we need to do it.1025 // Then it won't get written with the others and we need to do it.
1026 try self.writeSectHeader(self.debug_abbrev_section_index.?);1026 try self.writeSectHeader(self.debug_abbrev_section_index.?);
...@@ -1034,7 +1034,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1034,7 +1034,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1034 const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];1034 const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];
1035 const low_pc = text_phdr.p_vaddr;1035 const low_pc = text_phdr.p_vaddr;
1036 const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;1036 const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
1037 try dw.writeDbgInfoHeader(&self.base, module, low_pc, high_pc);1037 try dw.writeDbgInfoHeader(module, low_pc, high_pc);
1038 self.debug_info_header_dirty = false;1038 self.debug_info_header_dirty = false;
1039 }1039 }
10401040
...@@ -1042,7 +1042,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1042,7 +1042,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1042 // Currently only one compilation unit is supported, so the address range is simply1042 // Currently only one compilation unit is supported, so the address range is simply
1043 // identical to the main program header virtual address and memory size.1043 // identical to the main program header virtual address and memory size.
1044 const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];1044 const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?];
1045 try dw.writeDbgAranges(&self.base, text_phdr.p_vaddr, text_phdr.p_memsz);1045 try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz);
1046 if (!self.shdr_table_dirty) {1046 if (!self.shdr_table_dirty) {
1047 // Then it won't get written with the others and we need to do it.1047 // Then it won't get written with the others and we need to do it.
1048 try self.writeSectHeader(self.debug_aranges_section_index.?);1048 try self.writeSectHeader(self.debug_aranges_section_index.?);
...@@ -1051,7 +1051,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1051,7 +1051,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1051 }1051 }
10521052
1053 if (self.debug_line_header_dirty) {1053 if (self.debug_line_header_dirty) {
1054 try dw.writeDbgLineHeader(&self.base, module);1054 try dw.writeDbgLineHeader(module);
1055 self.debug_line_header_dirty = false;1055 self.debug_line_header_dirty = false;
1056 }1056 }
1057 }1057 }
...@@ -2422,7 +2422,6 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven...@@ -2422,7 +2422,6 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
2422 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_FUNC);2422 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_FUNC);
2423 if (decl_state) |*ds| {2423 if (decl_state) |*ds| {
2424 try self.dwarf.?.commitDeclState(2424 try self.dwarf.?.commitDeclState(
2425 &self.base,
2426 module,2425 module,
2427 decl_index,2426 decl_index,
2428 local_sym.st_value,2427 local_sym.st_value,
...@@ -2499,7 +2498,6 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v...@@ -2499,7 +2498,6 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v
2499 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_OBJECT);2498 const local_sym = try self.updateDeclCode(decl_index, code, elf.STT_OBJECT);
2500 if (decl_state) |*ds| {2499 if (decl_state) |*ds| {
2501 try self.dwarf.?.commitDeclState(2500 try self.dwarf.?.commitDeclState(
2502 &self.base,
2503 module,2501 module,
2504 decl_index,2502 decl_index,
2505 local_sym.st_value,2503 local_sym.st_value,
...@@ -2692,7 +2690,7 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl: *const Module.Decl)...@@ -2692,7 +2690,7 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl: *const Module.Decl)
26922690
2693 if (self.llvm_object) |_| return;2691 if (self.llvm_object) |_| return;
2694 if (self.dwarf) |*dw| {2692 if (self.dwarf) |*dw| {
2695 try dw.updateDeclLineNumber(&self.base, decl);2693 try dw.updateDeclLineNumber(decl);
2696 }2694 }
2697}2695}
26982696
src/link/MachO.zig+3-5
...@@ -347,7 +347,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -347,7 +347,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
347347
348 self.d_sym = .{348 self.d_sym = .{
349 .allocator = allocator,349 .allocator = allocator,
350 .dwarf = link.File.Dwarf.init(allocator, .macho, options.target),350 .dwarf = link.File.Dwarf.init(allocator, &self.base, options.target),
351 .file = d_sym_file,351 .file = d_sym_file,
352 .page_size = self.page_size,352 .page_size = self.page_size,
353 };353 };
...@@ -449,7 +449,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -449,7 +449,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
449 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;449 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
450450
451 if (self.d_sym) |*d_sym| {451 if (self.d_sym) |*d_sym| {
452 try d_sym.dwarf.flushModule(&self.base, module);452 try d_sym.dwarf.flushModule(module);
453 }453 }
454454
455 var libs = std.StringArrayHashMap(link.SystemLib).init(arena);455 var libs = std.StringArrayHashMap(link.SystemLib).init(arena);
...@@ -2213,7 +2213,6 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv...@@ -2213,7 +2213,6 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv
22132213
2214 if (decl_state) |*ds| {2214 if (decl_state) |*ds| {
2215 try self.d_sym.?.dwarf.commitDeclState(2215 try self.d_sym.?.dwarf.commitDeclState(
2216 &self.base,
2217 module,2216 module,
2218 decl_index,2217 decl_index,
2219 addr,2218 addr,
...@@ -2364,7 +2363,6 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)...@@ -2364,7 +2363,6 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
23642363
2365 if (decl_state) |*ds| {2364 if (decl_state) |*ds| {
2366 try self.d_sym.?.dwarf.commitDeclState(2365 try self.d_sym.?.dwarf.commitDeclState(
2367 &self.base,
2368 module,2366 module,
2369 decl_index,2367 decl_index,
2370 addr,2368 addr,
...@@ -2603,7 +2601,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8)...@@ -2603,7 +2601,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8)
2603pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {2601pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {
2604 _ = module;2602 _ = module;
2605 if (self.d_sym) |*d_sym| {2603 if (self.d_sym) |*d_sym| {
2606 try d_sym.dwarf.updateDeclLineNumber(&self.base, decl);2604 try d_sym.dwarf.updateDeclLineNumber(decl);
2607 }2605 }
2608}2606}
26092607
src/link/MachO/DebugSymbols.zig+4-4
...@@ -213,7 +213,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {...@@ -213,7 +213,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
213 }213 }
214214
215 if (self.debug_abbrev_section_dirty) {215 if (self.debug_abbrev_section_dirty) {
216 try self.dwarf.writeDbgAbbrev(&macho_file.base);216 try self.dwarf.writeDbgAbbrev();
217 self.debug_abbrev_section_dirty = false;217 self.debug_abbrev_section_dirty = false;
218 }218 }
219219
...@@ -223,7 +223,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {...@@ -223,7 +223,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
223 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];223 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
224 const low_pc = text_section.addr;224 const low_pc = text_section.addr;
225 const high_pc = text_section.addr + text_section.size;225 const high_pc = text_section.addr + text_section.size;
226 try self.dwarf.writeDbgInfoHeader(&macho_file.base, module, low_pc, high_pc);226 try self.dwarf.writeDbgInfoHeader(module, low_pc, high_pc);
227 self.debug_info_header_dirty = false;227 self.debug_info_header_dirty = false;
228 }228 }
229229
...@@ -231,12 +231,12 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {...@@ -231,12 +231,12 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
231 // Currently only one compilation unit is supported, so the address range is simply231 // Currently only one compilation unit is supported, so the address range is simply
232 // identical to the main program header virtual address and memory size.232 // identical to the main program header virtual address and memory size.
233 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];233 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
234 try self.dwarf.writeDbgAranges(&macho_file.base, text_section.addr, text_section.size);234 try self.dwarf.writeDbgAranges(text_section.addr, text_section.size);
235 self.debug_aranges_section_dirty = false;235 self.debug_aranges_section_dirty = false;
236 }236 }
237237
238 if (self.debug_line_header_dirty) {238 if (self.debug_line_header_dirty) {
239 try self.dwarf.writeDbgLineHeader(&macho_file.base, module);239 try self.dwarf.writeDbgLineHeader(module);
240 self.debug_line_header_dirty = false;240 self.debug_line_header_dirty = false;
241 }241 }
242242
src/link/Wasm.zig+7-8
...@@ -361,7 +361,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option...@@ -361,7 +361,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
361 }361 }
362362
363 if (!options.strip and options.module != null) {363 if (!options.strip and options.module != null) {
364 wasm_bin.dwarf = Dwarf.init(allocator, .wasm, options.target);364 wasm_bin.dwarf = Dwarf.init(allocator, &wasm_bin.base, options.target);
365 try wasm_bin.initDebugSections();365 try wasm_bin.initDebugSections();
366 }366 }
367367
...@@ -910,7 +910,6 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes...@@ -910,7 +910,6 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes
910910
911 if (wasm.dwarf) |*dwarf| {911 if (wasm.dwarf) |*dwarf| {
912 try dwarf.commitDeclState(912 try dwarf.commitDeclState(
913 &wasm.base,
914 mod,913 mod,
915 decl_index,914 decl_index,
916 // Actual value will be written after relocation.915 // Actual value will be written after relocation.
...@@ -990,7 +989,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl: *const Module.Decl)...@@ -990,7 +989,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl: *const Module.Decl)
990 defer wasm.base.allocator.free(decl_name);989 defer wasm.base.allocator.free(decl_name);
991990
992 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });991 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
993 try dw.updateDeclLineNumber(&wasm.base, decl);992 try dw.updateDeclLineNumber(decl);
994 }993 }
995}994}
996995
...@@ -2299,7 +2298,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -2299,7 +2298,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
2299 }2298 }
23002299
2301 if (wasm.dwarf) |*dwarf| {2300 if (wasm.dwarf) |*dwarf| {
2302 try dwarf.flushModule(&wasm.base, wasm.base.options.module.?);2301 try dwarf.flushModule(wasm.base.options.module.?);
2303 }2302 }
2304 }2303 }
23052304
...@@ -2668,12 +2667,12 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -2668,12 +2667,12 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
2668 if (!wasm.base.options.strip) {2667 if (!wasm.base.options.strip) {
2669 if (wasm.dwarf) |*dwarf| {2668 if (wasm.dwarf) |*dwarf| {
2670 const mod = wasm.base.options.module.?;2669 const mod = wasm.base.options.module.?;
2671 try dwarf.writeDbgAbbrev(&wasm.base);2670 try dwarf.writeDbgAbbrev();
2672 // for debug info and ranges, the address is always 0,2671 // for debug info and ranges, the address is always 0,
2673 // as locations are always offsets relative to 'code' section.2672 // as locations are always offsets relative to 'code' section.
2674 try dwarf.writeDbgInfoHeader(&wasm.base, mod, 0, code_section_size);2673 try dwarf.writeDbgInfoHeader(mod, 0, code_section_size);
2675 try dwarf.writeDbgAranges(&wasm.base, 0, code_section_size);2674 try dwarf.writeDbgAranges(0, code_section_size);
2676 try dwarf.writeDbgLineHeader(&wasm.base, mod);2675 try dwarf.writeDbgLineHeader(mod);
2677 }2676 }
26782677
2679 var debug_bytes = std.ArrayList(u8).init(wasm.base.allocator);2678 var debug_bytes = std.ArrayList(u8).init(wasm.base.allocator);