Commit 31220b50b5
lib/std/dwarf.zig
@@ -89,6 +89,7 @@ pub const LNS = struct {
};
pub const LNE = struct {
+ pub const padding = 0x00;
pub const end_sequence = 0x01;
pub const set_address = 0x02;
pub const define_file = 0x03;
src/link/Dwarf.zig
@@ -55,7 +55,10 @@ const ModInfo = struct {
const DebugAbbrev = struct {
section: Section,
const unit: Unit.Index = @enumFromInt(0);
- const entry: Entry.Index = @enumFromInt(0);
+
+ const header_bytes = 0;
+
+ const trailer_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.null));
};
const DebugAranges = struct {
@@ -119,8 +122,7 @@ const DebugLine = struct {
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;
}
- const trailer_bytes = 1 + uleb128Bytes(0) +
- 1 + uleb128Bytes(1) + 1;
+ const trailer_bytes = 1 + uleb128Bytes(1) + 1;
};
const DebugLocLists = struct {
@@ -173,10 +175,15 @@ const StringSection = struct {
errdefer _ = str_sec.map.pop();
const entry: Entry.Index = @enumFromInt(gop.index);
if (!gop.found_existing) {
- assert(try str_sec.section.addEntry(unit, dwarf) == entry);
- errdefer _ = str_sec.section.getUnit(unit).entries.pop();
- const entry_ptr = str_sec.section.getUnit(unit).getEntry(entry);
- assert(entry_ptr.off == str_sec.contents.items.len);
+ const unit_ptr = str_sec.section.getUnit(unit);
+ assert(try str_sec.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
+ errdefer _ = unit_ptr.entries.pop();
+ const entry_ptr = unit_ptr.getEntry(entry);
+ if (unit_ptr.last.unwrap()) |last_entry|
+ unit_ptr.getEntry(last_entry).next = entry.toOptional();
+ entry_ptr.prev = unit_ptr.last;
+ unit_ptr.last = entry.toOptional();
+ entry_ptr.off = @intCast(str_sec.contents.items.len);
entry_ptr.len = @intCast(str.len + 1);
try str_sec.contents.ensureUnusedCapacity(dwarf.gpa, str.len + 1);
str_sec.contents.appendSliceAssumeCapacity(str);
@@ -243,7 +250,7 @@ pub const Section = struct {
fn addUnit(sec: *Section, header_len: u32, trailer_len: u32, dwarf: *Dwarf) UpdateError!Unit.Index {
const unit: Unit.Index = @enumFromInt(sec.units.items.len);
const unit_ptr = try sec.units.addOne(dwarf.gpa);
- errdefer sec.popUnit();
+ errdefer sec.popUnit(dwarf.gpa);
unit_ptr.* = .{
.prev = sec.last,
.next = .none,
@@ -277,14 +284,11 @@ pub const Section = struct {
if (sec.last.unwrap().? == unit) sec.last = unit_ptr.prev;
}
- fn popUnit(sec: *Section) void {
- const unit: Unit.Index = @enumFromInt(sec.units.items.len - 1);
- sec.unlinkUnit(unit);
- _ = sec.units.pop();
- }
-
- fn addEntry(sec: *Section, unit: Unit.Index, dwarf: *Dwarf) UpdateError!Entry.Index {
- return sec.getUnit(unit).addEntry(sec, dwarf);
+ fn popUnit(sec: *Section, gpa: std.mem.Allocator) void {
+ const unit_index: Unit.Index = @enumFromInt(sec.units.items.len - 1);
+ sec.unlinkUnit(unit_index);
+ var unit = sec.units.pop();
+ unit.deinit(gpa);
}
pub fn getUnit(sec: *Section, unit: Unit.Index) *Unit {
@@ -293,7 +297,21 @@ pub const Section = struct {
fn replaceEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
const unit_ptr = sec.getUnit(unit);
- try unit_ptr.getEntry(entry).replace(unit_ptr, sec, dwarf, contents);
+ const entry_ptr = unit_ptr.getEntry(entry);
+ if (contents.len > 0) {
+ if (entry_ptr.len == 0) {
+ assert(entry_ptr.prev == .none and entry_ptr.next == .none);
+ entry_ptr.off = if (unit_ptr.last.unwrap()) |last_entry| off: {
+ const last_entry_ptr = unit_ptr.getEntry(last_entry);
+ last_entry_ptr.next = entry.toOptional();
+ break :off last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
+ } else 0;
+ entry_ptr.prev = unit_ptr.last;
+ unit_ptr.last = entry.toOptional();
+ }
+ try entry_ptr.replace(unit_ptr, sec, dwarf, contents);
+ }
+ assert(entry_ptr.len == contents.len);
}
fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
@@ -391,11 +409,11 @@ const Unit = struct {
unit.* = undefined;
}
- fn addEntry(unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!Entry.Index {
+ fn addEntry(unit: *Unit, gpa: std.mem.Allocator) std.mem.Allocator.Error!Entry.Index {
const entry: Entry.Index = @enumFromInt(unit.entries.items.len);
- const entry_ptr = try unit.entries.addOne(dwarf.gpa);
+ const entry_ptr = try unit.entries.addOne(gpa);
entry_ptr.* = .{
- .prev = unit.last,
+ .prev = .none,
.next = .none,
.off = 0,
.len = 0,
@@ -404,14 +422,6 @@ const Unit = struct {
.cross_section_relocs = .{},
.external_relocs = .{},
};
- if (unit.last.unwrap()) |last_entry| {
- const last_entry_ptr = unit.getEntry(last_entry);
- last_entry_ptr.next = entry.toOptional();
- entry_ptr.off = last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
- }
- if (unit.first == .none)
- unit.first = entry.toOptional();
- unit.last = entry.toOptional();
return entry;
}
@@ -509,42 +519,52 @@ const Unit = struct {
const last_entry_ptr = unit.getEntry(last_entry);
break :end last_entry_ptr.off + last_entry_ptr.len;
} else 0;
- const end = if (unit.next.unwrap()) |next_unit|
- sec.getUnit(next_unit).off
- else
- sec.len;
- const trailer_len: usize = @intCast(end - start);
- assert(trailer_len >= unit.trailer_len);
- var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, trailer_len);
+ const end = if (unit.next.unwrap()) |next_unit| sec.getUnit(next_unit).off else sec.len;
+ const len: usize = @intCast(end - start);
+ assert(len >= unit.trailer_len);
+ if (sec == &dwarf.debug_line.section) {
+ var buf: [1 + uleb128Bytes(std.math.maxInt(u32)) + 1]u8 = undefined;
+ var fbs = std.io.fixedBufferStream(&buf);
+ const writer = fbs.writer();
+ writer.writeByte(DW.LNS.extended_op) catch unreachable;
+ const extended_op_bytes = fbs.pos;
+ var op_len_bytes: u5 = 1;
+ while (true) switch (std.math.order(len - extended_op_bytes - op_len_bytes, @as(u32, 1) << 7 * op_len_bytes)) {
+ .lt => break uleb128(writer, len - extended_op_bytes - op_len_bytes) catch unreachable,
+ .eq => {
+ // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
+ op_len_bytes += 1;
+ std.leb.writeUnsignedExtended(buf[fbs.pos..][0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
+ fbs.pos += op_len_bytes;
+ break;
+ },
+ .gt => op_len_bytes += 1,
+ };
+ assert(fbs.pos == extended_op_bytes + op_len_bytes);
+ writer.writeByte(DW.LNE.padding) catch unreachable;
+ assert(fbs.pos >= unit.trailer_len and fbs.pos <= len);
+ return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + start);
+ }
+ var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, len);
defer trailer.deinit();
- const fill_byte: u8 = if (sec == &dwarf.debug_aranges.section) fill: {
+ const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: {
+ assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
+ trailer.appendAssumeCapacity(@intFromEnum(AbbrevCode.null));
+ break :fill @intFromEnum(AbbrevCode.null);
+ } else if (sec == &dwarf.debug_aranges.section) fill: {
trailer.appendNTimesAssumeCapacity(0, @intFromEnum(dwarf.address_size) * 2);
break :fill 0;
} else if (sec == &dwarf.debug_info.section) fill: {
assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
trailer.appendNTimesAssumeCapacity(@intFromEnum(AbbrevCode.null), 2);
break :fill @intFromEnum(AbbrevCode.null);
- } else if (sec == &dwarf.debug_line.section) fill: {
- unit.len -= unit.trailer_len;
- const extra_len: u32 = @intCast((trailer_len - DebugLine.trailer_bytes) & 1);
- unit.trailer_len = DebugLine.trailer_bytes + extra_len;
- unit.len += unit.trailer_len;
-
- // prevent end sequence from emitting an invalid file index
- trailer.appendAssumeCapacity(DW.LNS.set_file);
- uleb128(trailer.fixedWriter(), 0) catch unreachable;
-
- trailer.appendAssumeCapacity(DW.LNS.extended_op);
- std.leb.writeUnsignedExtended(trailer.addManyAsSliceAssumeCapacity(uleb128Bytes(1) + extra_len), 1);
- trailer.appendAssumeCapacity(DW.LNE.end_sequence);
- break :fill DW.LNS.extended_op;
} else if (sec == &dwarf.debug_rnglists.section) fill: {
trailer.appendAssumeCapacity(DW.RLE.end_of_list);
break :fill DW.RLE.end_of_list;
} else unreachable;
assert(trailer.items.len == unit.trailer_len);
- trailer.appendNTimesAssumeCapacity(fill_byte, trailer_len - trailer.items.len);
- assert(trailer.items.len == trailer_len);
+ trailer.appendNTimesAssumeCapacity(fill_byte, len - trailer.items.len);
+ assert(trailer.items.len == len);
try dwarf.getFile().?.pwriteAll(trailer.items, sec.off + start);
}
@@ -625,45 +645,62 @@ const Entry = struct {
};
fn pad(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void {
+ assert(entry.len > 0);
const start = entry.off + entry.len;
const len = unit.getEntry(entry.next.unwrap() orelse return).off - start;
- if (sec == &dwarf.debug_info.section) {
- var buf: [
- @max(
- uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)),
- uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) + uleb128Bytes(std.math.maxInt(u32)),
- )
- ]u8 = undefined;
- var fbs = std.io.fixedBufferStream(&buf);
- switch (len) {
- 0 => {},
- 1 => uleb128(fbs.writer(), @intFromEnum(AbbrevCode.pad_1)) catch unreachable,
- else => {
- uleb128(fbs.writer(), @intFromEnum(AbbrevCode.pad_n)) catch unreachable;
- const abbrev_code_bytes = fbs.pos;
- var block_len_bytes: u5 = 1;
- while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {
- .lt => break uleb128(fbs.writer(), len - abbrev_code_bytes - block_len_bytes) catch unreachable,
- .eq => {
- // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
- block_len_bytes += 1;
- std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
- fbs.pos += block_len_bytes;
- break;
- },
- .gt => block_len_bytes += 1,
- };
- assert(fbs.pos == abbrev_code_bytes + block_len_bytes);
- },
- }
- assert(fbs.pos <= len);
- try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start);
- } else if (sec == &dwarf.debug_line.section) {
- const buf = try dwarf.gpa.alloc(u8, len);
- defer dwarf.gpa.free(buf);
- @memset(buf, DW.LNS.const_add_pc);
- try dwarf.getFile().?.pwriteAll(buf, sec.off + unit.off + unit.header_len + start);
+ var buf: [
+ @max(
+ uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)),
+ uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) + uleb128Bytes(std.math.maxInt(u32)),
+ 1 + uleb128Bytes(std.math.maxInt(u32)) + 1,
+ )
+ ]u8 = undefined;
+ var fbs = std.io.fixedBufferStream(&buf);
+ const writer = fbs.writer();
+ if (sec == &dwarf.debug_info.section) switch (len) {
+ 0 => {},
+ 1 => uleb128(writer, try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
+ else => {
+ uleb128(writer, try dwarf.refAbbrevCode(.pad_n)) catch unreachable;
+ const abbrev_code_bytes = fbs.pos;
+ var block_len_bytes: u5 = 1;
+ while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {
+ .lt => break uleb128(writer, len - abbrev_code_bytes - block_len_bytes) catch unreachable,
+ .eq => {
+ // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
+ block_len_bytes += 1;
+ std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
+ fbs.pos += block_len_bytes;
+ break;
+ },
+ .gt => block_len_bytes += 1,
+ };
+ assert(fbs.pos == abbrev_code_bytes + block_len_bytes);
+ },
+ } else if (sec == &dwarf.debug_line.section) switch (len) {
+ 0 => {},
+ 1 => writer.writeByte(DW.LNS.const_add_pc) catch unreachable,
+ else => {
+ writer.writeByte(DW.LNS.extended_op) catch unreachable;
+ const extended_op_bytes = fbs.pos;
+ var op_len_bytes: u5 = 1;
+ while (true) switch (std.math.order(len - extended_op_bytes - op_len_bytes, @as(u32, 1) << 7 * op_len_bytes)) {
+ .lt => break uleb128(writer, len - extended_op_bytes - op_len_bytes) catch unreachable,
+ .eq => {
+ // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
+ op_len_bytes += 1;
+ std.leb.writeUnsignedExtended(buf[fbs.pos..][0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
+ fbs.pos += op_len_bytes;
+ break;
+ },
+ .gt => op_len_bytes += 1,
+ };
+ assert(fbs.pos == extended_op_bytes + op_len_bytes);
+ if (len > 2) writer.writeByte(DW.LNE.padding) catch unreachable;
+ },
} else assert(!sec.pad_to_ideal and len == 0);
+ assert(fbs.pos <= len);
+ try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start);
}
fn replace(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
@@ -691,15 +728,7 @@ const Entry = struct {
try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(contents.len) + unit.trailer_len));
}
entry_ptr.len = @intCast(contents.len);
- {
- var prev_entry_ptr = entry_ptr;
- while (prev_entry_ptr.prev.unwrap()) |prev_entry| {
- prev_entry_ptr = unit.getEntry(prev_entry);
- if (prev_entry_ptr.len == 0) continue;
- try prev_entry_ptr.pad(unit, sec, dwarf);
- break;
- }
- }
+ if (entry_ptr.prev.unwrap()) |prev_entry| try unit.getEntry(prev_entry).pad(unit, sec, dwarf);
try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off + unit.header_len + entry_ptr.off);
try entry_ptr.pad(unit, sec, dwarf);
if (false) {
@@ -1039,7 +1068,10 @@ pub const WipNav = struct {
func: InternPool.Index,
func_sym_index: u32,
func_high_reloc: u32,
- inlined_funcs_high_reloc: std.ArrayListUnmanaged(u32),
+ inlined_funcs: std.ArrayListUnmanaged(struct {
+ abbrev_code: u32,
+ high_reloc: u32,
+ }),
debug_info: std.ArrayListUnmanaged(u8),
debug_line: std.ArrayListUnmanaged(u8),
debug_loclists: std.ArrayListUnmanaged(u8),
@@ -1047,7 +1079,7 @@ pub const WipNav = struct {
pub fn deinit(wip_nav: *WipNav) void {
const gpa = wip_nav.dwarf.gpa;
- if (wip_nav.func != .none) wip_nav.inlined_funcs_high_reloc.deinit(gpa);
+ if (wip_nav.func != .none) wip_nav.inlined_funcs.deinit(gpa);
wip_nav.debug_info.deinit(gpa);
wip_nav.debug_line.deinit(gpa);
wip_nav.debug_loclists.deinit(gpa);
@@ -1066,15 +1098,14 @@ pub const WipNav = struct {
ty: Type,
loc: Loc,
) UpdateError!void {
- wip_nav.any_children = true;
assert(wip_nav.func != .none);
- const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
- try uleb128(diw, @intFromEnum(switch (tag) {
+ try wip_nav.abbrevCode(switch (tag) {
inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),
- }));
+ });
try wip_nav.strp(name);
try wip_nav.refType(ty);
try wip_nav.exprloc(loc);
+ wip_nav.any_children = true;
}
pub fn advancePCAndLine(
@@ -1136,9 +1167,10 @@ pub const WipNav = struct {
const dwarf = wip_nav.dwarf;
const zcu = wip_nav.pt.zcu;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try wip_nav.inlined_funcs_high_reloc.ensureUnusedCapacity(dwarf.gpa, 1);
+ const inlined_func = try wip_nav.inlined_funcs.addOne(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.inlined_func));
+ inlined_func.abbrev_code = @intCast(wip_nav.debug_info.items.len);
+ try wip_nav.abbrevCode(.inlined_func);
try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
try uleb128(diw, column + 1);
@@ -1150,7 +1182,7 @@ pub const WipNav = struct {
.target_off = code_off,
});
try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
- wip_nav.inlined_funcs_high_reloc.appendAssumeCapacity(@intCast(external_relocs.items.len));
+ inlined_func.high_reloc = @intCast(external_relocs.items.len);
external_relocs.appendAssumeCapacity(.{
.source_off = @intCast(wip_nav.debug_info.items.len),
.target_sym = wip_nav.func_sym_index,
@@ -1158,17 +1190,27 @@ pub const WipNav = struct {
});
try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
try wip_nav.setInlineFunc(func);
+ wip_nav.any_children = false;
}
pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {
+ const inlined_func_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.inlined_func));
+ const inlined_func = wip_nav.inlined_funcs.pop();
const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
- external_relocs.items[wip_nav.inlined_funcs_high_reloc.pop()].target_off = code_off;
- try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null));
+ external_relocs.items[inlined_func.high_reloc].target_off = code_off;
+ if (wip_nav.any_children)
+ try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))
+ else
+ std.leb.writeUnsignedFixed(
+ inlined_func_bytes,
+ wip_nav.debug_info.items[inlined_func.abbrev_code..][0..inlined_func_bytes],
+ try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func),
+ );
try wip_nav.setInlineFunc(func);
+ wip_nav.any_children = true;
}
pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {
- wip_nav.any_children = true;
const zcu = wip_nav.pt.zcu;
const dwarf = wip_nav.dwarf;
if (wip_nav.func == func) return;
@@ -1219,6 +1261,10 @@ pub const WipNav = struct {
wip_nav.func = func;
}
+ fn abbrevCode(wip_nav: *WipNav, abbrev_code: AbbrevCode) UpdateError!void {
+ try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), try wip_nav.dwarf.refAbbrevCode(abbrev_code));
+ }
+
fn infoSectionOffset(wip_nav: *WipNav, sec: Section.Index, unit: Unit.Index, entry: Entry.Index, off: u32) UpdateError!void {
const dwarf = wip_nav.dwarf;
const gpa = dwarf.gpa;
@@ -1336,7 +1382,7 @@ pub const WipNav = struct {
loaded_enum: InternPool.LoadedEnumType,
abbrev_code: std.enums.EnumFieldStruct(std.builtin.Signedness, AbbrevCode, null),
field_index: usize,
- ) std.mem.Allocator.Error!void {
+ ) UpdateError!void {
const zcu = wip_nav.pt.zcu;
const ip = &zcu.intern_pool;
const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
@@ -1344,9 +1390,9 @@ pub const WipNav = struct {
.comptime_int_type => .signed,
else => Type.fromInterned(loaded_enum.tag_ty).intInfo(zcu).signedness,
};
- try uleb128(diw, @intFromEnum(switch (signedness) {
+ try wip_nav.abbrevCode(switch (signedness) {
inline .signed, .unsigned => |ct_signedness| @field(abbrev_code, @tagName(ct_signedness)),
- }));
+ });
if (loaded_enum.values.len > 0) switch (ip.indexToKey(loaded_enum.values.get(ip)[field_index]).int.storage) {
.u64 => |value| switch (signedness) {
.signed => try sleb128(diw, value),
@@ -1535,20 +1581,21 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
dwarf.reloadSectionMetadata();
dwarf.debug_abbrev.section.pad_to_ideal = false;
- assert(try dwarf.debug_abbrev.section.addUnit(0, 0, dwarf) == DebugAbbrev.unit);
- errdefer dwarf.debug_abbrev.section.popUnit();
- assert(try dwarf.debug_abbrev.section.addEntry(DebugAbbrev.unit, dwarf) == DebugAbbrev.entry);
+ assert(try dwarf.debug_abbrev.section.addUnit(DebugAbbrev.header_bytes, DebugAbbrev.trailer_bytes, dwarf) == DebugAbbrev.unit);
+ errdefer dwarf.debug_abbrev.section.popUnit(dwarf.gpa);
+ for (std.enums.values(AbbrevCode)) |abbrev_code|
+ assert(@intFromEnum(try dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).addEntry(dwarf.gpa)) == @intFromEnum(abbrev_code));
dwarf.debug_aranges.section.pad_to_ideal = false;
dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);
dwarf.debug_line_str.section.pad_to_ideal = false;
assert(try dwarf.debug_line_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
- errdefer dwarf.debug_line_str.section.popUnit();
+ errdefer dwarf.debug_line_str.section.popUnit(dwarf.gpa);
dwarf.debug_str.section.pad_to_ideal = false;
assert(try dwarf.debug_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
- errdefer dwarf.debug_str.section.popUnit();
+ errdefer dwarf.debug_str.section.popUnit(dwarf.gpa);
dwarf.debug_loclists.section.pad_to_ideal = false;
@@ -1589,31 +1636,31 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
DebugAranges.trailerBytes(dwarf),
dwarf,
) == unit);
- errdefer dwarf.debug_aranges.section.popUnit();
+ errdefer dwarf.debug_aranges.section.popUnit(dwarf.gpa);
assert(try dwarf.debug_info.section.addUnit(
DebugInfo.headerBytes(dwarf),
DebugInfo.trailer_bytes,
dwarf,
) == unit);
- errdefer dwarf.debug_info.section.popUnit();
+ errdefer dwarf.debug_info.section.popUnit(dwarf.gpa);
assert(try dwarf.debug_line.section.addUnit(
DebugLine.headerBytes(dwarf, 5, 25),
DebugLine.trailer_bytes,
dwarf,
) == unit);
- errdefer dwarf.debug_line.section.popUnit();
+ errdefer dwarf.debug_line.section.popUnit(dwarf.gpa);
assert(try dwarf.debug_loclists.section.addUnit(
DebugLocLists.headerBytes(dwarf),
DebugLocLists.trailer_bytes,
dwarf,
) == unit);
- errdefer dwarf.debug_loclists.section.popUnit();
+ errdefer dwarf.debug_loclists.section.popUnit(dwarf.gpa);
assert(try dwarf.debug_rnglists.section.addUnit(
DebugRngLists.headerBytes(dwarf),
DebugRngLists.trailer_bytes,
dwarf,
) == unit);
- errdefer dwarf.debug_rnglists.section.popUnit();
+ errdefer dwarf.debug_rnglists.section.popUnit(dwarf.gpa);
}
return unit;
}
@@ -1658,7 +1705,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
.func = .none,
.func_sym_index = undefined,
.func_high_reloc = undefined,
- .inlined_funcs_high_reloc = undefined,
+ .inlined_funcs = undefined,
.debug_info = .{},
.debug_line = .{},
.debug_loclists = .{},
@@ -1699,7 +1746,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
} else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_var));
+ try wip_nav.abbrevCode(.decl_var);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
ty.abiAlignment(pt).toByteUnits().?);
try diw.writeByte(@intFromBool(false));
wip_nav.finishForward(ty_reloc_index);
- try uleb128(diw, @intFromEnum(AbbrevCode.is_const));
+ try wip_nav.abbrevCode(.is_const);
try wip_nav.refType(ty);
},
.variable => |variable| {
@@ -1749,7 +1796,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
} else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_var));
+ try wip_nav.abbrevCode(.decl_var);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
const func_type = ip.indexToKey(func.ty).func_type;
wip_nav.func = nav_val.toIntern();
wip_nav.func_sym_index = sym_index;
- wip_nav.inlined_funcs_high_reloc = .{};
+ wip_nav.inlined_funcs = .{};
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_func));
+ try wip_nav.abbrevCode(.decl_func);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
@@ -1891,7 +1938,7 @@ pub fn finishWipNav(
} else std.leb.writeUnsignedFixed(
AbbrevCode.decl_bytes,
wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
- @intFromEnum(AbbrevCode.decl_func_empty),
+ try dwarf.refAbbrevCode(.decl_empty_func),
);
var aranges_entry = [1]u8{0} ** (8 + 8);
@@ -1967,7 +2014,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
.func = .none,
.func_sym_index = undefined,
.func_high_reloc = undefined,
- .inlined_funcs_high_reloc = undefined,
+ .inlined_funcs = undefined,
.debug_info = .{},
.debug_line = .{},
.debug_loclists = .{},
@@ -1990,12 +2037,12 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
) != abbrev_code_buf.len) return error.InputOutput;
var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
const abbrev_code: AbbrevCode = @enumFromInt(
- try std.leb.readUleb128(@typeInfo(AbbrevCode).Enum.tag_type, abbrev_code_fbs.reader()),
+ std.leb.readUleb128(@typeInfo(AbbrevCode).Enum.tag_type, abbrev_code_fbs.reader()) catch unreachable,
);
switch (abbrev_code) {
else => unreachable,
- .decl_func, .decl_func_empty => return,
- .decl_func_generic, .decl_func_generic_empty => {},
+ .decl_func, .decl_empty_func => return,
+ .decl_func_generic, .decl_empty_func_generic => {},
}
}
entry_ptr.clear();
@@ -2017,7 +2064,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
const func_type = ip.indexToKey(func.ty).func_type;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- 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)));
+ try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)
+ .decl_func_generic
+ else
+ .decl_empty_func_generic);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
try wip_nav.refType(Type.fromInterned(func_type.return_type));
if (func_type.param_types.len > 0 or func_type.is_var_args) {
for (0..func_type.param_types.len) |param_index| {
- try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
+ try wip_nav.abbrevCode(.func_type_param);
try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
}
- if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
+ if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
try uleb128(diw, @intFromEnum(AbbrevCode.null));
}
},
@@ -2088,10 +2138,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
switch (loaded_struct.layout) {
.auto, .@"extern" => {
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0)
- .decl_namespace_struct
- else
- .decl_struct)));
+ try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
try uleb128(diw, nav_val.toType().abiAlignment(pt).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_comptime) .struct_field_comptime else .struct_field)));
+ try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
defer dwarf.gpa.free(field_name);
@@ -2121,7 +2168,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
}
},
.@"packed" => {
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_packed_struct));
+ try wip_nav.abbrevCode(.decl_packed_struct);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
var field_bit_offset: u16 = 0;
for (0..loaded_struct.field_types.len) |field_index| {
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, .packed_struct_field)));
+ try wip_nav.abbrevCode(.packed_struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
@@ -2150,7 +2197,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
+ try wip_nav.abbrevCode(.decl_alias);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
}
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_enum));
+ try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
}, field_index);
try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
}
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
+ if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
break :done;
}
@@ -2235,7 +2282,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
+ try wip_nav.abbrevCode(.decl_alias);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
}
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_union));
+ try wip_nav.abbrevCode(.decl_union);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
try uleb128(diw, union_layout.abi_align.toByteUnits().?);
const loaded_tag = loaded_union.loadTagType(ip);
if (loaded_union.hasTag(ip)) {
- try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
+ try wip_nav.abbrevCode(.tagged_union);
try wip_nav.infoSectionOffset(
.debug_info,
wip_nav.unit,
@@ -2313,7 +2360,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
@intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("tag");
try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
try uleb128(diw, union_layout.tagOffset());
@@ -2324,7 +2371,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
.unsigned = .unsigned_tagged_union_field,
}, field_index);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.struct_field));
+ try wip_nav.abbrevCode(.struct_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
@@ -2340,7 +2387,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
} else for (0..loaded_union.field_types.len) |field_index| {
- try uleb128(diw, @intFromEnum(AbbrevCode.untagged_union_field));
+ try wip_nav.abbrevCode(.untagged_union_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
@@ -2357,7 +2404,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
+ try wip_nav.abbrevCode(.decl_alias);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
}
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_namespace_struct));
+ try wip_nav.abbrevCode(.decl_namespace_struct);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
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
nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
wip_nav.entry = nav_gop.value_ptr.*;
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(AbbrevCode.decl_alias));
+ try wip_nav.abbrevCode(.decl_alias);
try wip_nav.refType(Type.fromInterned(parent_type));
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
@@ -2473,7 +2520,7 @@ fn updateType(
.func = .none,
.func_sym_index = undefined,
.func_high_reloc = undefined,
- .inlined_funcs_high_reloc = undefined,
+ .inlined_funcs = undefined,
.debug_info = .{},
.debug_line = .{},
.debug_loclists = .{},
@@ -2493,7 +2540,7 @@ fn updateType(
switch (ip.indexToKey(type_index)) {
.int_type => |int_type| {
- try uleb128(diw, @intFromEnum(AbbrevCode.numeric_type));
+ try wip_nav.abbrevCode(.numeric_type);
try wip_nav.strp(name);
try diw.writeByte(switch (int_type.signedness) {
inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
@@ -2505,7 +2552,7 @@ fn updateType(
.ptr_type => |ptr_type| switch (ptr_type.flags.size) {
.One, .Many, .C => {
const ptr_child_type = Type.fromInterned(ptr_type.child);
- try uleb128(diw, @intFromEnum(AbbrevCode.ptr_type));
+ try wip_nav.abbrevCode(.ptr_type);
try wip_nav.strp(name);
try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse
ptr_child_type.abiAlignment(pt).toByteUnits().?);
@@ -2517,7 +2564,7 @@ fn updateType(
@intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
) else try wip_nav.refType(ptr_child_type);
if (ptr_type.flags.is_const) {
- try uleb128(diw, @intFromEnum(AbbrevCode.is_const));
+ try wip_nav.abbrevCode(.is_const);
if (ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
.debug_info,
wip_nav.unit,
@@ -2526,21 +2573,21 @@ fn updateType(
) else try wip_nav.refType(ptr_child_type);
}
if (ptr_type.flags.is_volatile) {
- try uleb128(diw, @intFromEnum(AbbrevCode.is_volatile));
+ try wip_nav.abbrevCode(.is_volatile);
try wip_nav.refType(ptr_child_type);
}
},
.Slice => {
- try uleb128(diw, @intFromEnum(AbbrevCode.struct_type));
+ try wip_nav.abbrevCode(.struct_type);
try wip_nav.strp(name);
try uleb128(diw, ty.abiSize(pt));
try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("ptr");
const ptr_field_type = ty.slicePtrFieldType(zcu);
try wip_nav.refType(ptr_field_type);
try uleb128(diw, 0);
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("len");
const len_field_type = Type.usize;
try wip_nav.refType(len_field_type);
@@ -2549,28 +2596,28 @@ fn updateType(
},
},
inline .array_type, .vector_type => |array_type, ty_tag| {
- try uleb128(diw, @intFromEnum(AbbrevCode.array_type));
+ try wip_nav.abbrevCode(.array_type);
try wip_nav.strp(name);
try wip_nav.refType(Type.fromInterned(array_type.child));
try diw.writeByte(@intFromBool(ty_tag == .vector_type));
- try uleb128(diw, @intFromEnum(AbbrevCode.array_index));
+ try wip_nav.abbrevCode(.array_index);
try wip_nav.refType(Type.usize);
try uleb128(diw, array_type.len);
try uleb128(diw, @intFromEnum(AbbrevCode.null));
},
.opt_type => |opt_child_type_index| {
const opt_child_type = Type.fromInterned(opt_child_type_index);
- try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
+ try wip_nav.abbrevCode(.union_type);
try wip_nav.strp(name);
try uleb128(diw, ty.abiSize(pt));
try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
if (opt_child_type.isNoReturn(zcu)) {
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("null");
try wip_nav.refType(Type.null);
try uleb128(diw, 0);
} else {
- try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
+ try wip_nav.abbrevCode(.tagged_union);
try wip_nav.infoSectionOffset(
.debug_info,
wip_nav.unit,
@@ -2578,7 +2625,7 @@ fn updateType(
@intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("has_value");
const repr: enum { unpacked, error_set, pointer } = switch (opt_child_type_index) {
.anyerror_type => .error_set,
@@ -2609,19 +2656,19 @@ fn updateType(
},
}
- try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_tagged_union_field));
+ try wip_nav.abbrevCode(.unsigned_tagged_union_field);
try uleb128(diw, 0);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("null");
try wip_nav.refType(Type.null);
try uleb128(diw, 0);
}
try uleb128(diw, @intFromEnum(AbbrevCode.null));
- try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union_default_field));
+ try wip_nav.abbrevCode(.tagged_union_default_field);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("?");
try wip_nav.refType(opt_child_type);
try uleb128(diw, 0);
@@ -2644,7 +2691,7 @@ fn updateType(
},
};
- try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
+ try wip_nav.abbrevCode(.union_type);
try wip_nav.strp(name);
if (error_union_type.error_set_type != .generic_poison_type and
error_union_type.payload_type != .generic_poison_type)
@@ -2656,7 +2703,7 @@ fn updateType(
try uleb128(diw, 1);
}
{
- try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
+ try wip_nav.abbrevCode(.tagged_union);
try wip_nav.infoSectionOffset(
.debug_info,
wip_nav.unit,
@@ -2664,7 +2711,7 @@ fn updateType(
@intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("is_error");
try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
.signedness = .unsigned,
@@ -2672,19 +2719,19 @@ fn updateType(
} })));
try uleb128(diw, error_union_error_set_offset);
- try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_tagged_union_field));
+ try wip_nav.abbrevCode(.unsigned_tagged_union_field);
try uleb128(diw, 0);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("value");
try wip_nav.refType(error_union_payload_type);
try uleb128(diw, error_union_payload_offset);
}
try uleb128(diw, @intFromEnum(AbbrevCode.null));
- try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union_default_field));
+ try wip_nav.abbrevCode(.tagged_union_default_field);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("error");
try wip_nav.refType(error_union_error_set_type);
try uleb128(diw, error_union_error_set_offset);
@@ -2715,7 +2762,7 @@ fn updateType(
.c_longdouble,
.bool,
=> {
- try uleb128(diw, @intFromEnum(AbbrevCode.numeric_type));
+ try wip_nav.abbrevCode(.numeric_type);
try wip_nav.strp(name);
try diw.writeByte(if (type_index == .bool_type)
DW.ATE.boolean
@@ -2742,7 +2789,7 @@ fn updateType(
.enum_literal,
.generic_poison,
=> {
- try uleb128(diw, @intFromEnum(AbbrevCode.void_type));
+ try wip_nav.abbrevCode(.void_type);
try wip_nav.strp(if (type_index == .generic_poison_type) "anytype" else name);
},
.anyerror => return, // delay until flush
@@ -2752,15 +2799,19 @@ fn updateType(
.union_type,
.opaque_type,
=> unreachable,
- .anon_struct_type => |anon_struct_type| {
- try uleb128(diw, @intFromEnum(AbbrevCode.struct_type));
+ .anon_struct_type => |anon_struct_type| if (anon_struct_type.types.len == 0) {
+ try wip_nav.abbrevCode(.namespace_struct_type);
+ try wip_nav.strp(name);
+ try diw.writeByte(@intFromBool(false));
+ } else {
+ try wip_nav.abbrevCode(.struct_type);
try wip_nav.strp(name);
try uleb128(diw, ty.abiSize(pt));
try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
var field_byte_offset: u64 = 0;
for (0..anon_struct_type.types.len) |field_index| {
const comptime_value = anon_struct_type.values.get(ip)[field_index];
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (comptime_value != .none) .struct_field_comptime else .struct_field)));
+ try wip_nav.abbrevCode(if (comptime_value != .none) .struct_field_comptime else .struct_field);
if (anon_struct_type.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
defer dwarf.gpa.free(field_name);
@@ -2780,7 +2831,7 @@ fn updateType(
},
.enum_type => {
const loaded_enum = ip.loadEnumType(type_index);
- try uleb128(diw, @intFromEnum(AbbrevCode.enum_type));
+ try wip_nav.abbrevCode(.enum_type);
try wip_nav.strp(name);
try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
for (0..loaded_enum.names.len) |field_index| {
@@ -2794,7 +2845,7 @@ fn updateType(
},
.func_type => |func_type| {
const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_nullary) .nullary_func_type else .func_type)));
+ try wip_nav.abbrevCode(if (is_nullary) .nullary_func_type else .func_type);
try wip_nav.strp(name);
try diw.writeByte(@intFromEnum(@as(DW.CC, switch (func_type.cc) {
.Unspecified, .C => .normal,
@@ -2814,15 +2865,15 @@ fn updateType(
try wip_nav.refType(Type.fromInterned(func_type.return_type));
if (!is_nullary) {
for (0..func_type.param_types.len) |param_index| {
- try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
+ try wip_nav.abbrevCode(.func_type_param);
try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
}
- if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
+ if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
try uleb128(diw, @intFromEnum(AbbrevCode.null));
}
},
.error_set_type => |error_set_type| {
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (error_set_type.names.len > 0) .enum_type else .empty_enum_type)));
+ try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .enum_type else .empty_enum_type);
try wip_nav.strp(name);
try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
.signedness = .unsigned,
@@ -2830,7 +2881,7 @@ fn updateType(
} })));
for (0..error_set_type.names.len) |field_index| {
const field_name = error_set_type.names.get(ip)[field_index];
- try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_enum_field));
+ try wip_nav.abbrevCode(.unsigned_enum_field);
try uleb128(diw, ip.getErrorValueIfExists(field_name).?);
try wip_nav.strp(field_name.toSlice(ip));
}
@@ -2838,11 +2889,11 @@ fn updateType(
},
.inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) {
.none => {
- try uleb128(diw, @intFromEnum(AbbrevCode.void_type));
+ try wip_nav.abbrevCode(.void_type);
try wip_nav.strp(name);
},
else => |ies| {
- try uleb128(diw, @intFromEnum(AbbrevCode.inferred_error_set_type));
+ try wip_nav.abbrevCode(.inferred_error_set_type);
try wip_nav.strp(name);
try wip_nav.refType(Type.fromInterned(ies));
},
@@ -2894,7 +2945,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
.func = .none,
.func_sym_index = undefined,
.func_high_reloc = undefined,
- .inlined_funcs_high_reloc = undefined,
+ .inlined_funcs = undefined,
.debug_info = .{},
.debug_line = .{},
.debug_loclists = .{},
@@ -2905,7 +2956,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
const loaded_struct = ip.loadStructType(type_index);
const diw = wip_nav.debug_info.writer(dwarf.gpa);
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0) .namespace_file else .file)));
+ try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_file else .file);
const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
try uleb128(diw, file_gop.index);
try wip_nav.strp(loaded_struct.name.toSlice(ip));
@@ -2914,7 +2965,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_comptime) .struct_field_comptime else .struct_field)));
+ try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
defer dwarf.gpa.free(field_name);
@@ -2957,7 +3008,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
.func = .none,
.func_sym_index = undefined,
.func_high_reloc = undefined,
- .inlined_funcs_high_reloc = undefined,
+ .inlined_funcs = undefined,
.debug_info = .{},
.debug_line = .{},
.debug_loclists = .{},
@@ -2973,17 +3024,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
const loaded_struct = ip.loadStructType(type_index);
switch (loaded_struct.layout) {
.auto, .@"extern" => {
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (loaded_struct.field_types.len == 0)
- .namespace_struct_type
- else
- .struct_type)));
+ try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_struct_type else .struct_type);
try wip_nav.strp(name);
if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
try uleb128(diw, ty.abiSize(pt));
try uleb128(diw, ty.abiAlignment(pt).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (is_comptime) .struct_field_comptime else .struct_field)));
+ try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
defer dwarf.gpa.free(field_name);
@@ -3001,12 +3049,12 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
}
},
.@"packed" => {
- try uleb128(diw, @intFromEnum(AbbrevCode.packed_struct_type));
+ try wip_nav.abbrevCode(.packed_struct_type);
try wip_nav.strp(name);
try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
var field_bit_offset: u16 = 0;
for (0..loaded_struct.field_types.len) |field_index| {
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, .packed_struct_field)));
+ try wip_nav.abbrevCode(.packed_struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
@@ -3019,7 +3067,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
},
.enum_type => {
const loaded_enum = ip.loadEnumType(type_index);
- try uleb128(diw, @intFromEnum(AbbrevCode.enum_type));
+ try wip_nav.abbrevCode(.enum_type);
try wip_nav.strp(name);
try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
for (0..loaded_enum.names.len) |field_index| {
@@ -3033,14 +3081,14 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
},
.union_type => {
const loaded_union = ip.loadUnionType(type_index);
- try uleb128(diw, @intFromEnum(AbbrevCode.union_type));
+ try wip_nav.abbrevCode(.union_type);
try wip_nav.strp(name);
const union_layout = pt.getUnionLayout(loaded_union);
try uleb128(diw, union_layout.abi_size);
try uleb128(diw, union_layout.abi_align.toByteUnits().?);
const loaded_tag = loaded_union.loadTagType(ip);
if (loaded_union.hasTag(ip)) {
- try uleb128(diw, @intFromEnum(AbbrevCode.tagged_union));
+ try wip_nav.abbrevCode(.tagged_union);
try wip_nav.infoSectionOffset(
.debug_info,
wip_nav.unit,
@@ -3048,7 +3096,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
@intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.generated_field));
+ try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("tag");
try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
try uleb128(diw, union_layout.tagOffset());
@@ -3059,7 +3107,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
.unsigned = .unsigned_tagged_union_field,
}, field_index);
{
- try uleb128(diw, @intFromEnum(AbbrevCode.struct_field));
+ try wip_nav.abbrevCode(.struct_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
@@ -3075,7 +3123,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
if (ip.indexToKey(loaded_union.enum_tag_ty).enum_type == .generated_tag)
try wip_nav.pending_types.append(dwarf.gpa, loaded_union.enum_tag_ty);
} else for (0..loaded_union.field_types.len) |field_index| {
- try uleb128(diw, @intFromEnum(AbbrevCode.untagged_union_field));
+ try wip_nav.abbrevCode(.untagged_union_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
@@ -3085,7 +3133,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
try uleb128(diw, @intFromEnum(AbbrevCode.null));
},
.opaque_type => {
- try uleb128(diw, @intFromEnum(AbbrevCode.namespace_struct_type));
+ try wip_nav.abbrevCode(.namespace_struct_type);
try wip_nav.strp(name);
try diw.writeByte(@intFromBool(true));
},
@@ -3121,6 +3169,23 @@ pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {
_ = nav_index;
}
+fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(AbbrevCode).Enum.tag_type {
+ assert(abbrev_code != .null);
+ const entry: Entry.Index = @enumFromInt(@intFromEnum(abbrev_code));
+ if (dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).getEntry(entry).len > 0) return @intFromEnum(abbrev_code);
+ var debug_abbrev = std.ArrayList(u8).init(dwarf.gpa);
+ defer debug_abbrev.deinit();
+ const daw = debug_abbrev.writer();
+ const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
+ try uleb128(daw, @intFromEnum(abbrev_code));
+ try uleb128(daw, @intFromEnum(abbrev.tag));
+ try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
+ for (abbrev.attrs) |*attr| inline for (attr) |info| try uleb128(daw, @intFromEnum(info));
+ for (0..2) |_| try uleb128(daw, 0);
+ try dwarf.debug_abbrev.section.replaceEntry(DebugAbbrev.unit, entry, dwarf, debug_abbrev.items);
+ return @intFromEnum(abbrev_code);
+}
+
pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
const ip = &pt.zcu.intern_pool;
if (dwarf.types.get(.anyerror_type)) |entry| {
@@ -3133,7 +3198,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
.func = .none,
.func_sym_index = undefined,
.func_high_reloc = undefined,
- .inlined_funcs_high_reloc = undefined,
+ .inlined_funcs = undefined,
.debug_info = .{},
.debug_line = .{},
.debug_loclists = .{},
@@ -3142,14 +3207,14 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
defer wip_nav.deinit();
const diw = wip_nav.debug_info.writer(dwarf.gpa);
const global_error_set_names = ip.global_error_set.getNamesFromMainThread();
- try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (global_error_set_names.len > 0) .enum_type else .empty_enum_type)));
+ try wip_nav.abbrevCode(if (global_error_set_names.len > 0) .enum_type else .empty_enum_type);
try wip_nav.strp("anyerror");
try wip_nav.refType(Type.fromInterned(try pt.intern(.{ .int_type = .{
.signedness = .unsigned,
.bits = pt.zcu.errorSetBits(),
} })));
for (global_error_set_names, 1..) |name, value| {
- try uleb128(diw, @intFromEnum(AbbrevCode.unsigned_enum_field));
+ try wip_nav.abbrevCode(.unsigned_enum_field);
try uleb128(diw, value);
try wip_nav.strp(name.toSlice(ip));
}
@@ -3173,21 +3238,6 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
var header = std.ArrayList(u8).init(dwarf.gpa);
defer header.deinit();
- if (dwarf.debug_abbrev.section.dirty) {
- for (1.., &AbbrevCode.abbrevs) |code, *abbrev| {
- try uleb128(header.writer(), code);
- try uleb128(header.writer(), @intFromEnum(abbrev.tag));
- try header.append(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
- for (abbrev.attrs) |*attr| {
- try uleb128(header.writer(), @intFromEnum(attr[0]));
- try uleb128(header.writer(), @intFromEnum(attr[1]));
- }
- try header.appendSlice(&.{ 0, 0 });
- }
- try header.append(@intFromEnum(AbbrevCode.null));
- try dwarf.debug_abbrev.section.replaceEntry(DebugAbbrev.unit, DebugAbbrev.entry, dwarf, header.items);
- dwarf.debug_abbrev.section.dirty = false;
- }
if (dwarf.debug_aranges.section.dirty) {
for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
const unit: Unit.Index = @enumFromInt(unit_index);
@@ -3245,11 +3295,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
.source_off = @intCast(header.items.len),
.target_sec = .debug_abbrev,
.target_unit = DebugAbbrev.unit,
- .target_entry = DebugAbbrev.entry.toOptional(),
});
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
const compile_unit_off: u32 = @intCast(header.items.len);
- uleb128(header.fixedWriter(), @intFromEnum(AbbrevCode.compile_unit)) catch unreachable;
+ uleb128(header.fixedWriter(), try dwarf.refAbbrevCode(.compile_unit)) catch unreachable;
header.appendAssumeCapacity(DW.LANG.Zig);
unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
.source_off = @intCast(header.items.len),
@@ -3292,7 +3341,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
});
header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
uleb128(header.fixedWriter(), 0) catch unreachable;
- uleb128(header.fixedWriter(), @intFromEnum(AbbrevCode.module)) catch unreachable;
+ uleb128(header.fixedWriter(), try dwarf.refAbbrevCode(.module)) catch unreachable;
unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
.source_off = @intCast(header.items.len),
.target_sec = .debug_str,
@@ -3306,6 +3355,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
}
dwarf.debug_info.section.dirty = false;
}
+ if (dwarf.debug_abbrev.section.dirty) {
+ assert(!dwarf.debug_info.section.dirty);
+ try dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).writeTrailer(&dwarf.debug_abbrev.section, dwarf);
+ dwarf.debug_abbrev.section.dirty = false;
+ }
if (dwarf.debug_str.section.dirty) {
const contents = dwarf.debug_str.contents.items;
try dwarf.debug_str.section.resize(dwarf, contents.len);
@@ -3313,8 +3367,11 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
dwarf.debug_str.section.dirty = false;
}
if (dwarf.debug_line.section.dirty) {
- for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit|
- try unit.resizeHeader(&dwarf.debug_line.section, dwarf, DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())));
+ for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| try unit.resizeHeader(
+ &dwarf.debug_line.section,
+ dwarf,
+ DebugLine.headerBytes(dwarf, @intCast(mod_info.dirs.count()), @intCast(mod_info.files.count())),
+ );
for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
unit.clear();
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 {
}
std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);
header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
- switch (dwarf.format) {
- inline .@"32", .@"64" => |format| std.mem.writeInt(
- SectionOffset(format),
- header.addManyAsArrayAssumeCapacity(@sizeOf(SectionOffset(format))),
- @intCast(unit.header_len - header.items.len),
- dwarf.endian,
- ),
- }
+ dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), unit.header_len - header.items.len);
const StandardOpcode = DeclValEnum(DW.LNS);
header.appendSliceAssumeCapacity(&[_]u8{
dwarf.debug_line.header.minimum_instruction_length,
@@ -3422,6 +3472,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off);
dwarf.debug_line_str.section.dirty = false;
}
+ if (dwarf.debug_loclists.section.dirty) {
+ dwarf.debug_loclists.section.dirty = false;
+ }
if (dwarf.debug_rnglists.section.dirty) {
for (dwarf.debug_rnglists.section.units.items) |*unit| {
header.clearRetainingCapacity();
@@ -3440,19 +3493,20 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(@sizeOf(u16)), 5, dwarf.endian);
header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(@sizeOf(u32)), 1, dwarf.endian);
- switch (dwarf.format) {
- inline .@"32", .@"64" => |format| std.mem.writeInt(
- SectionOffset(format),
- header.addManyAsArrayAssumeCapacity(@sizeOf(SectionOffset(format))),
- @sizeOf(SectionOffset(format)),
- dwarf.endian,
- ),
- }
+ dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), dwarf.sectionOffsetBytes() * 1);
try unit.replaceHeader(&dwarf.debug_rnglists.section, dwarf, header.items);
try unit.writeTrailer(&dwarf.debug_rnglists.section, dwarf);
}
dwarf.debug_rnglists.section.dirty = false;
}
+ assert(!dwarf.debug_abbrev.section.dirty);
+ assert(!dwarf.debug_aranges.section.dirty);
+ assert(!dwarf.debug_info.section.dirty);
+ assert(!dwarf.debug_line.section.dirty);
+ assert(!dwarf.debug_line_str.section.dirty);
+ assert(!dwarf.debug_loclists.section.dirty);
+ assert(!dwarf.debug_rnglists.section.dirty);
+ assert(!dwarf.debug_str.section.dirty);
}
pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void {
@@ -3491,7 +3545,7 @@ fn DeclValEnum(comptime T: type) type {
} });
}
-const AbbrevCode = enum(u8) {
+const AbbrevCode = enum {
null,
// padding codes must be one byte uleb128 values to function
pad_1,
@@ -3499,15 +3553,16 @@ const AbbrevCode = enum(u8) {
// decl codes are assumed to all have the same uleb128 length
decl_alias,
decl_enum,
+ decl_empty_enum,
decl_namespace_struct,
decl_struct,
decl_packed_struct,
decl_union,
decl_var,
decl_func,
- decl_func_empty,
+ decl_empty_func,
decl_func_generic,
- decl_func_generic_empty,
+ decl_empty_func_generic,
// the rest are unrestricted
compile_unit,
module,
@@ -3542,11 +3597,12 @@ const AbbrevCode = enum(u8) {
struct_type,
packed_struct_type,
union_type,
+ empty_inlined_func,
inlined_func,
local_arg,
local_var,
- const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_generic_empty));
+ const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_empty_func_generic));
const Attr = struct {
DeclValEnum(DW.AT),
@@ -3586,6 +3642,12 @@ const AbbrevCode = enum(u8) {
.{ .type, .ref_addr },
},
},
+ .decl_empty_enum = .{
+ .tag = .enumeration_type,
+ .attrs = decl_abbrev_common_attrs ++ .{
+ .{ .type, .ref_addr },
+ },
+ },
.decl_namespace_struct = .{
.tag = .structure_type,
.attrs = decl_abbrev_common_attrs ++ .{
@@ -3638,7 +3700,7 @@ const AbbrevCode = enum(u8) {
.{ .noreturn, .flag },
},
},
- .decl_func_empty = .{
+ .decl_empty_func = .{
.tag = .subprogram,
.attrs = decl_abbrev_common_attrs ++ .{
.{ .linkage_name, .strp },
@@ -3657,7 +3719,7 @@ const AbbrevCode = enum(u8) {
.{ .type, .ref_addr },
},
},
- .decl_func_generic_empty = .{
+ .decl_empty_func_generic = .{
.tag = .subprogram,
.attrs = decl_abbrev_common_attrs ++ .{
.{ .type, .ref_addr },
@@ -3918,6 +3980,16 @@ const AbbrevCode = enum(u8) {
.{ .alignment, .udata },
},
},
+ .empty_inlined_func = .{
+ .tag = .inlined_subroutine,
+ .attrs = &.{
+ .{ .abstract_origin, .ref_addr },
+ .{ .call_line, .udata },
+ .{ .call_column, .udata },
+ .{ .low_pc, .addr },
+ .{ .high_pc, .addr },
+ },
+ },
.inlined_func = .{
.tag = .inlined_subroutine,
.children = true,
@@ -3946,7 +4018,7 @@ const AbbrevCode = enum(u8) {
},
},
.null = undefined,
- }).values[1..].*;
+ });
};
fn getFile(dwarf: *Dwarf) ?std.fs.File {
@@ -3955,11 +4027,11 @@ fn getFile(dwarf: *Dwarf) ?std.fs.File {
}
fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {
- const entry = try dwarf.debug_aranges.section.addEntry(unit, dwarf);
- assert(try dwarf.debug_info.section.addEntry(unit, dwarf) == entry);
- assert(try dwarf.debug_line.section.addEntry(unit, dwarf) == entry);
- assert(try dwarf.debug_loclists.section.addEntry(unit, dwarf) == entry);
- assert(try dwarf.debug_rnglists.section.addEntry(unit, dwarf) == entry);
+ const entry = try dwarf.debug_aranges.section.getUnit(unit).addEntry(dwarf.gpa);
+ assert(try dwarf.debug_info.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
+ assert(try dwarf.debug_line.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
+ assert(try dwarf.debug_loclists.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
+ assert(try dwarf.debug_rnglists.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
return entry;
}
@@ -3993,13 +4065,6 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 {
};
}
-fn SectionOffset(comptime format: DW.Format) type {
- return switch (format) {
- .@"32" => u32,
- .@"64" => u64,
- };
-}
-
fn uleb128Bytes(value: anytype) u32 {
var cw = std.io.countingWriter(std.io.null_writer);
try uleb128(cw.writer(), value);