authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-21 20:59:41-04:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-22 08:44:08+02:00
log31220b50b5e718b862a8ce8e993619ecd2959101
tree8289c75c146191d3d9e10f48fb35d7db5a6bfbc1
parent7cd1c882c9dda18d333649462193e3e44e54196e

Dwarf: cleanup emitted debug info

* reduce iteration cost by not tracking unused entries * avoid emitting unused abbrevs to `.debug_abbrev` * get the compiler executable passing `llvm-dwarfdump --verify` * make it possible to skip `.debug_line` padding much more quickly

2 files changed, 335 insertions(+), 269 deletions(-)

lib/std/dwarf.zig+1
......@@ -89,6 +89,7 @@ pub const LNS = struct {
8989};
9090
9191pub const LNE = struct {
92 pub const padding = 0x00;
9293 pub const end_sequence = 0x01;
9394 pub const set_address = 0x02;
9495 pub const define_file = 0x03;
src/link/Dwarf.zig+334-269
......@@ -55,7 +55,10 @@ const ModInfo = struct {
5555const DebugAbbrev = struct {
5656 section: Section,
5757 const unit: Unit.Index = @enumFromInt(0);
58 const entry: Entry.Index = @enumFromInt(0);
58
59 const header_bytes = 0;
60
61 const trailer_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.null));
5962};
6063
6164const DebugAranges = struct {
......@@ -119,8 +122,7 @@ const DebugLine = struct {
119122 1 + uleb128Bytes(DW.LNCT.path) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(DW.LNCT.directory_index) + uleb128Bytes(@intFromEnum(dir_index_info.form)) + uleb128Bytes(DW.LNCT.LLVM_source) + uleb128Bytes(DW.FORM.line_strp) + uleb128Bytes(file_count) + (dwarf.sectionOffsetBytes() + dir_index_info.bytes + dwarf.sectionOffsetBytes()) * file_count;
120123 }
121124
122 const trailer_bytes = 1 + uleb128Bytes(0) +
123 1 + uleb128Bytes(1) + 1;
125 const trailer_bytes = 1 + uleb128Bytes(1) + 1;
124126};
125127
126128const DebugLocLists = struct {
......@@ -173,10 +175,15 @@ const StringSection = struct {
173175 errdefer _ = str_sec.map.pop();
174176 const entry: Entry.Index = @enumFromInt(gop.index);
175177 if (!gop.found_existing) {
176 assert(try str_sec.section.addEntry(unit, dwarf) == entry);
177 errdefer _ = str_sec.section.getUnit(unit).entries.pop();
178 const entry_ptr = str_sec.section.getUnit(unit).getEntry(entry);
179 assert(entry_ptr.off == str_sec.contents.items.len);
178 const unit_ptr = str_sec.section.getUnit(unit);
179 assert(try str_sec.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
180 errdefer _ = unit_ptr.entries.pop();
181 const entry_ptr = unit_ptr.getEntry(entry);
182 if (unit_ptr.last.unwrap()) |last_entry|
183 unit_ptr.getEntry(last_entry).next = entry.toOptional();
184 entry_ptr.prev = unit_ptr.last;
185 unit_ptr.last = entry.toOptional();
186 entry_ptr.off = @intCast(str_sec.contents.items.len);
180187 entry_ptr.len = @intCast(str.len + 1);
181188 try str_sec.contents.ensureUnusedCapacity(dwarf.gpa, str.len + 1);
182189 str_sec.contents.appendSliceAssumeCapacity(str);
......@@ -243,7 +250,7 @@ pub const Section = struct {
243250 fn addUnit(sec: *Section, header_len: u32, trailer_len: u32, dwarf: *Dwarf) UpdateError!Unit.Index {
244251 const unit: Unit.Index = @enumFromInt(sec.units.items.len);
245252 const unit_ptr = try sec.units.addOne(dwarf.gpa);
246 errdefer sec.popUnit();
253 errdefer sec.popUnit(dwarf.gpa);
247254 unit_ptr.* = .{
248255 .prev = sec.last,
249256 .next = .none,
......@@ -277,14 +284,11 @@ pub const Section = struct {
277284 if (sec.last.unwrap().? == unit) sec.last = unit_ptr.prev;
278285 }
279286
280 fn popUnit(sec: *Section) void {
281 const unit: Unit.Index = @enumFromInt(sec.units.items.len - 1);
282 sec.unlinkUnit(unit);
283 _ = sec.units.pop();
284 }
285
286 fn addEntry(sec: *Section, unit: Unit.Index, dwarf: *Dwarf) UpdateError!Entry.Index {
287 return sec.getUnit(unit).addEntry(sec, dwarf);
287 fn popUnit(sec: *Section, gpa: std.mem.Allocator) void {
288 const unit_index: Unit.Index = @enumFromInt(sec.units.items.len - 1);
289 sec.unlinkUnit(unit_index);
290 var unit = sec.units.pop();
291 unit.deinit(gpa);
288292 }
289293
290294 pub fn getUnit(sec: *Section, unit: Unit.Index) *Unit {
......@@ -293,7 +297,21 @@ pub const Section = struct {
293297
294298 fn replaceEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
295299 const unit_ptr = sec.getUnit(unit);
296 try unit_ptr.getEntry(entry).replace(unit_ptr, sec, dwarf, contents);
300 const entry_ptr = unit_ptr.getEntry(entry);
301 if (contents.len > 0) {
302 if (entry_ptr.len == 0) {
303 assert(entry_ptr.prev == .none and entry_ptr.next == .none);
304 entry_ptr.off = if (unit_ptr.last.unwrap()) |last_entry| off: {
305 const last_entry_ptr = unit_ptr.getEntry(last_entry);
306 last_entry_ptr.next = entry.toOptional();
307 break :off last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
308 } else 0;
309 entry_ptr.prev = unit_ptr.last;
310 unit_ptr.last = entry.toOptional();
311 }
312 try entry_ptr.replace(unit_ptr, sec, dwarf, contents);
313 }
314 assert(entry_ptr.len == contents.len);
297315 }
298316
299317 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
......@@ -391,11 +409,11 @@ const Unit = struct {
391409 unit.* = undefined;
392410 }
393411
394 fn addEntry(unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!Entry.Index {
412 fn addEntry(unit: *Unit, gpa: std.mem.Allocator) std.mem.Allocator.Error!Entry.Index {
395413 const entry: Entry.Index = @enumFromInt(unit.entries.items.len);
396 const entry_ptr = try unit.entries.addOne(dwarf.gpa);
414 const entry_ptr = try unit.entries.addOne(gpa);
397415 entry_ptr.* = .{
398 .prev = unit.last,
416 .prev = .none,
399417 .next = .none,
400418 .off = 0,
401419 .len = 0,
......@@ -404,14 +422,6 @@ const Unit = struct {
404422 .cross_section_relocs = .{},
405423 .external_relocs = .{},
406424 };
407 if (unit.last.unwrap()) |last_entry| {
408 const last_entry_ptr = unit.getEntry(last_entry);
409 last_entry_ptr.next = entry.toOptional();
410 entry_ptr.off = last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
411 }
412 if (unit.first == .none)
413 unit.first = entry.toOptional();
414 unit.last = entry.toOptional();
415425 return entry;
416426 }
417427
......@@ -509,42 +519,52 @@ const Unit = struct {
509519 const last_entry_ptr = unit.getEntry(last_entry);
510520 break :end last_entry_ptr.off + last_entry_ptr.len;
511521 } else 0;
512 const end = if (unit.next.unwrap()) |next_unit|
513 sec.getUnit(next_unit).off
514 else
515 sec.len;
516 const trailer_len: usize = @intCast(end - start);
517 assert(trailer_len >= unit.trailer_len);
518 var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, trailer_len);
522 const end = if (unit.next.unwrap()) |next_unit| sec.getUnit(next_unit).off else sec.len;
523 const len: usize = @intCast(end - start);
524 assert(len >= unit.trailer_len);
525 if (sec == &dwarf.debug_line.section) {
526 var buf: [1 + uleb128Bytes(std.math.maxInt(u32)) + 1]u8 = undefined;
527 var fbs = std.io.fixedBufferStream(&buf);
528 const writer = fbs.writer();
529 writer.writeByte(DW.LNS.extended_op) catch unreachable;
530 const extended_op_bytes = fbs.pos;
531 var op_len_bytes: u5 = 1;
532 while (true) switch (std.math.order(len - extended_op_bytes - op_len_bytes, @as(u32, 1) << 7 * op_len_bytes)) {
533 .lt => break uleb128(writer, len - extended_op_bytes - op_len_bytes) catch unreachable,
534 .eq => {
535 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
536 op_len_bytes += 1;
537 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
538 fbs.pos += op_len_bytes;
539 break;
540 },
541 .gt => op_len_bytes += 1,
542 };
543 assert(fbs.pos == extended_op_bytes + op_len_bytes);
544 writer.writeByte(DW.LNE.padding) catch unreachable;
545 assert(fbs.pos >= unit.trailer_len and fbs.pos <= len);
546 return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + start);
547 }
548 var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, len);
519549 defer trailer.deinit();
520 const fill_byte: u8 = if (sec == &dwarf.debug_aranges.section) fill: {
550 const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: {
551 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
552 trailer.appendAssumeCapacity(@intFromEnum(AbbrevCode.null));
553 break :fill @intFromEnum(AbbrevCode.null);
554 } else if (sec == &dwarf.debug_aranges.section) fill: {
521555 trailer.appendNTimesAssumeCapacity(0, @intFromEnum(dwarf.address_size) * 2);
522556 break :fill 0;
523557 } else if (sec == &dwarf.debug_info.section) fill: {
524558 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
525559 trailer.appendNTimesAssumeCapacity(@intFromEnum(AbbrevCode.null), 2);
526560 break :fill @intFromEnum(AbbrevCode.null);
527 } else if (sec == &dwarf.debug_line.section) fill: {
528 unit.len -= unit.trailer_len;
529 const extra_len: u32 = @intCast((trailer_len - DebugLine.trailer_bytes) & 1);
530 unit.trailer_len = DebugLine.trailer_bytes + extra_len;
531 unit.len += unit.trailer_len;
532
533 // prevent end sequence from emitting an invalid file index
534 trailer.appendAssumeCapacity(DW.LNS.set_file);
535 uleb128(trailer.fixedWriter(), 0) catch unreachable;
536
537 trailer.appendAssumeCapacity(DW.LNS.extended_op);
538 std.leb.writeUnsignedExtended(trailer.addManyAsSliceAssumeCapacity(uleb128Bytes(1) + extra_len), 1);
539 trailer.appendAssumeCapacity(DW.LNE.end_sequence);
540 break :fill DW.LNS.extended_op;
541561 } else if (sec == &dwarf.debug_rnglists.section) fill: {
542562 trailer.appendAssumeCapacity(DW.RLE.end_of_list);
543563 break :fill DW.RLE.end_of_list;
544564 } else unreachable;
545565 assert(trailer.items.len == unit.trailer_len);
546 trailer.appendNTimesAssumeCapacity(fill_byte, trailer_len - trailer.items.len);
547 assert(trailer.items.len == trailer_len);
566 trailer.appendNTimesAssumeCapacity(fill_byte, len - trailer.items.len);
567 assert(trailer.items.len == len);
548568 try dwarf.getFile().?.pwriteAll(trailer.items, sec.off + start);
549569 }
550570
......@@ -625,45 +645,62 @@ const Entry = struct {
625645 };
626646
627647 fn pad(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void {
648 assert(entry.len > 0);
628649 const start = entry.off + entry.len;
629650 const len = unit.getEntry(entry.next.unwrap() orelse return).off - start;
630 if (sec == &dwarf.debug_info.section) {
631 var buf: [
632 @max(
633 uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)),
634 uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) + uleb128Bytes(std.math.maxInt(u32)),
635 )
636 ]u8 = undefined;
637 var fbs = std.io.fixedBufferStream(&buf);
638 switch (len) {
639 0 => {},
640 1 => uleb128(fbs.writer(), @intFromEnum(AbbrevCode.pad_1)) catch unreachable,
641 else => {
642 uleb128(fbs.writer(), @intFromEnum(AbbrevCode.pad_n)) catch unreachable;
643 const abbrev_code_bytes = fbs.pos;
644 var block_len_bytes: u5 = 1;
645 while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {
646 .lt => break uleb128(fbs.writer(), len - abbrev_code_bytes - block_len_bytes) catch unreachable,
647 .eq => {
648 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
649 block_len_bytes += 1;
650 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
651 fbs.pos += block_len_bytes;
652 break;
653 },
654 .gt => block_len_bytes += 1,
655 };
656 assert(fbs.pos == abbrev_code_bytes + block_len_bytes);
657 },
658 }
659 assert(fbs.pos <= len);
660 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start);
661 } else if (sec == &dwarf.debug_line.section) {
662 const buf = try dwarf.gpa.alloc(u8, len);
663 defer dwarf.gpa.free(buf);
664 @memset(buf, DW.LNS.const_add_pc);
665 try dwarf.getFile().?.pwriteAll(buf, sec.off + unit.off + unit.header_len + start);
651 var buf: [
652 @max(
653 uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)),
654 uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) + uleb128Bytes(std.math.maxInt(u32)),
655 1 + uleb128Bytes(std.math.maxInt(u32)) + 1,
656 )
657 ]u8 = undefined;
658 var fbs = std.io.fixedBufferStream(&buf);
659 const writer = fbs.writer();
660 if (sec == &dwarf.debug_info.section) switch (len) {
661 0 => {},
662 1 => uleb128(writer, try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
663 else => {
664 uleb128(writer, try dwarf.refAbbrevCode(.pad_n)) catch unreachable;
665 const abbrev_code_bytes = fbs.pos;
666 var block_len_bytes: u5 = 1;
667 while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {
668 .lt => break uleb128(writer, len - abbrev_code_bytes - block_len_bytes) catch unreachable,
669 .eq => {
670 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
671 block_len_bytes += 1;
672 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
673 fbs.pos += block_len_bytes;
674 break;
675 },
676 .gt => block_len_bytes += 1,
677 };
678 assert(fbs.pos == abbrev_code_bytes + block_len_bytes);
679 },
680 } else if (sec == &dwarf.debug_line.section) switch (len) {
681 0 => {},
682 1 => writer.writeByte(DW.LNS.const_add_pc) catch unreachable,
683 else => {
684 writer.writeByte(DW.LNS.extended_op) catch unreachable;
685 const extended_op_bytes = fbs.pos;
686 var op_len_bytes: u5 = 1;
687 while (true) switch (std.math.order(len - extended_op_bytes - op_len_bytes, @as(u32, 1) << 7 * op_len_bytes)) {
688 .lt => break uleb128(writer, len - extended_op_bytes - op_len_bytes) catch unreachable,
689 .eq => {
690 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
691 op_len_bytes += 1;
692 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
693 fbs.pos += op_len_bytes;
694 break;
695 },
696 .gt => op_len_bytes += 1,
697 };
698 assert(fbs.pos == extended_op_bytes + op_len_bytes);
699 if (len > 2) writer.writeByte(DW.LNE.padding) catch unreachable;
700 },
666701 } else assert(!sec.pad_to_ideal and len == 0);
702 assert(fbs.pos <= len);
703 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start);
667704 }
668705
669706 fn replace(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
......@@ -691,15 +728,7 @@ const Entry = struct {
691728 try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(contents.len) + unit.trailer_len));
692729 }
693730 entry_ptr.len = @intCast(contents.len);
694 {
695 var prev_entry_ptr = entry_ptr;
696 while (prev_entry_ptr.prev.unwrap()) |prev_entry| {
697 prev_entry_ptr = unit.getEntry(prev_entry);
698 if (prev_entry_ptr.len == 0) continue;
699 try prev_entry_ptr.pad(unit, sec, dwarf);
700 break;
701 }
702 }
731 if (entry_ptr.prev.unwrap()) |prev_entry| try unit.getEntry(prev_entry).pad(unit, sec, dwarf);
703732 try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off + unit.header_len + entry_ptr.off);
704733 try entry_ptr.pad(unit, sec, dwarf);
705734 if (false) {
......@@ -1039,7 +1068,10 @@ pub const WipNav = struct {
10391068 func: InternPool.Index,
10401069 func_sym_index: u32,
10411070 func_high_reloc: u32,
1042 inlined_funcs_high_reloc: std.ArrayListUnmanaged(u32),
1071 inlined_funcs: std.ArrayListUnmanaged(struct {
1072 abbrev_code: u32,
1073 high_reloc: u32,
1074 }),
10431075 debug_info: std.ArrayListUnmanaged(u8),
10441076 debug_line: std.ArrayListUnmanaged(u8),
10451077 debug_loclists: std.ArrayListUnmanaged(u8),
......@@ -1047,7 +1079,7 @@ pub const WipNav = struct {
10471079
10481080 pub fn deinit(wip_nav: *WipNav) void {
10491081 const gpa = wip_nav.dwarf.gpa;
1050 if (wip_nav.func != .none) wip_nav.inlined_funcs_high_reloc.deinit(gpa);
1082 if (wip_nav.func != .none) wip_nav.inlined_funcs.deinit(gpa);
10511083 wip_nav.debug_info.deinit(gpa);
10521084 wip_nav.debug_line.deinit(gpa);
10531085 wip_nav.debug_loclists.deinit(gpa);
......@@ -1066,15 +1098,14 @@ pub const WipNav = struct {
10661098 ty: Type,
10671099 loc: Loc,
10681100 ) UpdateError!void {
1069 wip_nav.any_children = true;
10701101 assert(wip_nav.func != .none);
1071 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
1072 try uleb128(diw, @intFromEnum(switch (tag) {
1102 try wip_nav.abbrevCode(switch (tag) {
10731103 inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),
1074 }));
1104 });
10751105 try wip_nav.strp(name);
10761106 try wip_nav.refType(ty);
10771107 try wip_nav.exprloc(loc);
1108 wip_nav.any_children = true;
10781109 }
10791110
10801111 pub fn advancePCAndLine(
......@@ -1136,9 +1167,10 @@ pub const WipNav = struct {
11361167 const dwarf = wip_nav.dwarf;
11371168 const zcu = wip_nav.pt.zcu;
11381169 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1139 try wip_nav.inlined_funcs_high_reloc.ensureUnusedCapacity(dwarf.gpa, 1);
1170 const inlined_func = try wip_nav.inlined_funcs.addOne(dwarf.gpa);
11401171
1141 try uleb128(diw, @intFromEnum(AbbrevCode.inlined_func));
1172 inlined_func.abbrev_code = @intCast(wip_nav.debug_info.items.len);
1173 try wip_nav.abbrevCode(.inlined_func);
11421174 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
11431175 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
11441176 try uleb128(diw, column + 1);
......@@ -1150,7 +1182,7 @@ pub const WipNav = struct {
11501182 .target_off = code_off,
11511183 });
11521184 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1153 wip_nav.inlined_funcs_high_reloc.appendAssumeCapacity(@intCast(external_relocs.items.len));
1185 inlined_func.high_reloc = @intCast(external_relocs.items.len);
11541186 external_relocs.appendAssumeCapacity(.{
11551187 .source_off = @intCast(wip_nav.debug_info.items.len),
11561188 .target_sym = wip_nav.func_sym_index,
......@@ -1158,17 +1190,27 @@ pub const WipNav = struct {
11581190 });
11591191 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
11601192 try wip_nav.setInlineFunc(func);
1193 wip_nav.any_children = false;
11611194 }
11621195
11631196 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {
1197 const inlined_func_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.inlined_func));
1198 const inlined_func = wip_nav.inlined_funcs.pop();
11641199 const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
1165 external_relocs.items[wip_nav.inlined_funcs_high_reloc.pop()].target_off = code_off;
1166 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null));
1200 external_relocs.items[inlined_func.high_reloc].target_off = code_off;
1201 if (wip_nav.any_children)
1202 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))
1203 else
1204 std.leb.writeUnsignedFixed(
1205 inlined_func_bytes,
1206 wip_nav.debug_info.items[inlined_func.abbrev_code..][0..inlined_func_bytes],
1207 try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func),
1208 );
11671209 try wip_nav.setInlineFunc(func);
1210 wip_nav.any_children = true;
11681211 }
11691212
11701213 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {
1171 wip_nav.any_children = true;
11721214 const zcu = wip_nav.pt.zcu;
11731215 const dwarf = wip_nav.dwarf;
11741216 if (wip_nav.func == func) return;
......@@ -1219,6 +1261,10 @@ pub const WipNav = struct {
12191261 wip_nav.func = func;
12201262 }
12211263
1264 fn abbrevCode(wip_nav: *WipNav, abbrev_code: AbbrevCode) UpdateError!void {
1265 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), try wip_nav.dwarf.refAbbrevCode(abbrev_code));
1266 }
1267
12221268 fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void {
12231269 const dwarf = wip_nav.dwarf;
12241270 const gpa = dwarf.gpa;
......@@ -1336,7 +1382,7 @@ pub const WipNav = struct {
13361382 loaded_enum: InternPool.LoadedEnumType,
13371383 abbrev_code: std.enums.EnumFieldStruct(std.builtin.Signedness, AbbrevCode, null),
13381384 field_index: usize,
1339 ) std.mem.Allocator.Error!void {
1385 ) UpdateError!void {
13401386 const zcu = wip_nav.pt.zcu;
13411387 const ip = &zcu.intern_pool;
13421388 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
......@@ -1344,9 +1390,9 @@ pub const WipNav = struct {
13441390 .comptime_int_type => .signed,
13451391 else => Type.fromInterned(loaded_enum.tag_ty).intInfo(zcu).signedness,
13461392 };
1347 try uleb128(diw, @intFromEnum(switch (signedness) {
1393 try wip_nav.abbrevCode(switch (signedness) {
13481394 inline .signed, .unsigned => |ct_signedness| @field(abbrev_code, @tagName(ct_signedness)),
1349 }));
1395 });
13501396 if (loaded_enum.values.len > 0) switch (ip.indexToKey(loaded_enum.values.get(ip)[field_index]).int.storage) {
13511397 .u64 => |value| switch (signedness) {
13521398 .signed => try sleb128(diw, value),
......@@ -1535,20 +1581,21 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
15351581 dwarf.reloadSectionMetadata();
15361582
15371583 dwarf.debug_abbrev.section.pad_to_ideal = false;
1538 assert(try dwarf.debug_abbrev.section.addUnit(0, 0, dwarf) == DebugAbbrev.unit);
1539 errdefer dwarf.debug_abbrev.section.popUnit();
1540 assert(try dwarf.debug_abbrev.section.addEntry(DebugAbbrev.unit, dwarf) == DebugAbbrev.entry);
1584 assert(try dwarf.debug_abbrev.section.addUnit(DebugAbbrev.header_bytes, DebugAbbrev.trailer_bytes, dwarf) == DebugAbbrev.unit);
1585 errdefer dwarf.debug_abbrev.section.popUnit(dwarf.gpa);
1586 for (std.enums.values(AbbrevCode)) |abbrev_code|
1587 assert(@intFromEnum(try dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).addEntry(dwarf.gpa)) == @intFromEnum(abbrev_code));
15411588
15421589 dwarf.debug_aranges.section.pad_to_ideal = false;
15431590 dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);
15441591
15451592 dwarf.debug_line_str.section.pad_to_ideal = false;
15461593 assert(try dwarf.debug_line_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
1547 errdefer dwarf.debug_line_str.section.popUnit();
1594 errdefer dwarf.debug_line_str.section.popUnit(dwarf.gpa);
15481595
15491596 dwarf.debug_str.section.pad_to_ideal = false;
15501597 assert(try dwarf.debug_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
1551 errdefer dwarf.debug_str.section.popUnit();
1598 errdefer dwarf.debug_str.section.popUnit(dwarf.gpa);
15521599
15531600 dwarf.debug_loclists.section.pad_to_ideal = false;
15541601
......@@ -1589,31 +1636,31 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
15891636 DebugAranges.trailerBytes(dwarf),
15901637 dwarf,
15911638 ) == unit);
1592 errdefer dwarf.debug_aranges.section.popUnit();
1639 errdefer dwarf.debug_aranges.section.popUnit(dwarf.gpa);
15931640 assert(try dwarf.debug_info.section.addUnit(
15941641 DebugInfo.headerBytes(dwarf),
15951642 DebugInfo.trailer_bytes,
15961643 dwarf,
15971644 ) == unit);
1598 errdefer dwarf.debug_info.section.popUnit();
1645 errdefer dwarf.debug_info.section.popUnit(dwarf.gpa);
15991646 assert(try dwarf.debug_line.section.addUnit(
16001647 DebugLine.headerBytes(dwarf, 5, 25),
16011648 DebugLine.trailer_bytes,
16021649 dwarf,
16031650 ) == unit);
1604 errdefer dwarf.debug_line.section.popUnit();
1651 errdefer dwarf.debug_line.section.popUnit(dwarf.gpa);
16051652 assert(try dwarf.debug_loclists.section.addUnit(
16061653 DebugLocLists.headerBytes(dwarf),
16071654 DebugLocLists.trailer_bytes,
16081655 dwarf,
16091656 ) == unit);
1610 errdefer dwarf.debug_loclists.section.popUnit();
1657 errdefer dwarf.debug_loclists.section.popUnit(dwarf.gpa);
16111658 assert(try dwarf.debug_rnglists.section.addUnit(
16121659 DebugRngLists.headerBytes(dwarf),
16131660 DebugRngLists.trailer_bytes,
16141661 dwarf,
16151662 ) == unit);
1616 errdefer dwarf.debug_rnglists.section.popUnit();
1663 errdefer dwarf.debug_rnglists.section.popUnit(dwarf.gpa);
16171664 }
16181665 return unit;
16191666}
......@@ -1658,7 +1705,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
16581705 .func = .none,
16591706 .func_sym_index = undefined,
16601707 .func_high_reloc = undefined,
1661 .inlined_funcs_high_reloc = undefined,
1708 .inlined_funcs = undefined,
16621709 .debug_info = .{},
16631710 .debug_line = .{},
16641711 .debug_loclists = .{},
......@@ -1699,7 +1746,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
16991746 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
17001747
17011748 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1702 try uleb128(diw, @intFromEnum(AbbrevCode.decl_var));
1749 try wip_nav.abbrevCode(.decl_var);
17031750 try wip_nav.refType(Type.fromInterned(parent_type));
17041751 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
17051752 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -1714,7 +1761,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17141761 ty.abiAlignment(pt).toByteUnits().?);
17151762 try diw.writeByte(@intFromBool(false));
17161763 wip_nav.finishForward(ty_reloc_index);
1717 try uleb128(diw, @intFromEnum(AbbrevCode.is_const));
1764 try wip_nav.abbrevCode(.is_const);
17181765 try wip_nav.refType(ty);
17191766 },
17201767 .variable => |variable| {
......@@ -1749,7 +1796,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17491796 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
17501797
17511798 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1752 try uleb128(diw, @intFromEnum(AbbrevCode.decl_var));
1799 try wip_nav.abbrevCode(.decl_var);
17531800 try wip_nav.refType(Type.fromInterned(parent_type));
17541801 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
17551802 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -1799,10 +1846,10 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17991846 const func_type = ip.indexToKey(func.ty).func_type;
18001847 wip_nav.func = nav_val.toIntern();
18011848 wip_nav.func_sym_index = sym_index;
1802 wip_nav.inlined_funcs_high_reloc = .{};
1849 wip_nav.inlined_funcs = .{};
18031850
18041851 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1805 try uleb128(diw, @intFromEnum(AbbrevCode.decl_func));
1852 try wip_nav.abbrevCode(.decl_func);
18061853 try wip_nav.refType(Type.fromInterned(parent_type));
18071854 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
18081855 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -1891,7 +1938,7 @@ pub fn finishWipNav(
18911938 } else std.leb.writeUnsignedFixed(
18921939 AbbrevCode.decl_bytes,
18931940 wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
1894 @intFromEnum(AbbrevCode.decl_func_empty),
1941 try dwarf.refAbbrevCode(.decl_empty_func),
18951942 );
18961943
18971944 var aranges_entry = [1]u8{0} ** (8 + 8);
......@@ -1967,7 +2014,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
19672014 .func = .none,
19682015 .func_sym_index = undefined,
19692016 .func_high_reloc = undefined,
1970 .inlined_funcs_high_reloc = undefined,
2017 .inlined_funcs = undefined,
19712018 .debug_info = .{},
19722019 .debug_line = .{},
19732020 .debug_loclists = .{},
......@@ -1990,12 +2037,12 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
19902037 ) != abbrev_code_buf.len) return error.InputOutput;
19912038 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
19922039 const abbrev_code: AbbrevCode = @enumFromInt(
1993 try std.leb.readUleb128(@typeInfo(AbbrevCode).Enum.tag_type, abbrev_code_fbs.reader()),
2040 std.leb.readUleb128(@typeInfo(AbbrevCode).Enum.tag_type, abbrev_code_fbs.reader()) catch unreachable,
19942041 );
19952042 switch (abbrev_code) {
19962043 else => unreachable,
1997 .decl_func, .decl_func_empty => return,
1998 .decl_func_generic, .decl_func_generic_empty => {},
2044 .decl_func, .decl_empty_func => return,
2045 .decl_func_generic, .decl_empty_func_generic => {},
19992046 }
20002047 }
20012048 entry_ptr.clear();
......@@ -2017,7 +2064,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
20172064
20182065 const func_type = ip.indexToKey(func.ty).func_type;
20192066 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2020 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (func_type.param_types.len > 0 or func_type.is_var_args) .decl_func_generic else .decl_func_generic_empty)));
2067 try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)
2068 .decl_func_generic
2069 else
2070 .decl_empty_func_generic);
20212071 try wip_nav.refType(Type.fromInterned(parent_type));
20222072 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
20232073 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2027,10 +2077,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
20272077 try wip_nav.refType(Type.fromInterned(func_type.return_type));
20282078 if (func_type.param_types.len > 0 or func_type.is_var_args) {
20292079 for (0..func_type.param_types.len) |param_index| {
2030 try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
2080 try wip_nav.abbrevCode(.func_type_param);
20312081 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
20322082 }
2033 if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
2083 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
20342084 try uleb128(diw, @intFromEnum(AbbrevCode.null));
20352085 }
20362086 },
......@@ -2088,10 +2138,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
20882138
20892139 switch (loaded_struct.layout) {
20902140 .auto, .@"extern" => {
2091 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0)
2092 .decl_namespace_struct
2093 else
2094 .decl_struct)));
2141 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
20952142 try wip_nav.refType(Type.fromInterned(parent_type));
20962143 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
20972144 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2103,7 +2150,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
21032150 try uleb128(diw, nav_val.toType().abiAlignment(pt).toByteUnits().?);
21042151 for (0..loaded_struct.field_types.len) |field_index| {
21052152 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
2106 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_comptime) .struct_field_comptime else .struct_field)));
2153 try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
21072154 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
21082155 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
21092156 defer dwarf.gpa.free(field_name);
......@@ -2121,7 +2168,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
21212168 }
21222169 },
21232170 .@"packed" => {
2124 try uleb128(diw, @intFromEnum(AbbrevCode.decl_packed_struct));
2171 try wip_nav.abbrevCode(.decl_packed_struct);
21252172 try wip_nav.refType(Type.fromInterned(parent_type));
21262173 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
21272174 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2131,7 +2178,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
21312178 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
21322179 var field_bit_offset: u16 = 0;
21332180 for (0..loaded_struct.field_types.len) |field_index| {
2134 try uleb128(diw, @intFromEnum(@as(AbbrevCode, .packed_struct_field)));
2181 try wip_nav.abbrevCode(.packed_struct_field);
21352182 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
21362183 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
21372184 try wip_nav.refType(field_type);
......@@ -2150,7 +2197,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
21502197 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
21512198 wip_nav.entry = nav_gop.value_ptr.*;
21522199 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2153 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
2200 try wip_nav.abbrevCode(.decl_alias);
21542201 try wip_nav.refType(Type.fromInterned(parent_type));
21552202 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
21562203 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2210,7 +2257,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
22102257 }
22112258 wip_nav.entry = nav_gop.value_ptr.*;
22122259 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2213 try uleb128(diw, @intFromEnum(AbbrevCode.decl_enum));
2260 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
22142261 try wip_nav.refType(Type.fromInterned(parent_type));
22152262 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
22162263 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2225,7 +2272,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
22252272 }, field_index);
22262273 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
22272274 }
2228 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2275 if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
22292276 break :done;
22302277 }
22312278
......@@ -2235,7 +2282,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
22352282 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
22362283 wip_nav.entry = nav_gop.value_ptr.*;
22372284 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2238 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
2285 try wip_nav.abbrevCode(.decl_alias);
22392286 try wip_nav.refType(Type.fromInterned(parent_type));
22402287 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
22412288 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2293,7 +2340,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
22932340 }
22942341 wip_nav.entry = nav_gop.value_ptr.*;
22952342 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2296 try uleb128(diw, @intFromEnum(AbbrevCode.decl_union));
2343 try wip_nav.abbrevCode(.decl_union);
22972344 try wip_nav.refType(Type.fromInterned(parent_type));
22982345 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
22992346 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2305,7 +2352,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
23052352 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
23062353 const loaded_tag = loaded_union.loadTagType(ip);
23072354 if (loaded_union.hasTag(ip)) {
2308 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
2355 try wip_nav.abbrevCode(.tagged_union);
23092356 try wip_nav.infoSectionOffset(
23102357 .debug_info,
23112358 wip_nav.unit,
......@@ -2313,7 +2360,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
23132360 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
23142361 );
23152362 {
2316 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2363 try wip_nav.abbrevCode(.generated_field);
23172364 try wip_nav.strp("tag");
23182365 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
23192366 try uleb128(diw, union_layout.tagOffset());
......@@ -2324,7 +2371,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
23242371 .unsigned = .unsigned_tagged_union_field,
23252372 }, field_index);
23262373 {
2327 try uleb128(diw, @intFromEnum(AbbrevCode.struct_field));
2374 try wip_nav.abbrevCode(.struct_field);
23282375 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
23292376 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
23302377 try wip_nav.refType(field_type);
......@@ -2340,7 +2387,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
23402387 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
23412388 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
23422389 } else for (0..loaded_union.field_types.len) |field_index| {
2343 try uleb128(diw, @intFromEnum(AbbrevCode.untagged_union_field));
2390 try wip_nav.abbrevCode(.untagged_union_field);
23442391 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
23452392 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
23462393 try wip_nav.refType(field_type);
......@@ -2357,7 +2404,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
23572404 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
23582405 wip_nav.entry = nav_gop.value_ptr.*;
23592406 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2360 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
2407 try wip_nav.abbrevCode(.decl_alias);
23612408 try wip_nav.refType(Type.fromInterned(parent_type));
23622409 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
23632410 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2415,7 +2462,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
24152462 }
24162463 wip_nav.entry = nav_gop.value_ptr.*;
24172464 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2418 try uleb128(diw, @intFromEnum(AbbrevCode.decl_namespace_struct));
2465 try wip_nav.abbrevCode(.decl_namespace_struct);
24192466 try wip_nav.refType(Type.fromInterned(parent_type));
24202467 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
24212468 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2432,7 +2479,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
24322479 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
24332480 wip_nav.entry = nav_gop.value_ptr.*;
24342481 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2435 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
2482 try wip_nav.abbrevCode(.decl_alias);
24362483 try wip_nav.refType(Type.fromInterned(parent_type));
24372484 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
24382485 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
......@@ -2473,7 +2520,7 @@ fn updateType(
24732520 .func = .none,
24742521 .func_sym_index = undefined,
24752522 .func_high_reloc = undefined,
2476 .inlined_funcs_high_reloc = undefined,
2523 .inlined_funcs = undefined,
24772524 .debug_info = .{},
24782525 .debug_line = .{},
24792526 .debug_loclists = .{},
......@@ -2493,7 +2540,7 @@ fn updateType(
24932540
24942541 switch (ip.indexToKey(type_index)) {
24952542 .int_type => |int_type| {
2496 try uleb128(diw, @intFromEnum(AbbrevCode.numeric_type));
2543 try wip_nav.abbrevCode(.numeric_type);
24972544 try wip_nav.strp(name);
24982545 try diw.writeByte(switch (int_type.signedness) {
24992546 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
......@@ -2505,7 +2552,7 @@ fn updateType(
25052552 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
25062553 .One, .Many, .C => {
25072554 const ptr_child_type = Type.fromInterned(ptr_type.child);
2508 try uleb128(diw, @intFromEnum(AbbrevCode.ptr_type));
2555 try wip_nav.abbrevCode(.ptr_type);
25092556 try wip_nav.strp(name);
25102557 try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse
25112558 ptr_child_type.abiAlignment(pt).toByteUnits().?);
......@@ -2517,7 +2564,7 @@ fn updateType(
25172564 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
25182565 ) else try wip_nav.refType(ptr_child_type);
25192566 if (ptr_type.flags.is_const) {
2520 try uleb128(diw, @intFromEnum(AbbrevCode.is_const));
2567 try wip_nav.abbrevCode(.is_const);
25212568 if (ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
25222569 .debug_info,
25232570 wip_nav.unit,
......@@ -2526,21 +2573,21 @@ fn updateType(
25262573 ) else try wip_nav.refType(ptr_child_type);
25272574 }
25282575 if (ptr_type.flags.is_volatile) {
2529 try uleb128(diw, @intFromEnum(AbbrevCode.is_volatile));
2576 try wip_nav.abbrevCode(.is_volatile);
25302577 try wip_nav.refType(ptr_child_type);
25312578 }
25322579 },
25332580 .Slice => {
2534 try uleb128(diw, @intFromEnum(AbbrevCode.struct_type));
2581 try wip_nav.abbrevCode(.struct_type);
25352582 try wip_nav.strp(name);
25362583 try uleb128(diw, ty.abiSize(pt));
25372584 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2538 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2585 try wip_nav.abbrevCode(.generated_field);
25392586 try wip_nav.strp("ptr");
25402587 const ptr_field_type = ty.slicePtrFieldType(zcu);
25412588 try wip_nav.refType(ptr_field_type);
25422589 try uleb128(diw, 0);
2543 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2590 try wip_nav.abbrevCode(.generated_field);
25442591 try wip_nav.strp("len");
25452592 const len_field_type = Type.usize;
25462593 try wip_nav.refType(len_field_type);
......@@ -2549,28 +2596,28 @@ fn updateType(
25492596 },
25502597 },
25512598 inline .array_type, .vector_type => |array_type, ty_tag| {
2552 try uleb128(diw, @intFromEnum(AbbrevCode.array_type));
2599 try wip_nav.abbrevCode(.array_type);
25532600 try wip_nav.strp(name);
25542601 try wip_nav.refType(Type.fromInterned(array_type.child));
25552602 try diw.writeByte(@intFromBool(ty_tag == .vector_type));
2556 try uleb128(diw, @intFromEnum(AbbrevCode.array_index));
2603 try wip_nav.abbrevCode(.array_index);
25572604 try wip_nav.refType(Type.usize);
25582605 try uleb128(diw, array_type.len);
25592606 try uleb128(diw, @intFromEnum(AbbrevCode.null));
25602607 },
25612608 .opt_type => |opt_child_type_index| {
25622609 const opt_child_type = Type.fromInterned(opt_child_type_index);
2563 try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
2610 try wip_nav.abbrevCode(.union_type);
25642611 try wip_nav.strp(name);
25652612 try uleb128(diw, ty.abiSize(pt));
25662613 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
25672614 if (opt_child_type.isNoReturn(zcu)) {
2568 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2615 try wip_nav.abbrevCode(.generated_field);
25692616 try wip_nav.strp("null");
25702617 try wip_nav.refType(Type.null);
25712618 try uleb128(diw, 0);
25722619 } else {
2573 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
2620 try wip_nav.abbrevCode(.tagged_union);
25742621 try wip_nav.infoSectionOffset(
25752622 .debug_info,
25762623 wip_nav.unit,
......@@ -2578,7 +2625,7 @@ fn updateType(
25782625 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
25792626 );
25802627 {
2581 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2628 try wip_nav.abbrevCode(.generated_field);
25822629 try wip_nav.strp("has_value");
25832630 const repr: enum { unpacked, error_set, pointer } = switch (opt_child_type_index) {
25842631 .anyerror_type => .error_set,
......@@ -2609,19 +2656,19 @@ fn updateType(
26092656 },
26102657 }
26112658
2612 try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_tagged_union_field));
2659 try wip_nav.abbrevCode(.unsigned_tagged_union_field);
26132660 try uleb128(diw, 0);
26142661 {
2615 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2662 try wip_nav.abbrevCode(.generated_field);
26162663 try wip_nav.strp("null");
26172664 try wip_nav.refType(Type.null);
26182665 try uleb128(diw, 0);
26192666 }
26202667 try uleb128(diw, @intFromEnum(AbbrevCode.null));
26212668
2622 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union_default_field));
2669 try wip_nav.abbrevCode(.tagged_union_default_field);
26232670 {
2624 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2671 try wip_nav.abbrevCode(.generated_field);
26252672 try wip_nav.strp("?");
26262673 try wip_nav.refType(opt_child_type);
26272674 try uleb128(diw, 0);
......@@ -2644,7 +2691,7 @@ fn updateType(
26442691 },
26452692 };
26462693
2647 try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
2694 try wip_nav.abbrevCode(.union_type);
26482695 try wip_nav.strp(name);
26492696 if (error_union_type.error_set_type != .generic_poison_type and
26502697 error_union_type.payload_type != .generic_poison_type)
......@@ -2656,7 +2703,7 @@ fn updateType(
26562703 try uleb128(diw, 1);
26572704 }
26582705 {
2659 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
2706 try wip_nav.abbrevCode(.tagged_union);
26602707 try wip_nav.infoSectionOffset(
26612708 .debug_info,
26622709 wip_nav.unit,
......@@ -2664,7 +2711,7 @@ fn updateType(
26642711 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
26652712 );
26662713 {
2667 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2714 try wip_nav.abbrevCode(.generated_field);
26682715 try wip_nav.strp("is_error");
26692716 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
26702717 .signedness = .unsigned,
......@@ -2672,19 +2719,19 @@ fn updateType(
26722719 } })));
26732720 try uleb128(diw, error_union_error_set_offset);
26742721
2675 try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_tagged_union_field));
2722 try wip_nav.abbrevCode(.unsigned_tagged_union_field);
26762723 try uleb128(diw, 0);
26772724 {
2678 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2725 try wip_nav.abbrevCode(.generated_field);
26792726 try wip_nav.strp("value");
26802727 try wip_nav.refType(error_union_payload_type);
26812728 try uleb128(diw, error_union_payload_offset);
26822729 }
26832730 try uleb128(diw, @intFromEnum(AbbrevCode.null));
26842731
2685 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union_default_field));
2732 try wip_nav.abbrevCode(.tagged_union_default_field);
26862733 {
2687 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
2734 try wip_nav.abbrevCode(.generated_field);
26882735 try wip_nav.strp("error");
26892736 try wip_nav.refType(error_union_error_set_type);
26902737 try uleb128(diw, error_union_error_set_offset);
......@@ -2715,7 +2762,7 @@ fn updateType(
27152762 .c_longdouble,
27162763 .bool,
27172764 => {
2718 try uleb128(diw, @intFromEnum(AbbrevCode.numeric_type));
2765 try wip_nav.abbrevCode(.numeric_type);
27192766 try wip_nav.strp(name);
27202767 try diw.writeByte(if (type_index == .bool_type)
27212768 DW.ATE.boolean
......@@ -2742,7 +2789,7 @@ fn updateType(
27422789 .enum_literal,
27432790 .generic_poison,
27442791 => {
2745 try uleb128(diw, @intFromEnum(AbbrevCode.void_type));
2792 try wip_nav.abbrevCode(.void_type);
27462793 try wip_nav.strp(if (type_index == .generic_poison_type) "anytype" else name);
27472794 },
27482795 .anyerror => return, // delay until flush
......@@ -2752,15 +2799,19 @@ fn updateType(
27522799 .union_type,
27532800 .opaque_type,
27542801 => unreachable,
2755 .anon_struct_type => |anon_struct_type| {
2756 try uleb128(diw, @intFromEnum(AbbrevCode.struct_type));
2802 .anon_struct_type => |anon_struct_type| if (anon_struct_type.types.len == 0) {
2803 try wip_nav.abbrevCode(.namespace_struct_type);
2804 try wip_nav.strp(name);
2805 try diw.writeByte(@intFromBool(false));
2806 } else {
2807 try wip_nav.abbrevCode(.struct_type);
27572808 try wip_nav.strp(name);
27582809 try uleb128(diw, ty.abiSize(pt));
27592810 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
27602811 var field_byte_offset: u64 = 0;
27612812 for (0..anon_struct_type.types.len) |field_index| {
27622813 const comptime_value = anon_struct_type.values.get(ip)[field_index];
2763 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (comptime_value != .none) .struct_field_comptime else .struct_field)));
2814 try wip_nav.abbrevCode(if (comptime_value != .none) .struct_field_comptime else .struct_field);
27642815 if (anon_struct_type.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
27652816 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
27662817 defer dwarf.gpa.free(field_name);
......@@ -2780,7 +2831,7 @@ fn updateType(
27802831 },
27812832 .enum_type => {
27822833 const loaded_enum = ip.loadEnumType(type_index);
2783 try uleb128(diw, @intFromEnum(AbbrevCode.enum_type));
2834 try wip_nav.abbrevCode(.enum_type);
27842835 try wip_nav.strp(name);
27852836 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
27862837 for (0..loaded_enum.names.len) |field_index| {
......@@ -2794,7 +2845,7 @@ fn updateType(
27942845 },
27952846 .func_type => |func_type| {
27962847 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
2797 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_nullary) .nullary_func_type else .func_type)));
2848 try wip_nav.abbrevCode(if (is_nullary) .nullary_func_type else .func_type);
27982849 try wip_nav.strp(name);
27992850 try diw.writeByte(@intFromEnum(@as(DW.CC, switch (func_type.cc) {
28002851 .Unspecified, .C => .normal,
......@@ -2814,15 +2865,15 @@ fn updateType(
28142865 try wip_nav.refType(Type.fromInterned(func_type.return_type));
28152866 if (!is_nullary) {
28162867 for (0..func_type.param_types.len) |param_index| {
2817 try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
2868 try wip_nav.abbrevCode(.func_type_param);
28182869 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
28192870 }
2820 if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
2871 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
28212872 try uleb128(diw, @intFromEnum(AbbrevCode.null));
28222873 }
28232874 },
28242875 .error_set_type => |error_set_type| {
2825 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (error_set_type.names.len > 0) .enum_type else .empty_enum_type)));
2876 try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .enum_type else .empty_enum_type);
28262877 try wip_nav.strp(name);
28272878 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
28282879 .signedness = .unsigned,
......@@ -2830,7 +2881,7 @@ fn updateType(
28302881 } })));
28312882 for (0..error_set_type.names.len) |field_index| {
28322883 const field_name = error_set_type.names.get(ip)[field_index];
2833 try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_enum_field));
2884 try wip_nav.abbrevCode(.unsigned_enum_field);
28342885 try uleb128(diw, ip.getErrorValueIfExists(field_name).?);
28352886 try wip_nav.strp(field_name.toSlice(ip));
28362887 }
......@@ -2838,11 +2889,11 @@ fn updateType(
28382889 },
28392890 .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) {
28402891 .none => {
2841 try uleb128(diw, @intFromEnum(AbbrevCode.void_type));
2892 try wip_nav.abbrevCode(.void_type);
28422893 try wip_nav.strp(name);
28432894 },
28442895 else => |ies| {
2845 try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type));
2896 try wip_nav.abbrevCode(.inferred_error_set_type);
28462897 try wip_nav.strp(name);
28472898 try wip_nav.refType(Type.fromInterned(ies));
28482899 },
......@@ -2894,7 +2945,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
28942945 .func = .none,
28952946 .func_sym_index = undefined,
28962947 .func_high_reloc = undefined,
2897 .inlined_funcs_high_reloc = undefined,
2948 .inlined_funcs = undefined,
28982949 .debug_info = .{},
28992950 .debug_line = .{},
29002951 .debug_loclists = .{},
......@@ -2905,7 +2956,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
29052956 const loaded_struct = ip.loadStructType(type_index);
29062957
29072958 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2908 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0) .namespace_file else .file)));
2959 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_file else .file);
29092960 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
29102961 try uleb128(diw, file_gop.index);
29112962 try wip_nav.strp(loaded_struct.name.toSlice(ip));
......@@ -2914,7 +2965,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
29142965 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
29152966 for (0..loaded_struct.field_types.len) |field_index| {
29162967 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
2917 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_comptime) .struct_field_comptime else .struct_field)));
2968 try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
29182969 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
29192970 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
29202971 defer dwarf.gpa.free(field_name);
......@@ -2957,7 +3008,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
29573008 .func = .none,
29583009 .func_sym_index = undefined,
29593010 .func_high_reloc = undefined,
2960 .inlined_funcs_high_reloc = undefined,
3011 .inlined_funcs = undefined,
29613012 .debug_info = .{},
29623013 .debug_line = .{},
29633014 .debug_loclists = .{},
......@@ -2973,17 +3024,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
29733024 const loaded_struct = ip.loadStructType(type_index);
29743025 switch (loaded_struct.layout) {
29753026 .auto, .@"extern" => {
2976 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0)
2977 .namespace_struct_type
2978 else
2979 .struct_type)));
3027 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_struct_type else .struct_type);
29803028 try wip_nav.strp(name);
29813029 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
29823030 try uleb128(diw, ty.abiSize(pt));
29833031 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
29843032 for (0..loaded_struct.field_types.len) |field_index| {
29853033 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
2986 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_comptime) .struct_field_comptime else .struct_field)));
3034 try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
29873035 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
29883036 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
29893037 defer dwarf.gpa.free(field_name);
......@@ -3001,12 +3049,12 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30013049 }
30023050 },
30033051 .@"packed" => {
3004 try uleb128(diw, @intFromEnum(AbbrevCode.packed_struct_type));
3052 try wip_nav.abbrevCode(.packed_struct_type);
30053053 try wip_nav.strp(name);
30063054 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
30073055 var field_bit_offset: u16 = 0;
30083056 for (0..loaded_struct.field_types.len) |field_index| {
3009 try uleb128(diw, @intFromEnum(@as(AbbrevCode, .packed_struct_field)));
3057 try wip_nav.abbrevCode(.packed_struct_field);
30103058 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
30113059 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
30123060 try wip_nav.refType(field_type);
......@@ -3019,7 +3067,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30193067 },
30203068 .enum_type => {
30213069 const loaded_enum = ip.loadEnumType(type_index);
3022 try uleb128(diw, @intFromEnum(AbbrevCode.enum_type));
3070 try wip_nav.abbrevCode(.enum_type);
30233071 try wip_nav.strp(name);
30243072 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
30253073 for (0..loaded_enum.names.len) |field_index| {
......@@ -3033,14 +3081,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30333081 },
30343082 .union_type => {
30353083 const loaded_union = ip.loadUnionType(type_index);
3036 try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
3084 try wip_nav.abbrevCode(.union_type);
30373085 try wip_nav.strp(name);
30383086 const union_layout = pt.getUnionLayout(loaded_union);
30393087 try uleb128(diw, union_layout.abi_size);
30403088 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
30413089 const loaded_tag = loaded_union.loadTagType(ip);
30423090 if (loaded_union.hasTag(ip)) {
3043 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
3091 try wip_nav.abbrevCode(.tagged_union);
30443092 try wip_nav.infoSectionOffset(
30453093 .debug_info,
30463094 wip_nav.unit,
......@@ -3048,7 +3096,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30483096 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
30493097 );
30503098 {
3051 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
3099 try wip_nav.abbrevCode(.generated_field);
30523100 try wip_nav.strp("tag");
30533101 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
30543102 try uleb128(diw, union_layout.tagOffset());
......@@ -3059,7 +3107,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30593107 .unsigned = .unsigned_tagged_union_field,
30603108 }, field_index);
30613109 {
3062 try uleb128(diw, @intFromEnum(AbbrevCode.struct_field));
3110 try wip_nav.abbrevCode(.struct_field);
30633111 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
30643112 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
30653113 try wip_nav.refType(field_type);
......@@ -3075,7 +3123,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30753123 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
30763124 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
30773125 } else for (0..loaded_union.field_types.len) |field_index| {
3078 try uleb128(diw, @intFromEnum(AbbrevCode.untagged_union_field));
3126 try wip_nav.abbrevCode(.untagged_union_field);
30793127 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
30803128 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
30813129 try wip_nav.refType(field_type);
......@@ -3085,7 +3133,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
30853133 try uleb128(diw, @intFromEnum(AbbrevCode.null));
30863134 },
30873135 .opaque_type => {
3088 try uleb128(diw, @intFromEnum(AbbrevCode.namespace_struct_type));
3136 try wip_nav.abbrevCode(.namespace_struct_type);
30893137 try wip_nav.strp(name);
30903138 try diw.writeByte(@intFromBool(true));
30913139 },
......@@ -3121,6 +3169,23 @@ pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {
31213169 _ = nav_index;
31223170}
31233171
3172fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(AbbrevCode).Enum.tag_type {
3173 assert(abbrev_code != .null);
3174 const entry: Entry.Index = @enumFromInt(@intFromEnum(abbrev_code));
3175 if (dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).getEntry(entry).len > 0) return @intFromEnum(abbrev_code);
3176 var debug_abbrev = std.ArrayList(u8).init(dwarf.gpa);
3177 defer debug_abbrev.deinit();
3178 const daw = debug_abbrev.writer();
3179 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
3180 try uleb128(daw, @intFromEnum(abbrev_code));
3181 try uleb128(daw, @intFromEnum(abbrev.tag));
3182 try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
3183 for (abbrev.attrs) |*attr| inline for (attr) |info| try uleb128(daw, @intFromEnum(info));
3184 for (0..2) |_| try uleb128(daw, 0);
3185 try dwarf.debug_abbrev.section.replaceEntry(DebugAbbrev.unit, entry, dwarf, debug_abbrev.items);
3186 return @intFromEnum(abbrev_code);
3187}
3188
31243189pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31253190 const ip = &pt.zcu.intern_pool;
31263191 if (dwarf.types.get(.anyerror_type)) |entry| {
......@@ -3133,7 +3198,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31333198 .func = .none,
31343199 .func_sym_index = undefined,
31353200 .func_high_reloc = undefined,
3136 .inlined_funcs_high_reloc = undefined,
3201 .inlined_funcs = undefined,
31373202 .debug_info = .{},
31383203 .debug_line = .{},
31393204 .debug_loclists = .{},
......@@ -3142,14 +3207,14 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31423207 defer wip_nav.deinit();
31433208 const diw = wip_nav.debug_info.writer(dwarf.gpa);
31443209 const global_error_set_names = ip.global_error_set.getNamesFromMainThread();
3145 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (global_error_set_names.len > 0) .enum_type else .empty_enum_type)));
3210 try wip_nav.abbrevCode(if (global_error_set_names.len > 0) .enum_type else .empty_enum_type);
31463211 try wip_nav.strp("anyerror");
31473212 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
31483213 .signedness = .unsigned,
31493214 .bits = pt.zcu.errorSetBits(),
31503215 } })));
31513216 for (global_error_set_names, 1..) |name, value| {
3152 try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_enum_field));
3217 try wip_nav.abbrevCode(.unsigned_enum_field);
31533218 try uleb128(diw, value);
31543219 try wip_nav.strp(name.toSlice(ip));
31553220 }
......@@ -3173,21 +3238,6 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31733238
31743239 var header = std.ArrayList(u8).init(dwarf.gpa);
31753240 defer header.deinit();
3176 if (dwarf.debug_abbrev.section.dirty) {
3177 for (1.., &AbbrevCode.abbrevs) |code, *abbrev| {
3178 try uleb128(header.writer(), code);
3179 try uleb128(header.writer(), @intFromEnum(abbrev.tag));
3180 try header.append(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
3181 for (abbrev.attrs) |*attr| {
3182 try uleb128(header.writer(), @intFromEnum(attr[0]));
3183 try uleb128(header.writer(), @intFromEnum(attr[1]));
3184 }
3185 try header.appendSlice(&.{ 0, 0 });
3186 }
3187 try header.append(@intFromEnum(AbbrevCode.null));
3188 try dwarf.debug_abbrev.section.replaceEntry(DebugAbbrev.unit, DebugAbbrev.entry, dwarf, header.items);
3189 dwarf.debug_abbrev.section.dirty = false;
3190 }
31913241 if (dwarf.debug_aranges.section.dirty) {
31923242 for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
31933243 const unit: Unit.Index = @enumFromInt(unit_index);
......@@ -3245,11 +3295,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
32453295 .source_off = @intCast(header.items.len),
32463296 .target_sec = .debug_abbrev,
32473297 .target_unit = DebugAbbrev.unit,
3248 .target_entry = DebugAbbrev.entry.toOptional(),
32493298 });
32503299 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
32513300 const compile_unit_off: u32 = @intCast(header.items.len);
3252 uleb128(header.fixedWriter(), @intFromEnum(AbbrevCode.compile_unit)) catch unreachable;
3301 uleb128(header.fixedWriter(), try dwarf.refAbbrevCode(.compile_unit)) catch unreachable;
32533302 header.appendAssumeCapacity(DW.LANG.Zig);
32543303 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
32553304 .source_off = @intCast(header.items.len),
......@@ -3292,7 +3341,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
32923341 });
32933342 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
32943343 uleb128(header.fixedWriter(), 0) catch unreachable;
3295 uleb128(header.fixedWriter(), @intFromEnum(AbbrevCode.module)) catch unreachable;
3344 uleb128(header.fixedWriter(), try dwarf.refAbbrevCode(.module)) catch unreachable;
32963345 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
32973346 .source_off = @intCast(header.items.len),
32983347 .target_sec = .debug_str,
......@@ -3306,6 +3355,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
33063355 }
33073356 dwarf.debug_info.section.dirty = false;
33083357 }
3358 if (dwarf.debug_abbrev.section.dirty) {
3359 assert(!dwarf.debug_info.section.dirty);
3360 try dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).writeTrailer(&dwarf.debug_abbrev.section, dwarf);
3361 dwarf.debug_abbrev.section.dirty = false;
3362 }
33093363 if (dwarf.debug_str.section.dirty) {
33103364 const contents = dwarf.debug_str.contents.items;
33113365 try dwarf.debug_str.section.resize(dwarf, contents.len);
......@@ -3313,8 +3367,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
33133367 dwarf.debug_str.section.dirty = false;
33143368 }
33153369 if (dwarf.debug_line.section.dirty) {
3316 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit|
3317 try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())));
3370 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| try unit.resizeHeader(
3371 &dwarf.debug_line.section,
3372 dwarf,
3373 DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())),
3374 );
33183375 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
33193376 unit.clear();
33203377 try unit.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count()));
......@@ -3333,14 +3390,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
33333390 }
33343391 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);
33353392 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
3336 switch (dwarf.format) {
3337 inline .@"32", .@"64" => |format| std.mem.writeInt(
3338 SectionOffset(format),
3339 header.addManyAsArrayAssumeCapacity(@sizeOf(SectionOffset(format))),
3340 @intCast(unit.header_len - header.items.len),
3341 dwarf.endian,
3342 ),
3343 }
3393 dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), unit.header_len - header.items.len);
33443394 const StandardOpcode = DeclValEnum(DW.LNS);
33453395 header.appendSliceAssumeCapacity(&[_]u8{
33463396 dwarf.debug_line.header.minimum_instruction_length,
......@@ -3422,6 +3472,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
34223472 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off);
34233473 dwarf.debug_line_str.section.dirty = false;
34243474 }
3475 if (dwarf.debug_loclists.section.dirty) {
3476 dwarf.debug_loclists.section.dirty = false;
3477 }
34253478 if (dwarf.debug_rnglists.section.dirty) {
34263479 for (dwarf.debug_rnglists.section.units.items) |*unit| {
34273480 header.clearRetainingCapacity();
......@@ -3440,19 +3493,20 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
34403493 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);
34413494 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
34423495 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(@sizeOf(u32)), 1, dwarf.endian);
3443 switch (dwarf.format) {
3444 inline .@"32", .@"64" => |format| std.mem.writeInt(
3445 SectionOffset(format),
3446 header.addManyAsArrayAssumeCapacity(@sizeOf(SectionOffset(format))),
3447 @sizeOf(SectionOffset(format)),
3448 dwarf.endian,
3449 ),
3450 }
3496 dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), dwarf.sectionOffsetBytes() * 1);
34513497 try unit.replaceHeader(&dwarf.debug_rnglists.section, dwarf, header.items);
34523498 try unit.writeTrailer(&dwarf.debug_rnglists.section, dwarf);
34533499 }
34543500 dwarf.debug_rnglists.section.dirty = false;
34553501 }
3502 assert(!dwarf.debug_abbrev.section.dirty);
3503 assert(!dwarf.debug_aranges.section.dirty);
3504 assert(!dwarf.debug_info.section.dirty);
3505 assert(!dwarf.debug_line.section.dirty);
3506 assert(!dwarf.debug_line_str.section.dirty);
3507 assert(!dwarf.debug_loclists.section.dirty);
3508 assert(!dwarf.debug_rnglists.section.dirty);
3509 assert(!dwarf.debug_str.section.dirty);
34563510}
34573511
34583512pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void {
......@@ -3491,7 +3545,7 @@ fn DeclValEnum(comptime T: type) type {
34913545 } });
34923546}
34933547
3494const AbbrevCode = enum(u8) {
3548const AbbrevCode = enum {
34953549 null,
34963550 // padding codes must be one byte uleb128 values to function
34973551 pad_1,
......@@ -3499,15 +3553,16 @@ const AbbrevCode = enum(u8) {
34993553 // decl codes are assumed to all have the same uleb128 length
35003554 decl_alias,
35013555 decl_enum,
3556 decl_empty_enum,
35023557 decl_namespace_struct,
35033558 decl_struct,
35043559 decl_packed_struct,
35053560 decl_union,
35063561 decl_var,
35073562 decl_func,
3508 decl_func_empty,
3563 decl_empty_func,
35093564 decl_func_generic,
3510 decl_func_generic_empty,
3565 decl_empty_func_generic,
35113566 // the rest are unrestricted
35123567 compile_unit,
35133568 module,
......@@ -3542,11 +3597,12 @@ const AbbrevCode = enum(u8) {
35423597 struct_type,
35433598 packed_struct_type,
35443599 union_type,
3600 empty_inlined_func,
35453601 inlined_func,
35463602 local_arg,
35473603 local_var,
35483604
3549 const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_generic_empty));
3605 const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_empty_func_generic));
35503606
35513607 const Attr = struct {
35523608 DeclValEnum(DW.AT),
......@@ -3586,6 +3642,12 @@ const AbbrevCode = enum(u8) {
35863642 .{ .type, .ref_addr },
35873643 },
35883644 },
3645 .decl_empty_enum = .{
3646 .tag = .enumeration_type,
3647 .attrs = decl_abbrev_common_attrs ++ .{
3648 .{ .type, .ref_addr },
3649 },
3650 },
35893651 .decl_namespace_struct = .{
35903652 .tag = .structure_type,
35913653 .attrs = decl_abbrev_common_attrs ++ .{
......@@ -3638,7 +3700,7 @@ const AbbrevCode = enum(u8) {
36383700 .{ .noreturn, .flag },
36393701 },
36403702 },
3641 .decl_func_empty = .{
3703 .decl_empty_func = .{
36423704 .tag = .subprogram,
36433705 .attrs = decl_abbrev_common_attrs ++ .{
36443706 .{ .linkage_name, .strp },
......@@ -3657,7 +3719,7 @@ const AbbrevCode = enum(u8) {
36573719 .{ .type, .ref_addr },
36583720 },
36593721 },
3660 .decl_func_generic_empty = .{
3722 .decl_empty_func_generic = .{
36613723 .tag = .subprogram,
36623724 .attrs = decl_abbrev_common_attrs ++ .{
36633725 .{ .type, .ref_addr },
......@@ -3918,6 +3980,16 @@ const AbbrevCode = enum(u8) {
39183980 .{ .alignment, .udata },
39193981 },
39203982 },
3983 .empty_inlined_func = .{
3984 .tag = .inlined_subroutine,
3985 .attrs = &.{
3986 .{ .abstract_origin, .ref_addr },
3987 .{ .call_line, .udata },
3988 .{ .call_column, .udata },
3989 .{ .low_pc, .addr },
3990 .{ .high_pc, .addr },
3991 },
3992 },
39213993 .inlined_func = .{
39223994 .tag = .inlined_subroutine,
39233995 .children = true,
......@@ -3946,7 +4018,7 @@ const AbbrevCode = enum(u8) {
39464018 },
39474019 },
39484020 .null = undefined,
3949 }).values[1..].*;
4021 });
39504022};
39514023
39524024fn getFile(dwarf: *Dwarf) ?std.fs.File {
......@@ -3955,11 +4027,11 @@ fn getFile(dwarf: *Dwarf) ?std.fs.File {
39554027}
39564028
39574029fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {
3958 const entry = try dwarf.debug_aranges.section.addEntry(unit, dwarf);
3959 assert(try dwarf.debug_info.section.addEntry(unit, dwarf) == entry);
3960 assert(try dwarf.debug_line.section.addEntry(unit, dwarf) == entry);
3961 assert(try dwarf.debug_loclists.section.addEntry(unit, dwarf) == entry);
3962 assert(try dwarf.debug_rnglists.section.addEntry(unit, dwarf) == entry);
4030 const entry = try dwarf.debug_aranges.section.getUnit(unit).addEntry(dwarf.gpa);
4031 assert(try dwarf.debug_info.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
4032 assert(try dwarf.debug_line.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
4033 assert(try dwarf.debug_loclists.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
4034 assert(try dwarf.debug_rnglists.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
39634035 return entry;
39644036}
39654037
......@@ -3993,13 +4065,6 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 {
39934065 };
39944066}
39954067
3996fn SectionOffset(comptime format: DW.Format) type {
3997 return switch (format) {
3998 .@"32" => u32,
3999 .@"64" => u64,
4000 };
4001}
4002
40034068fn uleb128Bytes(value: anytype) u32 {
40044069 var cw = std.io.countingWriter(std.io.null_writer);
40054070 try uleb128(cw.writer(), value);