authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-28 05:58:10-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-28 06:45:17-04:00
log12275cf4b9a1e02e08aef8e1b29e5accb16268f1
treed9503440a86820f10be7415140ba3bfff53cc87b
parent4cc16fd6f7ac22e32ff4e42b61ad1bb7157d282f

Dwarf: fix parsing self-hosted debug info for stack traces


1 files changed, 13 insertions(+), 14 deletions(-)

lib/std/debug/Dwarf.zig+13-14
......@@ -279,10 +279,11 @@ pub const Die = struct {
279279 };
280280 }
281281
282 fn getAttrRef(self: *const Die, id: u64) !u64 {
282 fn getAttrRef(self: *const Die, id: u64, unit_offset: u64, unit_len: u64) !u64 {
283283 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
284284 return switch (form_value.*) {
285 .ref => |value| value,
285 .ref => |offset| if (offset < unit_len) unit_offset + offset else bad(),
286 .ref_addr => |addr| addr,
286287 else => bad(),
287288 };
288289 }
......@@ -428,14 +429,14 @@ pub const ExceptionFrameHeader = struct {
428429 };
429430
430431 const fde_entry_header = try EntryHeader.read(&eh_frame_fbr, if (eh_frame_len == null) ma else null, .eh_frame);
431 if (!self.isValidPtr(u8, @intFromPtr(&fde_entry_header.entry_bytes[fde_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
432 if (fde_entry_header.entry_bytes.len > 0 and !self.isValidPtr(u8, @intFromPtr(&fde_entry_header.entry_bytes[fde_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
432433 if (fde_entry_header.type != .fde) return bad();
433434
434435 // CIEs always come before FDEs (the offset is a subtraction), so we can assume this memory is readable
435436 const cie_offset = fde_entry_header.type.fde;
436437 try eh_frame_fbr.seekTo(cie_offset);
437438 const cie_entry_header = try EntryHeader.read(&eh_frame_fbr, if (eh_frame_len == null) ma else null, .eh_frame);
438 if (!self.isValidPtr(u8, @intFromPtr(&cie_entry_header.entry_bytes[cie_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
439 if (cie_entry_header.entry_bytes.len > 0 and !self.isValidPtr(u8, @intFromPtr(&cie_entry_header.entry_bytes[cie_entry_header.entry_bytes.len - 1]), ma, eh_frame_len)) return bad();
439440 if (cie_entry_header.type != .cie) return bad();
440441
441442 cie.* = try CommonInformationEntry.parse(
......@@ -942,13 +943,12 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator) ScanError!void {
942943 defer fbr.pos = after_die_offset;
943944
944945 // Follow the DIE it points to and repeat
945 const ref_offset = try this_die_obj.getAttrRef(AT.abstract_origin);
946 if (ref_offset > next_offset) return bad();
947 try fbr.seekTo(this_unit_offset + ref_offset);
946 const ref_offset = try this_die_obj.getAttrRef(AT.abstract_origin, this_unit_offset, next_offset);
947 try fbr.seekTo(ref_offset);
948948 this_die_obj = (try parseDie(
949949 &fbr,
950950 attrs_bufs[2],
951 abbrev_table,
951 abbrev_table, // wrong abbrev table for different cu
952952 unit_header.format,
953953 )) orelse return bad();
954954 } else if (this_die_obj.getAttr(AT.specification)) |_| {
......@@ -956,13 +956,12 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator) ScanError!void {
956956 defer fbr.pos = after_die_offset;
957957
958958 // Follow the DIE it points to and repeat
959 const ref_offset = try this_die_obj.getAttrRef(AT.specification);
960 if (ref_offset > next_offset) return bad();
961 try fbr.seekTo(this_unit_offset + ref_offset);
959 const ref_offset = try this_die_obj.getAttrRef(AT.specification, this_unit_offset, next_offset);
960 try fbr.seekTo(ref_offset);
962961 this_die_obj = (try parseDie(
963962 &fbr,
964963 attrs_bufs[2],
965 abbrev_table,
964 abbrev_table, // wrong abbrev table for different cu
966965 unit_header.format,
967966 )) orelse return bad();
968967 } else {
......@@ -1494,7 +1493,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) !
14941493 }
14951494 } else {
14961495 const FileEntFmt = struct {
1497 content_type_code: u8,
1496 content_type_code: u16,
14981497 form_code: u16,
14991498 };
15001499 {
......@@ -1539,7 +1538,7 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) !
15391538 if (file_name_entry_format_count > file_ent_fmt_buf.len) return bad();
15401539 for (file_ent_fmt_buf[0..file_name_entry_format_count]) |*ent_fmt| {
15411540 ent_fmt.* = .{
1542 .content_type_code = try fbr.readUleb128(u8),
1541 .content_type_code = try fbr.readUleb128(u16),
15431542 .form_code = try fbr.readUleb128(u16),
15441543 };
15451544 }