| ... | @@ -22,7 +22,7 @@ const Value = @import("../value.zig").Value; | ... | @@ -22,7 +22,7 @@ const Value = @import("../value.zig").Value; |
| 22 | const Type = @import("../type.zig").Type; | 22 | const Type = @import("../type.zig").Type; |
| 23 | | 23 | |
| 24 | allocator: Allocator, | 24 | allocator: Allocator, |
| 25 | tag: File.Tag, | 25 | bin_file: *File, |
| 26 | ptr_width: PtrWidth, | 26 | ptr_width: PtrWidth, |
| 27 | target: std.Target, | 27 | target: std.Target, |
| 28 | | 28 | |
| ... | @@ -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. |
| 45 | strtab: std.ArrayListUnmanaged(u8) = .{}, | 45 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 46 | | 46 | |
| 47 | file_names_buffer: std.ArrayListUnmanaged(u8) = .{}, | 47 | di_files: std.ArrayListUnmanaged(DIFile) = .{}, |
| 48 | file_names: std.ArrayListUnmanaged(u32) = .{}, | 48 | di_files_free_list: std.ArrayListUnmanaged(u28) = .{}, |
| 49 | file_names_free_list: std.ArrayListUnmanaged(u28) = .{}, | 49 | di_files_lookup: std.AutoHashMapUnmanaged(*const Module.File, u28) = .{}, |
| 50 | file_names_lookup: std.AutoHashMapUnmanaged(*Module.File, u28) = .{}, | | |
| 51 | | 50 | |
| 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 make | 52 | /// 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) = .{}, |
| 56 | | 55 | |
| 57 | global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, | 56 | global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, |
| 58 | | 57 | |
| | 58 | const 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 | |
| 59 | pub const Atom = struct { | 67 | pub 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) |
| 893 | const ideal_factor = 3; | 901 | const ideal_factor = 3; |
| 894 | | 902 | |
| 895 | pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf { | 903 | pub 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); |
| 919 | | 926 | |
| 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 more | 985 | // 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.data4 | 1015 | 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.ref4 | 1020 | 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) |
| 1026 | | 1033 | |
| 1027 | pub fn commitDeclState( | 1034 | pub 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` for | 1088 | // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for |
| 1083 | // `TextBlock` and the .debug_info. If you are editing this logic, you | 1089 | // `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( |
| 1156 | | 1162 | |
| 1157 | // We only have support for one compilation unit so far, so the offsets are directly | 1163 | // 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 | }, |
| 1194 | | 1200 | |
| 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 | }, |
| 1229 | | 1235 | |
| 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; |
| 1263 | | 1269 | |
| 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 of | 1272 | // 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 actual | 1273 | // 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 | } |
| 1289 | | 1295 | |
| 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)); |
| 1292 | | 1298 | |
| 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 | } |
| 1334 | | 1340 | |
| 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 | } |
| 1354 | | 1360 | |
| 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 | } |
| 1358 | | 1364 | |
| 1359 | fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u32) !void { | 1365 | fn 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(); |
| 1362 | | 1368 | |
| ... | @@ -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 | } |
| 1427 | | 1433 | |
| 1428 | fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []const u8) !void { | 1434 | fn 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(); |
| 1431 | | 1437 | |
| ... | @@ -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 |
| 1445 | | 1451 | |
| 1446 | // We only have support for one compilation unit so far, so the offsets are directly | 1452 | // 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 | }, |
| 1484 | | 1490 | |
| 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 | }, |
| 1520 | | 1526 | |
| 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 | } |
| 1551 | | 1557 | |
| 1552 | pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl) !void { | 1558 | pub 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(); |
| 1555 | | 1561 | |
| ... | @@ -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); |
| 1565 | | 1571 | |
| 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 thing | 1621 | // 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 | } |
| 1645 | | 1661 | |
| 1646 | pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void { | 1662 | pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1647 | // These are LEB encoded but since the values are all less than 127 | 1663 | // 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; |
| 1778 | | 1794 | |
| 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 | } |
| 1832 | | 1848 | |
| 1833 | pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u64, high_pc: u64) !void { | 1849 | pub 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(); |
| 1843 | | 1859 | |
| 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 | 4 | 1862 | 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 version | 1886 | 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 size | 1890 | 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); |
| 1889 | | 1905 | |
| 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_offset | 1908 | 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 | } |
| 2160 | | 2176 | |
| 2161 | pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void { | 2177 | pub 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 | 4 | 2180 | 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); // version | 2198 | 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 offset | 2202 | mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // __debug_info offset |
| 2187 | } else { | 2203 | } else { |
| 2188 | self.writeAddrAssumeCapacity(&di_buf, 0); // .debug_info offset | 2204 | 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 { |
| 2205 | | 2221 | |
| 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 | } |
| 2221 | | 2237 | |
| 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 | } |
| 2269 | | 2285 | |
| 2270 | pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void { | 2286 | pub 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 | 4 | 2290 | 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 for | 2328 | // 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; |
| 2317 | | 2333 | |
| 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 name | 2360 | 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 name | 2362 | defer self.allocator.free(full_path); |
| 2347 | // 0, // directory_index | 2363 | 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 name | 2366 | 0, // null byte for the relative path name |
| 2359 | 0, // directory_index | 2367 | 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 sentinel | 2372 | di_buf.appendAssumeCapacity(0); // file names sentinel |
| 2365 | | 2373 | |
| 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; // "." |
| 2441 | | 2449 | |
| | 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 like | 2458 | // 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 | } |
| 2449 | | 2463 | |
| 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 | } |
| 2478 | | 2492 | |
| 2479 | pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void { | 2493 | pub 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 { |
| 2507 | | 2521 | |
| 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); |
| 2513 | | 2527 | |
| 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()); |
| 2535 | | 2549 | |
| 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 | } |
| 2557 | | 2571 | |
| 2558 | fn allocateFileIndex(self: *Dwarf) !u28 { | 2572 | fn allocateDIFileIndex(self: *Dwarf) !u28 { |
| 2559 | try self.file_names.ensureUnusedCapacity(self.allocator, 1); | 2573 | try self.di_files.ensureUnusedCapacity(self.allocator, 1); |
| 2560 | | 2574 | |
| 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 | } |
| 2575 | | 2589 | |
| 2576 | fn addFileName(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 { | 2590 | fn 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 | } | | |
| 2593 | | 2600 | |
| 2594 | fn 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 | } |
| 2598 | | 2613 | |
| 2599 | fn addDbgInfoErrorSet( | 2614 | fn addDbgInfoErrorSet( |