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 {...@@ -89,6 +89,7 @@ pub const LNS = struct {
89};89};
9090
91pub const LNE = struct {91pub const LNE = struct {
92 pub const padding = 0x00;
92 pub const end_sequence = 0x01;93 pub const end_sequence = 0x01;
93 pub const set_address = 0x02;94 pub const set_address = 0x02;
94 pub const define_file = 0x03;95 pub const define_file = 0x03;
src/link/Dwarf.zig+334-269
...@@ -55,7 +55,10 @@ const ModInfo = struct {...@@ -55,7 +55,10 @@ const ModInfo = struct {
55const DebugAbbrev = struct {55const DebugAbbrev = struct {
56 section: Section,56 section: Section,
57 const unit: Unit.Index = @enumFromInt(0);57 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));
59};62};
6063
61const DebugAranges = struct {64const DebugAranges = struct {
...@@ -119,8 +122,7 @@ const DebugLine = struct {...@@ -119,8 +122,7 @@ const DebugLine = struct {
119 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;122 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;
120 }123 }
121124
122 const trailer_bytes = 1 + uleb128Bytes(0) +125 const trailer_bytes = 1 + uleb128Bytes(1) + 1;
123 1 + uleb128Bytes(1) + 1;
124};126};
125127
126const DebugLocLists = struct {128const DebugLocLists = struct {
...@@ -173,10 +175,15 @@ const StringSection = struct {...@@ -173,10 +175,15 @@ const StringSection = struct {
173 errdefer _ = str_sec.map.pop();175 errdefer _ = str_sec.map.pop();
174 const entry: Entry.Index = @enumFromInt(gop.index);176 const entry: Entry.Index = @enumFromInt(gop.index);
175 if (!gop.found_existing) {177 if (!gop.found_existing) {
176 assert(try str_sec.section.addEntry(unit, dwarf) == entry);178 const unit_ptr = str_sec.section.getUnit(unit);
177 errdefer _ = str_sec.section.getUnit(unit).entries.pop();179 assert(try str_sec.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
178 const entry_ptr = str_sec.section.getUnit(unit).getEntry(entry);180 errdefer _ = unit_ptr.entries.pop();
179 assert(entry_ptr.off == str_sec.contents.items.len);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);
180 entry_ptr.len = @intCast(str.len + 1);187 entry_ptr.len = @intCast(str.len + 1);
181 try str_sec.contents.ensureUnusedCapacity(dwarf.gpa, str.len + 1);188 try str_sec.contents.ensureUnusedCapacity(dwarf.gpa, str.len + 1);
182 str_sec.contents.appendSliceAssumeCapacity(str);189 str_sec.contents.appendSliceAssumeCapacity(str);
...@@ -243,7 +250,7 @@ pub const Section = struct {...@@ -243,7 +250,7 @@ pub const Section = struct {
243 fn addUnit(sec: *Section, header_len: u32, trailer_len: u32, dwarf: *Dwarf) UpdateError!Unit.Index {250 fn addUnit(sec: *Section, header_len: u32, trailer_len: u32, dwarf: *Dwarf) UpdateError!Unit.Index {
244 const unit: Unit.Index = @enumFromInt(sec.units.items.len);251 const unit: Unit.Index = @enumFromInt(sec.units.items.len);
245 const unit_ptr = try sec.units.addOne(dwarf.gpa);252 const unit_ptr = try sec.units.addOne(dwarf.gpa);
246 errdefer sec.popUnit();253 errdefer sec.popUnit(dwarf.gpa);
247 unit_ptr.* = .{254 unit_ptr.* = .{
248 .prev = sec.last,255 .prev = sec.last,
249 .next = .none,256 .next = .none,
...@@ -277,14 +284,11 @@ pub const Section = struct {...@@ -277,14 +284,11 @@ pub const Section = struct {
277 if (sec.last.unwrap().? == unit) sec.last = unit_ptr.prev;284 if (sec.last.unwrap().? == unit) sec.last = unit_ptr.prev;
278 }285 }
279286
280 fn popUnit(sec: *Section) void {287 fn popUnit(sec: *Section, gpa: std.mem.Allocator) void {
281 const unit: Unit.Index = @enumFromInt(sec.units.items.len - 1);288 const unit_index: Unit.Index = @enumFromInt(sec.units.items.len - 1);
282 sec.unlinkUnit(unit);289 sec.unlinkUnit(unit_index);
283 _ = sec.units.pop();290 var unit = sec.units.pop();
284 }291 unit.deinit(gpa);
285
286 fn addEntry(sec: *Section, unit: Unit.Index, dwarf: *Dwarf) UpdateError!Entry.Index {
287 return sec.getUnit(unit).addEntry(sec, dwarf);
288 }292 }
289293
290 pub fn getUnit(sec: *Section, unit: Unit.Index) *Unit {294 pub fn getUnit(sec: *Section, unit: Unit.Index) *Unit {
...@@ -293,7 +297,21 @@ pub const Section = struct {...@@ -293,7 +297,21 @@ pub const Section = struct {
293297
294 fn replaceEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, contents: []const u8) UpdateError!void {298 fn replaceEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
295 const unit_ptr = sec.getUnit(unit);299 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);
297 }315 }
298316
299 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {317 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
...@@ -391,11 +409,11 @@ const Unit = struct {...@@ -391,11 +409,11 @@ const Unit = struct {
391 unit.* = undefined;409 unit.* = undefined;
392 }410 }
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 {
395 const entry: Entry.Index = @enumFromInt(unit.entries.items.len);413 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);
397 entry_ptr.* = .{415 entry_ptr.* = .{
398 .prev = unit.last,416 .prev = .none,
399 .next = .none,417 .next = .none,
400 .off = 0,418 .off = 0,
401 .len = 0,419 .len = 0,
...@@ -404,14 +422,6 @@ const Unit = struct {...@@ -404,14 +422,6 @@ const Unit = struct {
404 .cross_section_relocs = .{},422 .cross_section_relocs = .{},
405 .external_relocs = .{},423 .external_relocs = .{},
406 };424 };
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();
415 return entry;425 return entry;
416 }426 }
417427
...@@ -509,42 +519,52 @@ const Unit = struct {...@@ -509,42 +519,52 @@ const Unit = struct {
509 const last_entry_ptr = unit.getEntry(last_entry);519 const last_entry_ptr = unit.getEntry(last_entry);
510 break :end last_entry_ptr.off + last_entry_ptr.len;520 break :end last_entry_ptr.off + last_entry_ptr.len;
511 } else 0;521 } else 0;
512 const end = if (unit.next.unwrap()) |next_unit|522 const end = if (unit.next.unwrap()) |next_unit| sec.getUnit(next_unit).off else sec.len;
513 sec.getUnit(next_unit).off523 const len: usize = @intCast(end - start);
514 else524 assert(len >= unit.trailer_len);
515 sec.len;525 if (sec == &dwarf.debug_line.section) {
516 const trailer_len: usize = @intCast(end - start);526 var buf: [1 + uleb128Bytes(std.math.maxInt(u32)) + 1]u8 = undefined;
517 assert(trailer_len >= unit.trailer_len);527 var fbs = std.io.fixedBufferStream(&buf);
518 var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, trailer_len);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);
519 defer trailer.deinit();549 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: {
521 trailer.appendNTimesAssumeCapacity(0, @intFromEnum(dwarf.address_size) * 2);555 trailer.appendNTimesAssumeCapacity(0, @intFromEnum(dwarf.address_size) * 2);
522 break :fill 0;556 break :fill 0;
523 } else if (sec == &dwarf.debug_info.section) fill: {557 } else if (sec == &dwarf.debug_info.section) fill: {
524 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);558 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
525 trailer.appendNTimesAssumeCapacity(@intFromEnum(AbbrevCode.null), 2);559 trailer.appendNTimesAssumeCapacity(@intFromEnum(AbbrevCode.null), 2);
526 break :fill @intFromEnum(AbbrevCode.null);560 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;
541 } else if (sec == &dwarf.debug_rnglists.section) fill: {561 } else if (sec == &dwarf.debug_rnglists.section) fill: {
542 trailer.appendAssumeCapacity(DW.RLE.end_of_list);562 trailer.appendAssumeCapacity(DW.RLE.end_of_list);
543 break :fill DW.RLE.end_of_list;563 break :fill DW.RLE.end_of_list;
544 } else unreachable;564 } else unreachable;
545 assert(trailer.items.len == unit.trailer_len);565 assert(trailer.items.len == unit.trailer_len);
546 trailer.appendNTimesAssumeCapacity(fill_byte, trailer_len - trailer.items.len);566 trailer.appendNTimesAssumeCapacity(fill_byte, len - trailer.items.len);
547 assert(trailer.items.len == trailer_len);567 assert(trailer.items.len == len);
548 try dwarf.getFile().?.pwriteAll(trailer.items, sec.off + start);568 try dwarf.getFile().?.pwriteAll(trailer.items, sec.off + start);
549 }569 }
550570
...@@ -625,45 +645,62 @@ const Entry = struct {...@@ -625,45 +645,62 @@ const Entry = struct {
625 };645 };
626646
627 fn pad(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void {647 fn pad(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void {
648 assert(entry.len > 0);
628 const start = entry.off + entry.len;649 const start = entry.off + entry.len;
629 const len = unit.getEntry(entry.next.unwrap() orelse return).off - start;650 const len = unit.getEntry(entry.next.unwrap() orelse return).off - start;
630 if (sec == &dwarf.debug_info.section) {651 var buf: [
631 var buf: [652 @max(
632 @max(653 uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)),
633 uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)),654 uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) + uleb128Bytes(std.math.maxInt(u32)),
634 uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) + uleb128Bytes(std.math.maxInt(u32)),655 1 + uleb128Bytes(std.math.maxInt(u32)) + 1,
635 )656 )
636 ]u8 = undefined;657 ]u8 = undefined;
637 var fbs = std.io.fixedBufferStream(&buf);658 var fbs = std.io.fixedBufferStream(&buf);
638 switch (len) {659 const writer = fbs.writer();
639 0 => {},660 if (sec == &dwarf.debug_info.section) switch (len) {
640 1 => uleb128(fbs.writer(), @intFromEnum(AbbrevCode.pad_1)) catch unreachable,661 0 => {},
641 else => {662 1 => uleb128(writer, try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
642 uleb128(fbs.writer(), @intFromEnum(AbbrevCode.pad_n)) catch unreachable;663 else => {
643 const abbrev_code_bytes = fbs.pos;664 uleb128(writer, try dwarf.refAbbrevCode(.pad_n)) catch unreachable;
644 var block_len_bytes: u5 = 1;665 const abbrev_code_bytes = fbs.pos;
645 while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {666 var block_len_bytes: u5 = 1;
646 .lt => break uleb128(fbs.writer(), len - abbrev_code_bytes - block_len_bytes) catch unreachable,667 while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {
647 .eq => {668 .lt => break uleb128(writer, len - abbrev_code_bytes - block_len_bytes) catch unreachable,
648 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte669 .eq => {
649 block_len_bytes += 1;670 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
650 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);671 block_len_bytes += 1;
651 fbs.pos += block_len_bytes;672 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
652 break;673 fbs.pos += block_len_bytes;
653 },674 break;
654 .gt => block_len_bytes += 1,675 },
655 };676 .gt => block_len_bytes += 1,
656 assert(fbs.pos == abbrev_code_bytes + block_len_bytes);677 };
657 },678 assert(fbs.pos == abbrev_code_bytes + block_len_bytes);
658 }679 },
659 assert(fbs.pos <= len);680 } else if (sec == &dwarf.debug_line.section) switch (len) {
660 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start);681 0 => {},
661 } else if (sec == &dwarf.debug_line.section) {682 1 => writer.writeByte(DW.LNS.const_add_pc) catch unreachable,
662 const buf = try dwarf.gpa.alloc(u8, len);683 else => {
663 defer dwarf.gpa.free(buf);684 writer.writeByte(DW.LNS.extended_op) catch unreachable;
664 @memset(buf, DW.LNS.const_add_pc);685 const extended_op_bytes = fbs.pos;
665 try dwarf.getFile().?.pwriteAll(buf, sec.off + unit.off + unit.header_len + start);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 },
666 } else assert(!sec.pad_to_ideal and len == 0);701 } 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);
667 }704 }
668705
669 fn replace(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void {706 fn replace(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
...@@ -691,15 +728,7 @@ const Entry = struct {...@@ -691,15 +728,7 @@ const Entry = struct {
691 try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(contents.len) + unit.trailer_len));728 try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(contents.len) + unit.trailer_len));
692 }729 }
693 entry_ptr.len = @intCast(contents.len);730 entry_ptr.len = @intCast(contents.len);
694 {731 if (entry_ptr.prev.unwrap()) |prev_entry| try unit.getEntry(prev_entry).pad(unit, sec, dwarf);
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 }
703 try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off + unit.header_len + entry_ptr.off);732 try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off + unit.header_len + entry_ptr.off);
704 try entry_ptr.pad(unit, sec, dwarf);733 try entry_ptr.pad(unit, sec, dwarf);
705 if (false) {734 if (false) {
...@@ -1039,7 +1068,10 @@ pub const WipNav = struct {...@@ -1039,7 +1068,10 @@ pub const WipNav = struct {
1039 func: InternPool.Index,1068 func: InternPool.Index,
1040 func_sym_index: u32,1069 func_sym_index: u32,
1041 func_high_reloc: u32,1070 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 }),
1043 debug_info: std.ArrayListUnmanaged(u8),1075 debug_info: std.ArrayListUnmanaged(u8),
1044 debug_line: std.ArrayListUnmanaged(u8),1076 debug_line: std.ArrayListUnmanaged(u8),
1045 debug_loclists: std.ArrayListUnmanaged(u8),1077 debug_loclists: std.ArrayListUnmanaged(u8),
...@@ -1047,7 +1079,7 @@ pub const WipNav = struct {...@@ -1047,7 +1079,7 @@ pub const WipNav = struct {
10471079
1048 pub fn deinit(wip_nav: *WipNav) void {1080 pub fn deinit(wip_nav: *WipNav) void {
1049 const gpa = wip_nav.dwarf.gpa;1081 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);
1051 wip_nav.debug_info.deinit(gpa);1083 wip_nav.debug_info.deinit(gpa);
1052 wip_nav.debug_line.deinit(gpa);1084 wip_nav.debug_line.deinit(gpa);
1053 wip_nav.debug_loclists.deinit(gpa);1085 wip_nav.debug_loclists.deinit(gpa);
...@@ -1066,15 +1098,14 @@ pub const WipNav = struct {...@@ -1066,15 +1098,14 @@ pub const WipNav = struct {
1066 ty: Type,1098 ty: Type,
1067 loc: Loc,1099 loc: Loc,
1068 ) UpdateError!void {1100 ) UpdateError!void {
1069 wip_nav.any_children = true;
1070 assert(wip_nav.func != .none);1101 assert(wip_nav.func != .none);
1071 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);1102 try wip_nav.abbrevCode(switch (tag) {
1072 try uleb128(diw, @intFromEnum(switch (tag) {
1073 inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),1103 inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),
1074 }));1104 });
1075 try wip_nav.strp(name);1105 try wip_nav.strp(name);
1076 try wip_nav.refType(ty);1106 try wip_nav.refType(ty);
1077 try wip_nav.exprloc(loc);1107 try wip_nav.exprloc(loc);
1108 wip_nav.any_children = true;
1078 }1109 }
10791110
1080 pub fn advancePCAndLine(1111 pub fn advancePCAndLine(
...@@ -1136,9 +1167,10 @@ pub const WipNav = struct {...@@ -1136,9 +1167,10 @@ pub const WipNav = struct {
1136 const dwarf = wip_nav.dwarf;1167 const dwarf = wip_nav.dwarf;
1137 const zcu = wip_nav.pt.zcu;1168 const zcu = wip_nav.pt.zcu;
1138 const diw = wip_nav.debug_info.writer(dwarf.gpa);1169 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);
1142 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);1174 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
1143 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);1175 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
1144 try uleb128(diw, column + 1);1176 try uleb128(diw, column + 1);
...@@ -1150,7 +1182,7 @@ pub const WipNav = struct {...@@ -1150,7 +1182,7 @@ pub const WipNav = struct {
1150 .target_off = code_off,1182 .target_off = code_off,
1151 });1183 });
1152 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));1184 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);
1154 external_relocs.appendAssumeCapacity(.{1186 external_relocs.appendAssumeCapacity(.{
1155 .source_off = @intCast(wip_nav.debug_info.items.len),1187 .source_off = @intCast(wip_nav.debug_info.items.len),
1156 .target_sym = wip_nav.func_sym_index,1188 .target_sym = wip_nav.func_sym_index,
...@@ -1158,17 +1190,27 @@ pub const WipNav = struct {...@@ -1158,17 +1190,27 @@ pub const WipNav = struct {
1158 });1190 });
1159 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));1191 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1160 try wip_nav.setInlineFunc(func);1192 try wip_nav.setInlineFunc(func);
1193 wip_nav.any_children = false;
1161 }1194 }
11621195
1163 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {1196 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();
1164 const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;1199 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;1200 external_relocs.items[inlined_func.high_reloc].target_off = code_off;
1166 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null));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 );
1167 try wip_nav.setInlineFunc(func);1209 try wip_nav.setInlineFunc(func);
1210 wip_nav.any_children = true;
1168 }1211 }
11691212
1170 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {1213 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {
1171 wip_nav.any_children = true;
1172 const zcu = wip_nav.pt.zcu;1214 const zcu = wip_nav.pt.zcu;
1173 const dwarf = wip_nav.dwarf;1215 const dwarf = wip_nav.dwarf;
1174 if (wip_nav.func == func) return;1216 if (wip_nav.func == func) return;
...@@ -1219,6 +1261,10 @@ pub const WipNav = struct {...@@ -1219,6 +1261,10 @@ pub const WipNav = struct {
1219 wip_nav.func = func;1261 wip_nav.func = func;
1220 }1262 }
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
1222 fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void {1268 fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void {
1223 const dwarf = wip_nav.dwarf;1269 const dwarf = wip_nav.dwarf;
1224 const gpa = dwarf.gpa;1270 const gpa = dwarf.gpa;
...@@ -1336,7 +1382,7 @@ pub const WipNav = struct {...@@ -1336,7 +1382,7 @@ pub const WipNav = struct {
1336 loaded_enum: InternPool.LoadedEnumType,1382 loaded_enum: InternPool.LoadedEnumType,
1337 abbrev_code: std.enums.EnumFieldStruct(std.builtin.Signedness, AbbrevCode, null),1383 abbrev_code: std.enums.EnumFieldStruct(std.builtin.Signedness, AbbrevCode, null),
1338 field_index: usize,1384 field_index: usize,
1339 ) std.mem.Allocator.Error!void {1385 ) UpdateError!void {
1340 const zcu = wip_nav.pt.zcu;1386 const zcu = wip_nav.pt.zcu;
1341 const ip = &zcu.intern_pool;1387 const ip = &zcu.intern_pool;
1342 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);1388 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
...@@ -1344,9 +1390,9 @@ pub const WipNav = struct {...@@ -1344,9 +1390,9 @@ pub const WipNav = struct {
1344 .comptime_int_type => .signed,1390 .comptime_int_type => .signed,
1345 else => Type.fromInterned(loaded_enum.tag_ty).intInfo(zcu).signedness,1391 else => Type.fromInterned(loaded_enum.tag_ty).intInfo(zcu).signedness,
1346 };1392 };
1347 try uleb128(diw, @intFromEnum(switch (signedness) {1393 try wip_nav.abbrevCode(switch (signedness) {
1348 inline .signed, .unsigned => |ct_signedness| @field(abbrev_code, @tagName(ct_signedness)),1394 inline .signed, .unsigned => |ct_signedness| @field(abbrev_code, @tagName(ct_signedness)),
1349 }));1395 });
1350 if (loaded_enum.values.len > 0) switch (ip.indexToKey(loaded_enum.values.get(ip)[field_index]).int.storage) {1396 if (loaded_enum.values.len > 0) switch (ip.indexToKey(loaded_enum.values.get(ip)[field_index]).int.storage) {
1351 .u64 => |value| switch (signedness) {1397 .u64 => |value| switch (signedness) {
1352 .signed => try sleb128(diw, value),1398 .signed => try sleb128(diw, value),
...@@ -1535,20 +1581,21 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {...@@ -1535,20 +1581,21 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
1535 dwarf.reloadSectionMetadata();1581 dwarf.reloadSectionMetadata();
15361582
1537 dwarf.debug_abbrev.section.pad_to_ideal = false;1583 dwarf.debug_abbrev.section.pad_to_ideal = false;
1538 assert(try dwarf.debug_abbrev.section.addUnit(0, 0, dwarf) == DebugAbbrev.unit);1584 assert(try dwarf.debug_abbrev.section.addUnit(DebugAbbrev.header_bytes, DebugAbbrev.trailer_bytes, dwarf) == DebugAbbrev.unit);
1539 errdefer dwarf.debug_abbrev.section.popUnit();1585 errdefer dwarf.debug_abbrev.section.popUnit(dwarf.gpa);
1540 assert(try dwarf.debug_abbrev.section.addEntry(DebugAbbrev.unit, dwarf) == DebugAbbrev.entry);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
1542 dwarf.debug_aranges.section.pad_to_ideal = false;1589 dwarf.debug_aranges.section.pad_to_ideal = false;
1543 dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);1590 dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);
15441591
1545 dwarf.debug_line_str.section.pad_to_ideal = false;1592 dwarf.debug_line_str.section.pad_to_ideal = false;
1546 assert(try dwarf.debug_line_str.section.addUnit(0, 0, dwarf) == StringSection.unit);1593 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
1549 dwarf.debug_str.section.pad_to_ideal = false;1596 dwarf.debug_str.section.pad_to_ideal = false;
1550 assert(try dwarf.debug_str.section.addUnit(0, 0, dwarf) == StringSection.unit);1597 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
1553 dwarf.debug_loclists.section.pad_to_ideal = false;1600 dwarf.debug_loclists.section.pad_to_ideal = false;
15541601
...@@ -1589,31 +1636,31 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {...@@ -1589,31 +1636,31 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
1589 DebugAranges.trailerBytes(dwarf),1636 DebugAranges.trailerBytes(dwarf),
1590 dwarf,1637 dwarf,
1591 ) == unit);1638 ) == unit);
1592 errdefer dwarf.debug_aranges.section.popUnit();1639 errdefer dwarf.debug_aranges.section.popUnit(dwarf.gpa);
1593 assert(try dwarf.debug_info.section.addUnit(1640 assert(try dwarf.debug_info.section.addUnit(
1594 DebugInfo.headerBytes(dwarf),1641 DebugInfo.headerBytes(dwarf),
1595 DebugInfo.trailer_bytes,1642 DebugInfo.trailer_bytes,
1596 dwarf,1643 dwarf,
1597 ) == unit);1644 ) == unit);
1598 errdefer dwarf.debug_info.section.popUnit();1645 errdefer dwarf.debug_info.section.popUnit(dwarf.gpa);
1599 assert(try dwarf.debug_line.section.addUnit(1646 assert(try dwarf.debug_line.section.addUnit(
1600 DebugLine.headerBytes(dwarf, 5, 25),1647 DebugLine.headerBytes(dwarf, 5, 25),
1601 DebugLine.trailer_bytes,1648 DebugLine.trailer_bytes,
1602 dwarf,1649 dwarf,
1603 ) == unit);1650 ) == unit);
1604 errdefer dwarf.debug_line.section.popUnit();1651 errdefer dwarf.debug_line.section.popUnit(dwarf.gpa);
1605 assert(try dwarf.debug_loclists.section.addUnit(1652 assert(try dwarf.debug_loclists.section.addUnit(
1606 DebugLocLists.headerBytes(dwarf),1653 DebugLocLists.headerBytes(dwarf),
1607 DebugLocLists.trailer_bytes,1654 DebugLocLists.trailer_bytes,
1608 dwarf,1655 dwarf,
1609 ) == unit);1656 ) == unit);
1610 errdefer dwarf.debug_loclists.section.popUnit();1657 errdefer dwarf.debug_loclists.section.popUnit(dwarf.gpa);
1611 assert(try dwarf.debug_rnglists.section.addUnit(1658 assert(try dwarf.debug_rnglists.section.addUnit(
1612 DebugRngLists.headerBytes(dwarf),1659 DebugRngLists.headerBytes(dwarf),
1613 DebugRngLists.trailer_bytes,1660 DebugRngLists.trailer_bytes,
1614 dwarf,1661 dwarf,
1615 ) == unit);1662 ) == unit);
1616 errdefer dwarf.debug_rnglists.section.popUnit();1663 errdefer dwarf.debug_rnglists.section.popUnit(dwarf.gpa);
1617 }1664 }
1618 return unit;1665 return unit;
1619}1666}
...@@ -1658,7 +1705,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -1658,7 +1705,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1658 .func = .none,1705 .func = .none,
1659 .func_sym_index = undefined,1706 .func_sym_index = undefined,
1660 .func_high_reloc = undefined,1707 .func_high_reloc = undefined,
1661 .inlined_funcs_high_reloc = undefined,1708 .inlined_funcs = undefined,
1662 .debug_info = .{},1709 .debug_info = .{},
1663 .debug_line = .{},1710 .debug_line = .{},
1664 .debug_loclists = .{},1711 .debug_loclists = .{},
...@@ -1699,7 +1746,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -1699,7 +1746,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1699 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };1746 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
17001747
1701 const diw = wip_nav.debug_info.writer(dwarf.gpa);1748 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1702 try uleb128(diw, @intFromEnum(AbbrevCode.decl_var));1749 try wip_nav.abbrevCode(.decl_var);
1703 try wip_nav.refType(Type.fromInterned(parent_type));1750 try wip_nav.refType(Type.fromInterned(parent_type));
1704 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));1751 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
1705 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);1752 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...@@ -1714,7 +1761,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1714 ty.abiAlignment(pt).toByteUnits().?);1761 ty.abiAlignment(pt).toByteUnits().?);
1715 try diw.writeByte(@intFromBool(false));1762 try diw.writeByte(@intFromBool(false));
1716 wip_nav.finishForward(ty_reloc_index);1763 wip_nav.finishForward(ty_reloc_index);
1717 try uleb128(diw, @intFromEnum(AbbrevCode.is_const));1764 try wip_nav.abbrevCode(.is_const);
1718 try wip_nav.refType(ty);1765 try wip_nav.refType(ty);
1719 },1766 },
1720 .variable => |variable| {1767 .variable => |variable| {
...@@ -1749,7 +1796,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -1749,7 +1796,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1749 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };1796 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
17501797
1751 const diw = wip_nav.debug_info.writer(dwarf.gpa);1798 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1752 try uleb128(diw, @intFromEnum(AbbrevCode.decl_var));1799 try wip_nav.abbrevCode(.decl_var);
1753 try wip_nav.refType(Type.fromInterned(parent_type));1800 try wip_nav.refType(Type.fromInterned(parent_type));
1754 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));1801 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
1755 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);1802 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...@@ -1799,10 +1846,10 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1799 const func_type = ip.indexToKey(func.ty).func_type;1846 const func_type = ip.indexToKey(func.ty).func_type;
1800 wip_nav.func = nav_val.toIntern();1847 wip_nav.func = nav_val.toIntern();
1801 wip_nav.func_sym_index = sym_index;1848 wip_nav.func_sym_index = sym_index;
1802 wip_nav.inlined_funcs_high_reloc = .{};1849 wip_nav.inlined_funcs = .{};
18031850
1804 const diw = wip_nav.debug_info.writer(dwarf.gpa);1851 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1805 try uleb128(diw, @intFromEnum(AbbrevCode.decl_func));1852 try wip_nav.abbrevCode(.decl_func);
1806 try wip_nav.refType(Type.fromInterned(parent_type));1853 try wip_nav.refType(Type.fromInterned(parent_type));
1807 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));1854 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
1808 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);1855 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
...@@ -1891,7 +1938,7 @@ pub fn finishWipNav(...@@ -1891,7 +1938,7 @@ pub fn finishWipNav(
1891 } else std.leb.writeUnsignedFixed(1938 } else std.leb.writeUnsignedFixed(
1892 AbbrevCode.decl_bytes,1939 AbbrevCode.decl_bytes,
1893 wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],1940 wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
1894 @intFromEnum(AbbrevCode.decl_func_empty),1941 try dwarf.refAbbrevCode(.decl_empty_func),
1895 );1942 );
18961943
1897 var aranges_entry = [1]u8{0} ** (8 + 8);1944 var aranges_entry = [1]u8{0} ** (8 + 8);
...@@ -1967,7 +2014,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -1967,7 +2014,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
1967 .func = .none,2014 .func = .none,
1968 .func_sym_index = undefined,2015 .func_sym_index = undefined,
1969 .func_high_reloc = undefined,2016 .func_high_reloc = undefined,
1970 .inlined_funcs_high_reloc = undefined,2017 .inlined_funcs = undefined,
1971 .debug_info = .{},2018 .debug_info = .{},
1972 .debug_line = .{},2019 .debug_line = .{},
1973 .debug_loclists = .{},2020 .debug_loclists = .{},
...@@ -1990,12 +2037,12 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -1990,12 +2037,12 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
1990 ) != abbrev_code_buf.len) return error.InputOutput;2037 ) != abbrev_code_buf.len) return error.InputOutput;
1991 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);2038 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
1992 const abbrev_code: AbbrevCode = @enumFromInt(2039 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,
1994 );2041 );
1995 switch (abbrev_code) {2042 switch (abbrev_code) {
1996 else => unreachable,2043 else => unreachable,
1997 .decl_func, .decl_func_empty => return,2044 .decl_func, .decl_empty_func => return,
1998 .decl_func_generic, .decl_func_generic_empty => {},2045 .decl_func_generic, .decl_empty_func_generic => {},
1999 }2046 }
2000 }2047 }
2001 entry_ptr.clear();2048 entry_ptr.clear();
...@@ -2017,7 +2064,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2017,7 +2064,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
20172064
2018 const func_type = ip.indexToKey(func.ty).func_type;2065 const func_type = ip.indexToKey(func.ty).func_type;
2019 const diw = wip_nav.debug_info.writer(dwarf.gpa);2066 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);
2021 try wip_nav.refType(Type.fromInterned(parent_type));2071 try wip_nav.refType(Type.fromInterned(parent_type));
2022 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2072 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2023 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2073 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...@@ -2027,10 +2077,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2027 try wip_nav.refType(Type.fromInterned(func_type.return_type));2077 try wip_nav.refType(Type.fromInterned(func_type.return_type));
2028 if (func_type.param_types.len > 0 or func_type.is_var_args) {2078 if (func_type.param_types.len > 0 or func_type.is_var_args) {
2029 for (0..func_type.param_types.len) |param_index| {2079 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);
2031 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));2081 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
2032 }2082 }
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);
2034 try uleb128(diw, @intFromEnum(AbbrevCode.null));2084 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2035 }2085 }
2036 },2086 },
...@@ -2088,10 +2138,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2088,10 +2138,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
20882138
2089 switch (loaded_struct.layout) {2139 switch (loaded_struct.layout) {
2090 .auto, .@"extern" => {2140 .auto, .@"extern" => {
2091 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0)2141 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
2092 .decl_namespace_struct
2093 else
2094 .decl_struct)));
2095 try wip_nav.refType(Type.fromInterned(parent_type));2142 try wip_nav.refType(Type.fromInterned(parent_type));
2096 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2143 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2097 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2144 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...@@ -2103,7 +2150,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2103 try uleb128(diw, nav_val.toType().abiAlignment(pt).toByteUnits().?);2150 try uleb128(diw, nav_val.toType().abiAlignment(pt).toByteUnits().?);
2104 for (0..loaded_struct.field_types.len) |field_index| {2151 for (0..loaded_struct.field_types.len) |field_index| {
2105 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);2152 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);
2107 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {2154 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
2108 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});2155 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
2109 defer dwarf.gpa.free(field_name);2156 defer dwarf.gpa.free(field_name);
...@@ -2121,7 +2168,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2121,7 +2168,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2121 }2168 }
2122 },2169 },
2123 .@"packed" => {2170 .@"packed" => {
2124 try uleb128(diw, @intFromEnum(AbbrevCode.decl_packed_struct));2171 try wip_nav.abbrevCode(.decl_packed_struct);
2125 try wip_nav.refType(Type.fromInterned(parent_type));2172 try wip_nav.refType(Type.fromInterned(parent_type));
2126 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2173 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2127 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2174 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...@@ -2131,7 +2178,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2131 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));2178 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
2132 var field_bit_offset: u16 = 0;2179 var field_bit_offset: u16 = 0;
2133 for (0..loaded_struct.field_types.len) |field_index| {2180 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);
2135 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));2182 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
2136 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);2183 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2137 try wip_nav.refType(field_type);2184 try wip_nav.refType(field_type);
...@@ -2150,7 +2197,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2150,7 +2197,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2150 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2197 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2151 wip_nav.entry = nav_gop.value_ptr.*;2198 wip_nav.entry = nav_gop.value_ptr.*;
2152 const diw = wip_nav.debug_info.writer(dwarf.gpa);2199 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2153 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));2200 try wip_nav.abbrevCode(.decl_alias);
2154 try wip_nav.refType(Type.fromInterned(parent_type));2201 try wip_nav.refType(Type.fromInterned(parent_type));
2155 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2202 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2156 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2203 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...@@ -2210,7 +2257,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2210 }2257 }
2211 wip_nav.entry = nav_gop.value_ptr.*;2258 wip_nav.entry = nav_gop.value_ptr.*;
2212 const diw = wip_nav.debug_info.writer(dwarf.gpa);2259 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);
2214 try wip_nav.refType(Type.fromInterned(parent_type));2261 try wip_nav.refType(Type.fromInterned(parent_type));
2215 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2262 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2216 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2263 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...@@ -2225,7 +2272,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2225 }, field_index);2272 }, field_index);
2226 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));2273 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
2227 }2274 }
2228 try uleb128(diw, @intFromEnum(AbbrevCode.null));2275 if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
2229 break :done;2276 break :done;
2230 }2277 }
22312278
...@@ -2235,7 +2282,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2235,7 +2282,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2235 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2282 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2236 wip_nav.entry = nav_gop.value_ptr.*;2283 wip_nav.entry = nav_gop.value_ptr.*;
2237 const diw = wip_nav.debug_info.writer(dwarf.gpa);2284 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2238 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));2285 try wip_nav.abbrevCode(.decl_alias);
2239 try wip_nav.refType(Type.fromInterned(parent_type));2286 try wip_nav.refType(Type.fromInterned(parent_type));
2240 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2287 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2241 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2288 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...@@ -2293,7 +2340,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2293 }2340 }
2294 wip_nav.entry = nav_gop.value_ptr.*;2341 wip_nav.entry = nav_gop.value_ptr.*;
2295 const diw = wip_nav.debug_info.writer(dwarf.gpa);2342 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2296 try uleb128(diw, @intFromEnum(AbbrevCode.decl_union));2343 try wip_nav.abbrevCode(.decl_union);
2297 try wip_nav.refType(Type.fromInterned(parent_type));2344 try wip_nav.refType(Type.fromInterned(parent_type));
2298 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2345 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2299 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2346 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...@@ -2305,7 +2352,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2305 try uleb128(diw, union_layout.abi_align.toByteUnits().?);2352 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
2306 const loaded_tag = loaded_union.loadTagType(ip);2353 const loaded_tag = loaded_union.loadTagType(ip);
2307 if (loaded_union.hasTag(ip)) {2354 if (loaded_union.hasTag(ip)) {
2308 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));2355 try wip_nav.abbrevCode(.tagged_union);
2309 try wip_nav.infoSectionOffset(2356 try wip_nav.infoSectionOffset(
2310 .debug_info,2357 .debug_info,
2311 wip_nav.unit,2358 wip_nav.unit,
...@@ -2313,7 +2360,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2313,7 +2360,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2313 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),2360 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
2314 );2361 );
2315 {2362 {
2316 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2363 try wip_nav.abbrevCode(.generated_field);
2317 try wip_nav.strp("tag");2364 try wip_nav.strp("tag");
2318 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));2365 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
2319 try uleb128(diw, union_layout.tagOffset());2366 try uleb128(diw, union_layout.tagOffset());
...@@ -2324,7 +2371,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2324,7 +2371,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2324 .unsigned = .unsigned_tagged_union_field,2371 .unsigned = .unsigned_tagged_union_field,
2325 }, field_index);2372 }, field_index);
2326 {2373 {
2327 try uleb128(diw, @intFromEnum(AbbrevCode.struct_field));2374 try wip_nav.abbrevCode(.struct_field);
2328 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));2375 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
2329 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);2376 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2330 try wip_nav.refType(field_type);2377 try wip_nav.refType(field_type);
...@@ -2340,7 +2387,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2340,7 +2387,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2340 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)2387 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
2341 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);2388 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
2342 } else for (0..loaded_union.field_types.len) |field_index| {2389 } 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);
2344 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));2391 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
2345 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);2392 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2346 try wip_nav.refType(field_type);2393 try wip_nav.refType(field_type);
...@@ -2357,7 +2404,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2357,7 +2404,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2357 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2404 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2358 wip_nav.entry = nav_gop.value_ptr.*;2405 wip_nav.entry = nav_gop.value_ptr.*;
2359 const diw = wip_nav.debug_info.writer(dwarf.gpa);2406 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2360 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));2407 try wip_nav.abbrevCode(.decl_alias);
2361 try wip_nav.refType(Type.fromInterned(parent_type));2408 try wip_nav.refType(Type.fromInterned(parent_type));
2362 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2409 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2363 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2410 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...@@ -2415,7 +2462,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2415 }2462 }
2416 wip_nav.entry = nav_gop.value_ptr.*;2463 wip_nav.entry = nav_gop.value_ptr.*;
2417 const diw = wip_nav.debug_info.writer(dwarf.gpa);2464 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);
2419 try wip_nav.refType(Type.fromInterned(parent_type));2466 try wip_nav.refType(Type.fromInterned(parent_type));
2420 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2467 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2421 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2468 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...@@ -2432,7 +2479,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2432 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2479 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2433 wip_nav.entry = nav_gop.value_ptr.*;2480 wip_nav.entry = nav_gop.value_ptr.*;
2434 const diw = wip_nav.debug_info.writer(dwarf.gpa);2481 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2435 try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));2482 try wip_nav.abbrevCode(.decl_alias);
2436 try wip_nav.refType(Type.fromInterned(parent_type));2483 try wip_nav.refType(Type.fromInterned(parent_type));
2437 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2484 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2438 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2485 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
...@@ -2473,7 +2520,7 @@ fn updateType(...@@ -2473,7 +2520,7 @@ fn updateType(
2473 .func = .none,2520 .func = .none,
2474 .func_sym_index = undefined,2521 .func_sym_index = undefined,
2475 .func_high_reloc = undefined,2522 .func_high_reloc = undefined,
2476 .inlined_funcs_high_reloc = undefined,2523 .inlined_funcs = undefined,
2477 .debug_info = .{},2524 .debug_info = .{},
2478 .debug_line = .{},2525 .debug_line = .{},
2479 .debug_loclists = .{},2526 .debug_loclists = .{},
...@@ -2493,7 +2540,7 @@ fn updateType(...@@ -2493,7 +2540,7 @@ fn updateType(
24932540
2494 switch (ip.indexToKey(type_index)) {2541 switch (ip.indexToKey(type_index)) {
2495 .int_type => |int_type| {2542 .int_type => |int_type| {
2496 try uleb128(diw, @intFromEnum(AbbrevCode.numeric_type));2543 try wip_nav.abbrevCode(.numeric_type);
2497 try wip_nav.strp(name);2544 try wip_nav.strp(name);
2498 try diw.writeByte(switch (int_type.signedness) {2545 try diw.writeByte(switch (int_type.signedness) {
2499 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),2546 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
...@@ -2505,7 +2552,7 @@ fn updateType(...@@ -2505,7 +2552,7 @@ fn updateType(
2505 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {2552 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
2506 .One, .Many, .C => {2553 .One, .Many, .C => {
2507 const ptr_child_type = Type.fromInterned(ptr_type.child);2554 const ptr_child_type = Type.fromInterned(ptr_type.child);
2508 try uleb128(diw, @intFromEnum(AbbrevCode.ptr_type));2555 try wip_nav.abbrevCode(.ptr_type);
2509 try wip_nav.strp(name);2556 try wip_nav.strp(name);
2510 try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse2557 try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse
2511 ptr_child_type.abiAlignment(pt).toByteUnits().?);2558 ptr_child_type.abiAlignment(pt).toByteUnits().?);
...@@ -2517,7 +2564,7 @@ fn updateType(...@@ -2517,7 +2564,7 @@ fn updateType(
2517 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),2564 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
2518 ) else try wip_nav.refType(ptr_child_type);2565 ) else try wip_nav.refType(ptr_child_type);
2519 if (ptr_type.flags.is_const) {2566 if (ptr_type.flags.is_const) {
2520 try uleb128(diw, @intFromEnum(AbbrevCode.is_const));2567 try wip_nav.abbrevCode(.is_const);
2521 if (ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(2568 if (ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
2522 .debug_info,2569 .debug_info,
2523 wip_nav.unit,2570 wip_nav.unit,
...@@ -2526,21 +2573,21 @@ fn updateType(...@@ -2526,21 +2573,21 @@ fn updateType(
2526 ) else try wip_nav.refType(ptr_child_type);2573 ) else try wip_nav.refType(ptr_child_type);
2527 }2574 }
2528 if (ptr_type.flags.is_volatile) {2575 if (ptr_type.flags.is_volatile) {
2529 try uleb128(diw, @intFromEnum(AbbrevCode.is_volatile));2576 try wip_nav.abbrevCode(.is_volatile);
2530 try wip_nav.refType(ptr_child_type);2577 try wip_nav.refType(ptr_child_type);
2531 }2578 }
2532 },2579 },
2533 .Slice => {2580 .Slice => {
2534 try uleb128(diw, @intFromEnum(AbbrevCode.struct_type));2581 try wip_nav.abbrevCode(.struct_type);
2535 try wip_nav.strp(name);2582 try wip_nav.strp(name);
2536 try uleb128(diw, ty.abiSize(pt));2583 try uleb128(diw, ty.abiSize(pt));
2537 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);2584 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2538 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2585 try wip_nav.abbrevCode(.generated_field);
2539 try wip_nav.strp("ptr");2586 try wip_nav.strp("ptr");
2540 const ptr_field_type = ty.slicePtrFieldType(zcu);2587 const ptr_field_type = ty.slicePtrFieldType(zcu);
2541 try wip_nav.refType(ptr_field_type);2588 try wip_nav.refType(ptr_field_type);
2542 try uleb128(diw, 0);2589 try uleb128(diw, 0);
2543 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2590 try wip_nav.abbrevCode(.generated_field);
2544 try wip_nav.strp("len");2591 try wip_nav.strp("len");
2545 const len_field_type = Type.usize;2592 const len_field_type = Type.usize;
2546 try wip_nav.refType(len_field_type);2593 try wip_nav.refType(len_field_type);
...@@ -2549,28 +2596,28 @@ fn updateType(...@@ -2549,28 +2596,28 @@ fn updateType(
2549 },2596 },
2550 },2597 },
2551 inline .array_type, .vector_type => |array_type, ty_tag| {2598 inline .array_type, .vector_type => |array_type, ty_tag| {
2552 try uleb128(diw, @intFromEnum(AbbrevCode.array_type));2599 try wip_nav.abbrevCode(.array_type);
2553 try wip_nav.strp(name);2600 try wip_nav.strp(name);
2554 try wip_nav.refType(Type.fromInterned(array_type.child));2601 try wip_nav.refType(Type.fromInterned(array_type.child));
2555 try diw.writeByte(@intFromBool(ty_tag == .vector_type));2602 try diw.writeByte(@intFromBool(ty_tag == .vector_type));
2556 try uleb128(diw, @intFromEnum(AbbrevCode.array_index));2603 try wip_nav.abbrevCode(.array_index);
2557 try wip_nav.refType(Type.usize);2604 try wip_nav.refType(Type.usize);
2558 try uleb128(diw, array_type.len);2605 try uleb128(diw, array_type.len);
2559 try uleb128(diw, @intFromEnum(AbbrevCode.null));2606 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2560 },2607 },
2561 .opt_type => |opt_child_type_index| {2608 .opt_type => |opt_child_type_index| {
2562 const opt_child_type = Type.fromInterned(opt_child_type_index);2609 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);
2564 try wip_nav.strp(name);2611 try wip_nav.strp(name);
2565 try uleb128(diw, ty.abiSize(pt));2612 try uleb128(diw, ty.abiSize(pt));
2566 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);2613 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2567 if (opt_child_type.isNoReturn(zcu)) {2614 if (opt_child_type.isNoReturn(zcu)) {
2568 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2615 try wip_nav.abbrevCode(.generated_field);
2569 try wip_nav.strp("null");2616 try wip_nav.strp("null");
2570 try wip_nav.refType(Type.null);2617 try wip_nav.refType(Type.null);
2571 try uleb128(diw, 0);2618 try uleb128(diw, 0);
2572 } else {2619 } else {
2573 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));2620 try wip_nav.abbrevCode(.tagged_union);
2574 try wip_nav.infoSectionOffset(2621 try wip_nav.infoSectionOffset(
2575 .debug_info,2622 .debug_info,
2576 wip_nav.unit,2623 wip_nav.unit,
...@@ -2578,7 +2625,7 @@ fn updateType(...@@ -2578,7 +2625,7 @@ fn updateType(
2578 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),2625 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
2579 );2626 );
2580 {2627 {
2581 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2628 try wip_nav.abbrevCode(.generated_field);
2582 try wip_nav.strp("has_value");2629 try wip_nav.strp("has_value");
2583 const repr: enum { unpacked, error_set, pointer } = switch (opt_child_type_index) {2630 const repr: enum { unpacked, error_set, pointer } = switch (opt_child_type_index) {
2584 .anyerror_type => .error_set,2631 .anyerror_type => .error_set,
...@@ -2609,19 +2656,19 @@ fn updateType(...@@ -2609,19 +2656,19 @@ fn updateType(
2609 },2656 },
2610 }2657 }
26112658
2612 try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_tagged_union_field));2659 try wip_nav.abbrevCode(.unsigned_tagged_union_field);
2613 try uleb128(diw, 0);2660 try uleb128(diw, 0);
2614 {2661 {
2615 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2662 try wip_nav.abbrevCode(.generated_field);
2616 try wip_nav.strp("null");2663 try wip_nav.strp("null");
2617 try wip_nav.refType(Type.null);2664 try wip_nav.refType(Type.null);
2618 try uleb128(diw, 0);2665 try uleb128(diw, 0);
2619 }2666 }
2620 try uleb128(diw, @intFromEnum(AbbrevCode.null));2667 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);
2623 {2670 {
2624 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2671 try wip_nav.abbrevCode(.generated_field);
2625 try wip_nav.strp("?");2672 try wip_nav.strp("?");
2626 try wip_nav.refType(opt_child_type);2673 try wip_nav.refType(opt_child_type);
2627 try uleb128(diw, 0);2674 try uleb128(diw, 0);
...@@ -2644,7 +2691,7 @@ fn updateType(...@@ -2644,7 +2691,7 @@ fn updateType(
2644 },2691 },
2645 };2692 };
26462693
2647 try uleb128(diw, @intFromEnum(AbbrevCode.union_type));2694 try wip_nav.abbrevCode(.union_type);
2648 try wip_nav.strp(name);2695 try wip_nav.strp(name);
2649 if (error_union_type.error_set_type != .generic_poison_type and2696 if (error_union_type.error_set_type != .generic_poison_type and
2650 error_union_type.payload_type != .generic_poison_type)2697 error_union_type.payload_type != .generic_poison_type)
...@@ -2656,7 +2703,7 @@ fn updateType(...@@ -2656,7 +2703,7 @@ fn updateType(
2656 try uleb128(diw, 1);2703 try uleb128(diw, 1);
2657 }2704 }
2658 {2705 {
2659 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));2706 try wip_nav.abbrevCode(.tagged_union);
2660 try wip_nav.infoSectionOffset(2707 try wip_nav.infoSectionOffset(
2661 .debug_info,2708 .debug_info,
2662 wip_nav.unit,2709 wip_nav.unit,
...@@ -2664,7 +2711,7 @@ fn updateType(...@@ -2664,7 +2711,7 @@ fn updateType(
2664 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),2711 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
2665 );2712 );
2666 {2713 {
2667 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2714 try wip_nav.abbrevCode(.generated_field);
2668 try wip_nav.strp("is_error");2715 try wip_nav.strp("is_error");
2669 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{2716 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
2670 .signedness = .unsigned,2717 .signedness = .unsigned,
...@@ -2672,19 +2719,19 @@ fn updateType(...@@ -2672,19 +2719,19 @@ fn updateType(
2672 } })));2719 } })));
2673 try uleb128(diw, error_union_error_set_offset);2720 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);
2676 try uleb128(diw, 0);2723 try uleb128(diw, 0);
2677 {2724 {
2678 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2725 try wip_nav.abbrevCode(.generated_field);
2679 try wip_nav.strp("value");2726 try wip_nav.strp("value");
2680 try wip_nav.refType(error_union_payload_type);2727 try wip_nav.refType(error_union_payload_type);
2681 try uleb128(diw, error_union_payload_offset);2728 try uleb128(diw, error_union_payload_offset);
2682 }2729 }
2683 try uleb128(diw, @intFromEnum(AbbrevCode.null));2730 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);
2686 {2733 {
2687 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));2734 try wip_nav.abbrevCode(.generated_field);
2688 try wip_nav.strp("error");2735 try wip_nav.strp("error");
2689 try wip_nav.refType(error_union_error_set_type);2736 try wip_nav.refType(error_union_error_set_type);
2690 try uleb128(diw, error_union_error_set_offset);2737 try uleb128(diw, error_union_error_set_offset);
...@@ -2715,7 +2762,7 @@ fn updateType(...@@ -2715,7 +2762,7 @@ fn updateType(
2715 .c_longdouble,2762 .c_longdouble,
2716 .bool,2763 .bool,
2717 => {2764 => {
2718 try uleb128(diw, @intFromEnum(AbbrevCode.numeric_type));2765 try wip_nav.abbrevCode(.numeric_type);
2719 try wip_nav.strp(name);2766 try wip_nav.strp(name);
2720 try diw.writeByte(if (type_index == .bool_type)2767 try diw.writeByte(if (type_index == .bool_type)
2721 DW.ATE.boolean2768 DW.ATE.boolean
...@@ -2742,7 +2789,7 @@ fn updateType(...@@ -2742,7 +2789,7 @@ fn updateType(
2742 .enum_literal,2789 .enum_literal,
2743 .generic_poison,2790 .generic_poison,
2744 => {2791 => {
2745 try uleb128(diw, @intFromEnum(AbbrevCode.void_type));2792 try wip_nav.abbrevCode(.void_type);
2746 try wip_nav.strp(if (type_index == .generic_poison_type) "anytype" else name);2793 try wip_nav.strp(if (type_index == .generic_poison_type) "anytype" else name);
2747 },2794 },
2748 .anyerror => return, // delay until flush2795 .anyerror => return, // delay until flush
...@@ -2752,15 +2799,19 @@ fn updateType(...@@ -2752,15 +2799,19 @@ fn updateType(
2752 .union_type,2799 .union_type,
2753 .opaque_type,2800 .opaque_type,
2754 => unreachable,2801 => unreachable,
2755 .anon_struct_type => |anon_struct_type| {2802 .anon_struct_type => |anon_struct_type| if (anon_struct_type.types.len == 0) {
2756 try uleb128(diw, @intFromEnum(AbbrevCode.struct_type));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);
2757 try wip_nav.strp(name);2808 try wip_nav.strp(name);
2758 try uleb128(diw, ty.abiSize(pt));2809 try uleb128(diw, ty.abiSize(pt));
2759 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);2810 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2760 var field_byte_offset: u64 = 0;2811 var field_byte_offset: u64 = 0;
2761 for (0..anon_struct_type.types.len) |field_index| {2812 for (0..anon_struct_type.types.len) |field_index| {
2762 const comptime_value = anon_struct_type.values.get(ip)[field_index];2813 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);
2764 if (anon_struct_type.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {2815 if (anon_struct_type.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
2765 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});2816 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
2766 defer dwarf.gpa.free(field_name);2817 defer dwarf.gpa.free(field_name);
...@@ -2780,7 +2831,7 @@ fn updateType(...@@ -2780,7 +2831,7 @@ fn updateType(
2780 },2831 },
2781 .enum_type => {2832 .enum_type => {
2782 const loaded_enum = ip.loadEnumType(type_index);2833 const loaded_enum = ip.loadEnumType(type_index);
2783 try uleb128(diw, @intFromEnum(AbbrevCode.enum_type));2834 try wip_nav.abbrevCode(.enum_type);
2784 try wip_nav.strp(name);2835 try wip_nav.strp(name);
2785 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));2836 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
2786 for (0..loaded_enum.names.len) |field_index| {2837 for (0..loaded_enum.names.len) |field_index| {
...@@ -2794,7 +2845,7 @@ fn updateType(...@@ -2794,7 +2845,7 @@ fn updateType(
2794 },2845 },
2795 .func_type => |func_type| {2846 .func_type => |func_type| {
2796 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;2847 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);
2798 try wip_nav.strp(name);2849 try wip_nav.strp(name);
2799 try diw.writeByte(@intFromEnum(@as(DW.CC, switch (func_type.cc) {2850 try diw.writeByte(@intFromEnum(@as(DW.CC, switch (func_type.cc) {
2800 .Unspecified, .C => .normal,2851 .Unspecified, .C => .normal,
...@@ -2814,15 +2865,15 @@ fn updateType(...@@ -2814,15 +2865,15 @@ fn updateType(
2814 try wip_nav.refType(Type.fromInterned(func_type.return_type));2865 try wip_nav.refType(Type.fromInterned(func_type.return_type));
2815 if (!is_nullary) {2866 if (!is_nullary) {
2816 for (0..func_type.param_types.len) |param_index| {2867 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);
2818 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));2869 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
2819 }2870 }
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);
2821 try uleb128(diw, @intFromEnum(AbbrevCode.null));2872 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2822 }2873 }
2823 },2874 },
2824 .error_set_type => |error_set_type| {2875 .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);
2826 try wip_nav.strp(name);2877 try wip_nav.strp(name);
2827 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{2878 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
2828 .signedness = .unsigned,2879 .signedness = .unsigned,
...@@ -2830,7 +2881,7 @@ fn updateType(...@@ -2830,7 +2881,7 @@ fn updateType(
2830 } })));2881 } })));
2831 for (0..error_set_type.names.len) |field_index| {2882 for (0..error_set_type.names.len) |field_index| {
2832 const field_name = error_set_type.names.get(ip)[field_index];2883 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);
2834 try uleb128(diw, ip.getErrorValueIfExists(field_name).?);2885 try uleb128(diw, ip.getErrorValueIfExists(field_name).?);
2835 try wip_nav.strp(field_name.toSlice(ip));2886 try wip_nav.strp(field_name.toSlice(ip));
2836 }2887 }
...@@ -2838,11 +2889,11 @@ fn updateType(...@@ -2838,11 +2889,11 @@ fn updateType(
2838 },2889 },
2839 .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) {2890 .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) {
2840 .none => {2891 .none => {
2841 try uleb128(diw, @intFromEnum(AbbrevCode.void_type));2892 try wip_nav.abbrevCode(.void_type);
2842 try wip_nav.strp(name);2893 try wip_nav.strp(name);
2843 },2894 },
2844 else => |ies| {2895 else => |ies| {
2845 try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type));2896 try wip_nav.abbrevCode(.inferred_error_set_type);
2846 try wip_nav.strp(name);2897 try wip_nav.strp(name);
2847 try wip_nav.refType(Type.fromInterned(ies));2898 try wip_nav.refType(Type.fromInterned(ies));
2848 },2899 },
...@@ -2894,7 +2945,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2894,7 +2945,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2894 .func = .none,2945 .func = .none,
2895 .func_sym_index = undefined,2946 .func_sym_index = undefined,
2896 .func_high_reloc = undefined,2947 .func_high_reloc = undefined,
2897 .inlined_funcs_high_reloc = undefined,2948 .inlined_funcs = undefined,
2898 .debug_info = .{},2949 .debug_info = .{},
2899 .debug_line = .{},2950 .debug_line = .{},
2900 .debug_loclists = .{},2951 .debug_loclists = .{},
...@@ -2905,7 +2956,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2905,7 +2956,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2905 const loaded_struct = ip.loadStructType(type_index);2956 const loaded_struct = ip.loadStructType(type_index);
29062957
2907 const diw = wip_nav.debug_info.writer(dwarf.gpa);2958 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);
2909 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);2960 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
2910 try uleb128(diw, file_gop.index);2961 try uleb128(diw, file_gop.index);
2911 try wip_nav.strp(loaded_struct.name.toSlice(ip));2962 try wip_nav.strp(loaded_struct.name.toSlice(ip));
...@@ -2914,7 +2965,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2914,7 +2965,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2914 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);2965 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2915 for (0..loaded_struct.field_types.len) |field_index| {2966 for (0..loaded_struct.field_types.len) |field_index| {
2916 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);2967 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);
2918 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {2969 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
2919 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});2970 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
2920 defer dwarf.gpa.free(field_name);2971 defer dwarf.gpa.free(field_name);
...@@ -2957,7 +3008,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2957,7 +3008,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2957 .func = .none,3008 .func = .none,
2958 .func_sym_index = undefined,3009 .func_sym_index = undefined,
2959 .func_high_reloc = undefined,3010 .func_high_reloc = undefined,
2960 .inlined_funcs_high_reloc = undefined,3011 .inlined_funcs = undefined,
2961 .debug_info = .{},3012 .debug_info = .{},
2962 .debug_line = .{},3013 .debug_line = .{},
2963 .debug_loclists = .{},3014 .debug_loclists = .{},
...@@ -2973,17 +3024,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2973,17 +3024,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2973 const loaded_struct = ip.loadStructType(type_index);3024 const loaded_struct = ip.loadStructType(type_index);
2974 switch (loaded_struct.layout) {3025 switch (loaded_struct.layout) {
2975 .auto, .@"extern" => {3026 .auto, .@"extern" => {
2976 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0)3027 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_struct_type else .struct_type);
2977 .namespace_struct_type
2978 else
2979 .struct_type)));
2980 try wip_nav.strp(name);3028 try wip_nav.strp(name);
2981 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {3029 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
2982 try uleb128(diw, ty.abiSize(pt));3030 try uleb128(diw, ty.abiSize(pt));
2983 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);3031 try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
2984 for (0..loaded_struct.field_types.len) |field_index| {3032 for (0..loaded_struct.field_types.len) |field_index| {
2985 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);3033 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);
2987 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {3035 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
2988 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});3036 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
2989 defer dwarf.gpa.free(field_name);3037 defer dwarf.gpa.free(field_name);
...@@ -3001,12 +3049,12 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3001,12 +3049,12 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3001 }3049 }
3002 },3050 },
3003 .@"packed" => {3051 .@"packed" => {
3004 try uleb128(diw, @intFromEnum(AbbrevCode.packed_struct_type));3052 try wip_nav.abbrevCode(.packed_struct_type);
3005 try wip_nav.strp(name);3053 try wip_nav.strp(name);
3006 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));3054 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
3007 var field_bit_offset: u16 = 0;3055 var field_bit_offset: u16 = 0;
3008 for (0..loaded_struct.field_types.len) |field_index| {3056 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);
3010 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));3058 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
3011 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);3059 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
3012 try wip_nav.refType(field_type);3060 try wip_nav.refType(field_type);
...@@ -3019,7 +3067,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3019,7 +3067,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3019 },3067 },
3020 .enum_type => {3068 .enum_type => {
3021 const loaded_enum = ip.loadEnumType(type_index);3069 const loaded_enum = ip.loadEnumType(type_index);
3022 try uleb128(diw, @intFromEnum(AbbrevCode.enum_type));3070 try wip_nav.abbrevCode(.enum_type);
3023 try wip_nav.strp(name);3071 try wip_nav.strp(name);
3024 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));3072 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
3025 for (0..loaded_enum.names.len) |field_index| {3073 for (0..loaded_enum.names.len) |field_index| {
...@@ -3033,14 +3081,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3033,14 +3081,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3033 },3081 },
3034 .union_type => {3082 .union_type => {
3035 const loaded_union = ip.loadUnionType(type_index);3083 const loaded_union = ip.loadUnionType(type_index);
3036 try uleb128(diw, @intFromEnum(AbbrevCode.union_type));3084 try wip_nav.abbrevCode(.union_type);
3037 try wip_nav.strp(name);3085 try wip_nav.strp(name);
3038 const union_layout = pt.getUnionLayout(loaded_union);3086 const union_layout = pt.getUnionLayout(loaded_union);
3039 try uleb128(diw, union_layout.abi_size);3087 try uleb128(diw, union_layout.abi_size);
3040 try uleb128(diw, union_layout.abi_align.toByteUnits().?);3088 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
3041 const loaded_tag = loaded_union.loadTagType(ip);3089 const loaded_tag = loaded_union.loadTagType(ip);
3042 if (loaded_union.hasTag(ip)) {3090 if (loaded_union.hasTag(ip)) {
3043 try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));3091 try wip_nav.abbrevCode(.tagged_union);
3044 try wip_nav.infoSectionOffset(3092 try wip_nav.infoSectionOffset(
3045 .debug_info,3093 .debug_info,
3046 wip_nav.unit,3094 wip_nav.unit,
...@@ -3048,7 +3096,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3048,7 +3096,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3048 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),3096 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
3049 );3097 );
3050 {3098 {
3051 try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));3099 try wip_nav.abbrevCode(.generated_field);
3052 try wip_nav.strp("tag");3100 try wip_nav.strp("tag");
3053 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));3101 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
3054 try uleb128(diw, union_layout.tagOffset());3102 try uleb128(diw, union_layout.tagOffset());
...@@ -3059,7 +3107,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3059,7 +3107,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3059 .unsigned = .unsigned_tagged_union_field,3107 .unsigned = .unsigned_tagged_union_field,
3060 }, field_index);3108 }, field_index);
3061 {3109 {
3062 try uleb128(diw, @intFromEnum(AbbrevCode.struct_field));3110 try wip_nav.abbrevCode(.struct_field);
3063 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));3111 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
3064 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);3112 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
3065 try wip_nav.refType(field_type);3113 try wip_nav.refType(field_type);
...@@ -3075,7 +3123,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3075,7 +3123,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3075 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)3123 if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
3076 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);3124 try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
3077 } else for (0..loaded_union.field_types.len) |field_index| {3125 } 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);
3079 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));3127 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
3080 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);3128 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
3081 try wip_nav.refType(field_type);3129 try wip_nav.refType(field_type);
...@@ -3085,7 +3133,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3085,7 +3133,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3085 try uleb128(diw, @intFromEnum(AbbrevCode.null));3133 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3086 },3134 },
3087 .opaque_type => {3135 .opaque_type => {
3088 try uleb128(diw, @intFromEnum(AbbrevCode.namespace_struct_type));3136 try wip_nav.abbrevCode(.namespace_struct_type);
3089 try wip_nav.strp(name);3137 try wip_nav.strp(name);
3090 try diw.writeByte(@intFromBool(true));3138 try diw.writeByte(@intFromBool(true));
3091 },3139 },
...@@ -3121,6 +3169,23 @@ pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {...@@ -3121,6 +3169,23 @@ pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {
3121 _ = nav_index;3169 _ = nav_index;
3122}3170}
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
3124pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {3189pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3125 const ip = &pt.zcu.intern_pool;3190 const ip = &pt.zcu.intern_pool;
3126 if (dwarf.types.get(.anyerror_type)) |entry| {3191 if (dwarf.types.get(.anyerror_type)) |entry| {
...@@ -3133,7 +3198,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3133,7 +3198,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3133 .func = .none,3198 .func = .none,
3134 .func_sym_index = undefined,3199 .func_sym_index = undefined,
3135 .func_high_reloc = undefined,3200 .func_high_reloc = undefined,
3136 .inlined_funcs_high_reloc = undefined,3201 .inlined_funcs = undefined,
3137 .debug_info = .{},3202 .debug_info = .{},
3138 .debug_line = .{},3203 .debug_line = .{},
3139 .debug_loclists = .{},3204 .debug_loclists = .{},
...@@ -3142,14 +3207,14 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3142,14 +3207,14 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3142 defer wip_nav.deinit();3207 defer wip_nav.deinit();
3143 const diw = wip_nav.debug_info.writer(dwarf.gpa);3208 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3144 const global_error_set_names = ip.global_error_set.getNamesFromMainThread();3209 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);
3146 try wip_nav.strp("anyerror");3211 try wip_nav.strp("anyerror");
3147 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{3212 try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
3148 .signedness = .unsigned,3213 .signedness = .unsigned,
3149 .bits = pt.zcu.errorSetBits(),3214 .bits = pt.zcu.errorSetBits(),
3150 } })));3215 } })));
3151 for (global_error_set_names, 1..) |name, value| {3216 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);
3153 try uleb128(diw, value);3218 try uleb128(diw, value);
3154 try wip_nav.strp(name.toSlice(ip));3219 try wip_nav.strp(name.toSlice(ip));
3155 }3220 }
...@@ -3173,21 +3238,6 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3173,21 +3238,6 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
31733238
3174 var header = std.ArrayList(u8).init(dwarf.gpa);3239 var header = std.ArrayList(u8).init(dwarf.gpa);
3175 defer header.deinit();3240 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 }
3191 if (dwarf.debug_aranges.section.dirty) {3241 if (dwarf.debug_aranges.section.dirty) {
3192 for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {3242 for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
3193 const unit: Unit.Index = @enumFromInt(unit_index);3243 const unit: Unit.Index = @enumFromInt(unit_index);
...@@ -3245,11 +3295,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3245,11 +3295,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3245 .source_off = @intCast(header.items.len),3295 .source_off = @intCast(header.items.len),
3246 .target_sec = .debug_abbrev,3296 .target_sec = .debug_abbrev,
3247 .target_unit = DebugAbbrev.unit,3297 .target_unit = DebugAbbrev.unit,
3248 .target_entry = DebugAbbrev.entry.toOptional(),
3249 });3298 });
3250 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());3299 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
3251 const compile_unit_off: u32 = @intCast(header.items.len);3300 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;
3253 header.appendAssumeCapacity(DW.LANG.Zig);3302 header.appendAssumeCapacity(DW.LANG.Zig);
3254 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{3303 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
3255 .source_off = @intCast(header.items.len),3304 .source_off = @intCast(header.items.len),
...@@ -3292,7 +3341,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3292,7 +3341,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3292 });3341 });
3293 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());3342 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
3294 uleb128(header.fixedWriter(), 0) catch unreachable;3343 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;
3296 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{3345 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
3297 .source_off = @intCast(header.items.len),3346 .source_off = @intCast(header.items.len),
3298 .target_sec = .debug_str,3347 .target_sec = .debug_str,
...@@ -3306,6 +3355,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3306,6 +3355,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3306 }3355 }
3307 dwarf.debug_info.section.dirty = false;3356 dwarf.debug_info.section.dirty = false;
3308 }3357 }
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 }
3309 if (dwarf.debug_str.section.dirty) {3363 if (dwarf.debug_str.section.dirty) {
3310 const contents = dwarf.debug_str.contents.items;3364 const contents = dwarf.debug_str.contents.items;
3311 try dwarf.debug_str.section.resize(dwarf, contents.len);3365 try dwarf.debug_str.section.resize(dwarf, contents.len);
...@@ -3313,8 +3367,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3313,8 +3367,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3313 dwarf.debug_str.section.dirty = false;3367 dwarf.debug_str.section.dirty = false;
3314 }3368 }
3315 if (dwarf.debug_line.section.dirty) {3369 if (dwarf.debug_line.section.dirty) {
3316 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit|3370 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| try unit.resizeHeader(
3317 try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())));3371 &dwarf.debug_line.section,
3372 dwarf,
3373 DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())),
3374 );
3318 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {3375 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
3319 unit.clear();3376 unit.clear();
3320 try unit.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 2 * (1 + mod_info.files.count()));3377 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 {...@@ -3333,14 +3390,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3333 }3390 }
3334 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);3391 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);
3335 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });3392 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
3336 switch (dwarf.format) {3393 dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), unit.header_len - header.items.len);
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 }
3344 const StandardOpcode = DeclValEnum(DW.LNS);3394 const StandardOpcode = DeclValEnum(DW.LNS);
3345 header.appendSliceAssumeCapacity(&[_]u8{3395 header.appendSliceAssumeCapacity(&[_]u8{
3346 dwarf.debug_line.header.minimum_instruction_length,3396 dwarf.debug_line.header.minimum_instruction_length,
...@@ -3422,6 +3472,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3422,6 +3472,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3422 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off);3472 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off);
3423 dwarf.debug_line_str.section.dirty = false;3473 dwarf.debug_line_str.section.dirty = false;
3424 }3474 }
3475 if (dwarf.debug_loclists.section.dirty) {
3476 dwarf.debug_loclists.section.dirty = false;
3477 }
3425 if (dwarf.debug_rnglists.section.dirty) {3478 if (dwarf.debug_rnglists.section.dirty) {
3426 for (dwarf.debug_rnglists.section.units.items) |*unit| {3479 for (dwarf.debug_rnglists.section.units.items) |*unit| {
3427 header.clearRetainingCapacity();3480 header.clearRetainingCapacity();
...@@ -3440,19 +3493,20 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -3440,19 +3493,20 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3440 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);3493 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);
3441 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });3494 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
3442 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(@sizeOf(u32)), 1, dwarf.endian);3495 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(@sizeOf(u32)), 1, dwarf.endian);
3443 switch (dwarf.format) {3496 dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), dwarf.sectionOffsetBytes() * 1);
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 }
3451 try unit.replaceHeader(&dwarf.debug_rnglists.section, dwarf, header.items);3497 try unit.replaceHeader(&dwarf.debug_rnglists.section, dwarf, header.items);
3452 try unit.writeTrailer(&dwarf.debug_rnglists.section, dwarf);3498 try unit.writeTrailer(&dwarf.debug_rnglists.section, dwarf);
3453 }3499 }
3454 dwarf.debug_rnglists.section.dirty = false;3500 dwarf.debug_rnglists.section.dirty = false;
3455 }3501 }
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);
3456}3510}
34573511
3458pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void {3512pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void {
...@@ -3491,7 +3545,7 @@ fn DeclValEnum(comptime T: type) type {...@@ -3491,7 +3545,7 @@ fn DeclValEnum(comptime T: type) type {
3491 } });3545 } });
3492}3546}
34933547
3494const AbbrevCode = enum(u8) {3548const AbbrevCode = enum {
3495 null,3549 null,
3496 // padding codes must be one byte uleb128 values to function3550 // padding codes must be one byte uleb128 values to function
3497 pad_1,3551 pad_1,
...@@ -3499,15 +3553,16 @@ const AbbrevCode = enum(u8) {...@@ -3499,15 +3553,16 @@ const AbbrevCode = enum(u8) {
3499 // decl codes are assumed to all have the same uleb128 length3553 // decl codes are assumed to all have the same uleb128 length
3500 decl_alias,3554 decl_alias,
3501 decl_enum,3555 decl_enum,
3556 decl_empty_enum,
3502 decl_namespace_struct,3557 decl_namespace_struct,
3503 decl_struct,3558 decl_struct,
3504 decl_packed_struct,3559 decl_packed_struct,
3505 decl_union,3560 decl_union,
3506 decl_var,3561 decl_var,
3507 decl_func,3562 decl_func,
3508 decl_func_empty,3563 decl_empty_func,
3509 decl_func_generic,3564 decl_func_generic,
3510 decl_func_generic_empty,3565 decl_empty_func_generic,
3511 // the rest are unrestricted3566 // the rest are unrestricted
3512 compile_unit,3567 compile_unit,
3513 module,3568 module,
...@@ -3542,11 +3597,12 @@ const AbbrevCode = enum(u8) {...@@ -3542,11 +3597,12 @@ const AbbrevCode = enum(u8) {
3542 struct_type,3597 struct_type,
3543 packed_struct_type,3598 packed_struct_type,
3544 union_type,3599 union_type,
3600 empty_inlined_func,
3545 inlined_func,3601 inlined_func,
3546 local_arg,3602 local_arg,
3547 local_var,3603 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
3551 const Attr = struct {3607 const Attr = struct {
3552 DeclValEnum(DW.AT),3608 DeclValEnum(DW.AT),
...@@ -3586,6 +3642,12 @@ const AbbrevCode = enum(u8) {...@@ -3586,6 +3642,12 @@ const AbbrevCode = enum(u8) {
3586 .{ .type, .ref_addr },3642 .{ .type, .ref_addr },
3587 },3643 },
3588 },3644 },
3645 .decl_empty_enum = .{
3646 .tag = .enumeration_type,
3647 .attrs = decl_abbrev_common_attrs ++ .{
3648 .{ .type, .ref_addr },
3649 },
3650 },
3589 .decl_namespace_struct = .{3651 .decl_namespace_struct = .{
3590 .tag = .structure_type,3652 .tag = .structure_type,
3591 .attrs = decl_abbrev_common_attrs ++ .{3653 .attrs = decl_abbrev_common_attrs ++ .{
...@@ -3638,7 +3700,7 @@ const AbbrevCode = enum(u8) {...@@ -3638,7 +3700,7 @@ const AbbrevCode = enum(u8) {
3638 .{ .noreturn, .flag },3700 .{ .noreturn, .flag },
3639 },3701 },
3640 },3702 },
3641 .decl_func_empty = .{3703 .decl_empty_func = .{
3642 .tag = .subprogram,3704 .tag = .subprogram,
3643 .attrs = decl_abbrev_common_attrs ++ .{3705 .attrs = decl_abbrev_common_attrs ++ .{
3644 .{ .linkage_name, .strp },3706 .{ .linkage_name, .strp },
...@@ -3657,7 +3719,7 @@ const AbbrevCode = enum(u8) {...@@ -3657,7 +3719,7 @@ const AbbrevCode = enum(u8) {
3657 .{ .type, .ref_addr },3719 .{ .type, .ref_addr },
3658 },3720 },
3659 },3721 },
3660 .decl_func_generic_empty = .{3722 .decl_empty_func_generic = .{
3661 .tag = .subprogram,3723 .tag = .subprogram,
3662 .attrs = decl_abbrev_common_attrs ++ .{3724 .attrs = decl_abbrev_common_attrs ++ .{
3663 .{ .type, .ref_addr },3725 .{ .type, .ref_addr },
...@@ -3918,6 +3980,16 @@ const AbbrevCode = enum(u8) {...@@ -3918,6 +3980,16 @@ const AbbrevCode = enum(u8) {
3918 .{ .alignment, .udata },3980 .{ .alignment, .udata },
3919 },3981 },
3920 },3982 },
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 },
3921 .inlined_func = .{3993 .inlined_func = .{
3922 .tag = .inlined_subroutine,3994 .tag = .inlined_subroutine,
3923 .children = true,3995 .children = true,
...@@ -3946,7 +4018,7 @@ const AbbrevCode = enum(u8) {...@@ -3946,7 +4018,7 @@ const AbbrevCode = enum(u8) {
3946 },4018 },
3947 },4019 },
3948 .null = undefined,4020 .null = undefined,
3949 }).values[1..].*;4021 });
3950};4022};
39514023
3952fn getFile(dwarf: *Dwarf) ?std.fs.File {4024fn getFile(dwarf: *Dwarf) ?std.fs.File {
...@@ -3955,11 +4027,11 @@ fn getFile(dwarf: *Dwarf) ?std.fs.File {...@@ -3955,11 +4027,11 @@ fn getFile(dwarf: *Dwarf) ?std.fs.File {
3955}4027}
39564028
3957fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {4029fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {
3958 const entry = try dwarf.debug_aranges.section.addEntry(unit, dwarf);4030 const entry = try dwarf.debug_aranges.section.getUnit(unit).addEntry(dwarf.gpa);
3959 assert(try dwarf.debug_info.section.addEntry(unit, dwarf) == entry);4031 assert(try dwarf.debug_info.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
3960 assert(try dwarf.debug_line.section.addEntry(unit, dwarf) == entry);4032 assert(try dwarf.debug_line.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
3961 assert(try dwarf.debug_loclists.section.addEntry(unit, dwarf) == entry);4033 assert(try dwarf.debug_loclists.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
3962 assert(try dwarf.debug_rnglists.section.addEntry(unit, dwarf) == entry);4034 assert(try dwarf.debug_rnglists.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
3963 return entry;4035 return entry;
3964}4036}
39654037
...@@ -3993,13 +4065,6 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 {...@@ -3993,13 +4065,6 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 {
3993 };4065 };
3994}4066}
39954067
3996fn SectionOffset(comptime format: DW.Format) type {
3997 return switch (format) {
3998 .@"32" => u32,
3999 .@"64" => u64,
4000 };
4001}
4002
4003fn uleb128Bytes(value: anytype) u32 {4068fn uleb128Bytes(value: anytype) u32 {
4004 var cw = std.io.countingWriter(std.io.null_writer);4069 var cw = std.io.countingWriter(std.io.null_writer);
4005 try uleb128(cw.writer(), value);4070 try uleb128(cw.writer(), value);