authorgravatar for KD.Chambers97@Gmail.comKeith Chambers <KD.Chambers97@Gmail.com> 2022-08-22 19:50:06-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-08-22 20:50:06-04:00
log96737ef499e66d8ab3e32fd4641599b1843f5b8c
tree6a99c4c92be980e877dc87484b2866c0d5fba799
parent6d679eb2bcbe76e389c02e0bb4d4c4feb2847783
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Dwarf: Added stroffsetsptr support (#12270)

* Added support for stroffsetsptr class in Dwarf stdlib * Proper initializion of debug_str_offsets in DwarfInfo * Added missing null initializer to DwarfInfo in Macho * Added missing is_64 field to getAttrString in DwarfInfo * Fixed formatting * Added missing is_64 param to getAttrString * Added required cast to usize * Adding missing .debug_str_offsets initialization * getAttrString now uses the str_offsets_base attr

4 files changed, 39 insertions(+), 6 deletions(-)

lib/std/debug.zig+8-1
......@@ -846,6 +846,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo
846846 .debug_info = debug_info_data orelse return error.MissingDebugInfo,
847847 .debug_abbrev = debug_abbrev_data orelse return error.MissingDebugInfo,
848848 .debug_str = debug_str_data orelse return error.MissingDebugInfo,
849 .debug_str_offsets = null,
849850 .debug_line = debug_line_data orelse return error.MissingDebugInfo,
850851 .debug_line_str = debug_line_str_data,
851852 .debug_ranges = debug_ranges_data,
......@@ -912,6 +913,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
912913 var opt_debug_info: ?[]const u8 = null;
913914 var opt_debug_abbrev: ?[]const u8 = null;
914915 var opt_debug_str: ?[]const u8 = null;
916 var opt_debug_str_offsets: ?[]const u8 = null;
915917 var opt_debug_line: ?[]const u8 = null;
916918 var opt_debug_line_str: ?[]const u8 = null;
917919 var opt_debug_ranges: ?[]const u8 = null;
......@@ -926,6 +928,8 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
926928 opt_debug_abbrev = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
927929 } else if (mem.eql(u8, name, ".debug_str")) {
928930 opt_debug_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
931 } else if (mem.eql(u8, name, ".debug_str_offsets")) {
932 opt_debug_str_offsets = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
929933 } else if (mem.eql(u8, name, ".debug_line")) {
930934 opt_debug_line = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
931935 } else if (mem.eql(u8, name, ".debug_line_str")) {
......@@ -940,6 +944,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
940944 .debug_info = opt_debug_info orelse return error.MissingDebugInfo,
941945 .debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo,
942946 .debug_str = opt_debug_str orelse return error.MissingDebugInfo,
947 .debug_str_offsets = opt_debug_str_offsets,
943948 .debug_line = opt_debug_line orelse return error.MissingDebugInfo,
944949 .debug_line_str = opt_debug_line_str,
945950 .debug_ranges = opt_debug_ranges,
......@@ -1515,6 +1520,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15151520 .debug_info = try chopSlice(mapped_mem, debug_info.offset, debug_info.size),
15161521 .debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.offset, debug_abbrev.size),
15171522 .debug_str = try chopSlice(mapped_mem, debug_str.offset, debug_str.size),
1523 .debug_str_offsets = null,
15181524 .debug_line = try chopSlice(mapped_mem, debug_line.offset, debug_line.size),
15191525 .debug_line_str = if (opt_debug_line_str) |debug_line_str|
15201526 try chopSlice(mapped_mem, debug_line_str.offset, debug_line_str.size)
......@@ -1578,6 +1584,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15781584 .compile_unit_name = compile_unit.die.getAttrString(
15791585 o_file_di,
15801586 DW.AT.name,
1587 compile_unit.is_64,
15811588 ) catch |err| switch (err) {
15821589 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
15831590 },
......@@ -1698,7 +1705,7 @@ fn getSymbolFromDwarf(allocator: mem.Allocator, address: u64, di: *DW.DwarfInfo)
16981705 if (nosuspend di.findCompileUnit(address)) |compile_unit| {
16991706 return SymbolInfo{
17001707 .symbol_name = nosuspend di.getSymbolName(address) orelse "???",
1701 .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT.name) catch |err| switch (err) {
1708 .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT.name, compile_unit.is_64) catch |err| switch (err) {
17021709 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
17031710 },
17041711 .line_info = nosuspend di.getLineNumberInfo(allocator, compile_unit.*, address) catch |err| switch (err) {
lib/std/dwarf.zig+27-3
......@@ -214,6 +214,7 @@ const FormValue = union(enum) {
214214 RefAddr: u64,
215215 String: []const u8,
216216 StrPtr: u64,
217 StrOffset: u64,
217218 LineStrPtr: u64,
218219};
219220
......@@ -284,11 +285,15 @@ const Die = struct {
284285 };
285286 }
286287
287 pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {
288 pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64, is_64: bool) ![]const u8 {
288289 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
289290 return switch (form_value.*) {
290291 FormValue.String => |value| value,
291292 FormValue.StrPtr => |offset| di.getString(offset),
293 FormValue.StrOffset => |index| blk: {
294 const base_offset = self.getAttrSecOffset(AT.str_offsets_base) catch 0;
295 break :blk di.getLineString(try di.getStringOffset(base_offset + index, is_64));
296 },
292297 FormValue.LineStrPtr => |offset| di.getLineString(offset),
293298 else => error.InvalidDebugInfo,
294299 };
......@@ -522,6 +527,10 @@ fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, en
522527
523528 FORM.string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
524529 FORM.strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
530 FORM.strx1 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u8, endian)) },
531 FORM.strx2 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u16, endian)) },
532 FORM.strx3 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u24, endian)) },
533 FORM.strx4 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u32, endian)) },
525534 FORM.line_strp => FormValue{ .LineStrPtr = try readAddress(in_stream, endian, is_64) },
526535 FORM.indirect => {
527536 const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
......@@ -554,6 +563,7 @@ pub const DwarfInfo = struct {
554563 debug_info: []const u8,
555564 debug_abbrev: []const u8,
556565 debug_str: []const u8,
566 debug_str_offsets: ?[]const u8,
557567 debug_line: []const u8,
558568 debug_line_str: ?[]const u8,
559569 debug_ranges: ?[]const u8,
......@@ -652,7 +662,7 @@ pub const DwarfInfo = struct {
652662 // Prevent endless loops
653663 while (depth > 0) : (depth -= 1) {
654664 if (this_die_obj.getAttr(AT.name)) |_| {
655 const name = try this_die_obj.getAttrString(di, AT.name);
665 const name = try this_die_obj.getAttrString(di, AT.name, is_64);
656666 break :x try allocator.dupe(u8, name);
657667 } else if (this_die_obj.getAttr(AT.abstract_origin)) |_| {
658668 // Follow the DIE it points to and repeat
......@@ -956,7 +966,7 @@ pub const DwarfInfo = struct {
956966 const in = &stream.reader();
957967 const seekable = &stream.seekableStream();
958968
959 const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT.comp_dir);
969 const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT.comp_dir, compile_unit.is_64);
960970 const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list);
961971
962972 try seekable.seekTo(line_info_offset);
......@@ -1144,6 +1154,20 @@ pub const DwarfInfo = struct {
11441154 return error.InvalidDebugInfo;
11451155 }
11461156
1157 fn getStringOffset(di: *DwarfInfo, offset: u64, is_64: bool) !u64 {
1158 if (di.debug_str_offsets) |debug_str_offsets| {
1159 if (offset >= debug_str_offsets.len) {
1160 return error.InvalidDebugInfo;
1161 }
1162 const offset_casted = @intCast(usize, offset);
1163 if (is_64) {
1164 return std.mem.readIntSlice(u64, debug_str_offsets[offset_casted .. offset_casted + 8], di.endian);
1165 }
1166 return @intCast(u64, std.mem.readIntSlice(u32, debug_str_offsets[offset_casted .. offset_casted + 4], di.endian));
1167 }
1168 return error.InvalidDebugInfo;
1169 }
1170
11471171 fn getLineString(di: *DwarfInfo, offset: u64) ![]const u8 {
11481172 const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo;
11491173 if (offset > debug_line_str.len)
src/link/MachO.zig+3-2
......@@ -5861,8 +5861,9 @@ pub fn generateSymbolStabs(
58615861 },
58625862 else => |e| return e,
58635863 };
5864 const tu_name = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.name);
5865 const tu_comp_dir = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.comp_dir);
5864
5865 const tu_name = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.name, compile_unit.is_64);
5866 const tu_comp_dir = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.comp_dir, compile_unit.is_64);
58665867
58675868 // Open scope
58685869 try locals.ensureUnusedCapacity(3);
src/link/MachO/Object.zig+1
......@@ -580,6 +580,7 @@ pub fn parseDwarfInfo(self: Object) error{Overflow}!dwarf.DwarfInfo {
580580 .debug_info = &[0]u8{},
581581 .debug_abbrev = &[0]u8{},
582582 .debug_str = &[0]u8{},
583 .debug_str_offsets = null,
583584 .debug_line = &[0]u8{},
584585 .debug_line_str = &[0]u8{},
585586 .debug_ranges = &[0]u8{},