authorgravatar for fabi.theo@gmail.comTheo Fabi <fabi.theo@gmail.com> 2026-07-23 11:54:00-04:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-02 12:03:06+02:00
log833105128485bf84a22f26506eb5e7b9bfa146a0
tree37eee896082b17553e613dbe08b6c8c71d93e984
parent8523ee09ae1f03d93d8029263c7bb7fe0ec282e7

debug.Dwarf: FORM_ref_addr is host address sized in DWARFv2

DW_FORM_ref_addr encoding specification is different in dwarf version 2. parseFormValue() now accepts a `version` argument so that it can parse such attributes correctly based on the version.

1 files changed, 16 insertions(+), 5 deletions(-)

lib/std/debug/Dwarf.zig+16-5
......@@ -450,6 +450,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void {
450450 unit_header.format,
451451 endian,
452452 address_size,
453 version,
453454 )) orelse continue;
454455
455456 switch (die_obj.tag_id) {
......@@ -485,6 +486,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void {
485486 unit_header.format,
486487 endian,
487488 address_size,
489 version,
488490 )) orelse return bad();
489491 } else if (this_die_obj.getAttr(AT.specification)) |_| {
490492 const after_die_offset = fr.seek;
......@@ -500,6 +502,7 @@ fn scanAllFunctions(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void {
500502 unit_header.format,
501503 endian,
502504 address_size,
505 version,
503506 )) orelse return bad();
504507 } else {
505508 break :x null;
......@@ -611,6 +614,7 @@ fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!voi
611614 unit_header.format,
612615 endian,
613616 address_size,
617 version,
614618 )) orelse return bad();
615619
616620 if (compile_unit_die.tag_id != DW.TAG.compile_unit) return bad();
......@@ -931,6 +935,7 @@ fn parseDie(
931935 format: Format,
932936 endian: Endian,
933937 addr_size_bytes: u8,
938 version: u16,
934939) ScanError!?Die {
935940 const abbrev_code = try fr.takeLeb128(u64);
936941 if (abbrev_code == 0) return null;
......@@ -939,7 +944,7 @@ fn parseDie(
939944 const attrs = attrs_buf[0..table_entry.attrs.len];
940945 for (attrs, table_entry.attrs) |*result_attr, attr| result_attr.* = .{
941946 .id = attr.id,
942 .value = try parseFormValue(fr, attr.form_id, format, endian, addr_size_bytes, attr.payload),
947 .value = try parseFormValue(fr, attr.form_id, format, endian, addr_size_bytes, attr.payload, version),
943948 };
944949 return .{
945950 .tag_id = table_entry.tag_id,
......@@ -1042,7 +1047,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
10421047 for (try directories.addManyAsSlice(gpa, directories_count)) |*e| {
10431048 e.* = .{ .path = &.{} };
10441049 for (dir_ent_fmt_buf[0..directory_entry_format_count]) |ent_fmt| {
1045 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null);
1050 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null, version);
10461051 switch (ent_fmt.content_type_code) {
10471052 DW.LNCT.path => e.path = try form_value.getString(d.*),
10481053 DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32),
......@@ -1074,7 +1079,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, endian: Endian, compile_unit:
10741079 for (try file_entries.addManyAsSlice(gpa, file_names_count)) |*e| {
10751080 e.* = .{ .path = &.{} };
10761081 for (file_ent_fmt_buf[0..file_name_entry_format_count]) |ent_fmt| {
1077 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null);
1082 const form_value = try parseFormValue(&fr, ent_fmt.form_code, unit_header.format, endian, addr_size_bytes, null, version);
10781083 switch (ent_fmt.content_type_code) {
10791084 DW.LNCT.path => e.path = try form_value.getString(d.*),
10801085 DW.LNCT.directory_index => e.dir_index = try form_value.getUInt(u32),
......@@ -1285,6 +1290,7 @@ fn parseFormValue(
12851290 endian: Endian,
12861291 addr_size_bytes: u8,
12871292 implicit_const: ?i64,
1293 version: u16,
12881294) ScanError!FormValue {
12891295 return switch (form_id) {
12901296 // DWARF5.pdf page 213: the size of this value is encoded in the
......@@ -1319,7 +1325,12 @@ fn parseFormValue(
13191325 FORM.ref8 => .{ .ref = try r.takeInt(u64, endian) },
13201326 FORM.ref_udata => .{ .ref = try r.takeLeb128(u64) },
13211327
1322 FORM.ref_addr => .{ .ref_addr = try readFormatSizedInt(r, format, endian) },
1328 FORM.ref_addr => .{
1329 .ref_addr = switch (version) {
1330 2 => try readAddress(r, endian, addr_size_bytes),
1331 else => try readFormatSizedInt(r, format, endian),
1332 },
1333 },
13231334 FORM.ref_sig8 => .{ .ref = try r.takeInt(u64, endian) },
13241335
13251336 FORM.string => .{ .string = try r.takeSentinel(0) },
......@@ -1330,7 +1341,7 @@ fn parseFormValue(
13301341 FORM.strx4 => .{ .strx = try r.takeInt(u32, endian) },
13311342 FORM.strx => .{ .strx = try r.takeLeb128(usize) },
13321343 FORM.line_strp => .{ .line_strp = try readFormatSizedInt(r, format, endian) },
1333 FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, addr_size_bytes, implicit_const),
1344 FORM.indirect => parseFormValue(r, try r.takeLeb128(u64), format, endian, addr_size_bytes, implicit_const, version),
13341345 FORM.implicit_const => .{ .sdata = implicit_const orelse return bad() },
13351346 FORM.loclistx => .{ .loclistx = try r.takeLeb128(u64) },
13361347 FORM.rnglistx => .{ .rnglistx = try r.takeLeb128(u64) },