diff options
| author | Keith Chambers <KD.Chambers97@Gmail.com> | 2022-08-22 19:50:06 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-22 20:50:06 -0400 |
| commit | 96737ef499e66d8ab3e32fd4641599b1843f5b8c (patch) | |
| tree | 6a99c4c92be980e877dc87484b2866c0d5fba799 /lib/std | |
| parent | 6d679eb2bcbe76e389c02e0bb4d4c4feb2847783 (diff) | |
| download | zig-96737ef499e66d8ab3e32fd4641599b1843f5b8c.tar.gz zig-96737ef499e66d8ab3e32fd4641599b1843f5b8c.zip | |
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
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/debug.zig | 9 | ||||
| -rw-r--r-- | lib/std/dwarf.zig | 30 |
2 files changed, 35 insertions, 4 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 33b8a98d7f..3ce9f3c1d3 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -846,6 +846,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo .debug_info = debug_info_data orelse return error.MissingDebugInfo, .debug_abbrev = debug_abbrev_data orelse return error.MissingDebugInfo, .debug_str = debug_str_data orelse return error.MissingDebugInfo, + .debug_str_offsets = null, .debug_line = debug_line_data orelse return error.MissingDebugInfo, .debug_line_str = debug_line_str_data, .debug_ranges = debug_ranges_data, @@ -912,6 +913,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn var opt_debug_info: ?[]const u8 = null; var opt_debug_abbrev: ?[]const u8 = null; var opt_debug_str: ?[]const u8 = null; + var opt_debug_str_offsets: ?[]const u8 = null; var opt_debug_line: ?[]const u8 = null; var opt_debug_line_str: ?[]const u8 = null; var opt_debug_ranges: ?[]const u8 = null; @@ -926,6 +928,8 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn opt_debug_abbrev = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); } else if (mem.eql(u8, name, ".debug_str")) { opt_debug_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); + } else if (mem.eql(u8, name, ".debug_str_offsets")) { + opt_debug_str_offsets = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); } else if (mem.eql(u8, name, ".debug_line")) { opt_debug_line = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); } else if (mem.eql(u8, name, ".debug_line_str")) { @@ -940,6 +944,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn .debug_info = opt_debug_info orelse return error.MissingDebugInfo, .debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo, .debug_str = opt_debug_str orelse return error.MissingDebugInfo, + .debug_str_offsets = opt_debug_str_offsets, .debug_line = opt_debug_line orelse return error.MissingDebugInfo, .debug_line_str = opt_debug_line_str, .debug_ranges = opt_debug_ranges, @@ -1515,6 +1520,7 @@ pub const ModuleDebugInfo = switch (native_os) { .debug_info = try chopSlice(mapped_mem, debug_info.offset, debug_info.size), .debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.offset, debug_abbrev.size), .debug_str = try chopSlice(mapped_mem, debug_str.offset, debug_str.size), + .debug_str_offsets = null, .debug_line = try chopSlice(mapped_mem, debug_line.offset, debug_line.size), .debug_line_str = if (opt_debug_line_str) |debug_line_str| try chopSlice(mapped_mem, debug_line_str.offset, debug_line_str.size) @@ -1578,6 +1584,7 @@ pub const ModuleDebugInfo = switch (native_os) { .compile_unit_name = compile_unit.die.getAttrString( o_file_di, DW.AT.name, + compile_unit.is_64, ) catch |err| switch (err) { error.MissingDebugInfo, error.InvalidDebugInfo => "???", }, @@ -1698,7 +1705,7 @@ fn getSymbolFromDwarf(allocator: mem.Allocator, address: u64, di: *DW.DwarfInfo) if (nosuspend di.findCompileUnit(address)) |compile_unit| { return SymbolInfo{ .symbol_name = nosuspend di.getSymbolName(address) orelse "???", - .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT.name) catch |err| switch (err) { + .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT.name, compile_unit.is_64) catch |err| switch (err) { error.MissingDebugInfo, error.InvalidDebugInfo => "???", }, .line_info = nosuspend di.getLineNumberInfo(allocator, compile_unit.*, address) catch |err| switch (err) { diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index d61d198c7e..40dfc8cebb 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -214,6 +214,7 @@ const FormValue = union(enum) { RefAddr: u64, String: []const u8, StrPtr: u64, + StrOffset: u64, LineStrPtr: u64, }; @@ -284,11 +285,15 @@ const Die = struct { }; } - pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 { + pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64, is_64: bool) ![]const u8 { const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; return switch (form_value.*) { FormValue.String => |value| value, FormValue.StrPtr => |offset| di.getString(offset), + FormValue.StrOffset => |index| blk: { + const base_offset = self.getAttrSecOffset(AT.str_offsets_base) catch 0; + break :blk di.getLineString(try di.getStringOffset(base_offset + index, is_64)); + }, FormValue.LineStrPtr => |offset| di.getLineString(offset), else => error.InvalidDebugInfo, }; @@ -522,6 +527,10 @@ fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, en FORM.string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) }, FORM.strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) }, + FORM.strx1 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u8, endian)) }, + FORM.strx2 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u16, endian)) }, + FORM.strx3 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u24, endian)) }, + FORM.strx4 => return FormValue{ .StrOffset = @intCast(u64, try in_stream.readInt(u32, endian)) }, FORM.line_strp => FormValue{ .LineStrPtr = try readAddress(in_stream, endian, is_64) }, FORM.indirect => { const child_form_id = try nosuspend leb.readULEB128(u64, in_stream); @@ -554,6 +563,7 @@ pub const DwarfInfo = struct { debug_info: []const u8, debug_abbrev: []const u8, debug_str: []const u8, + debug_str_offsets: ?[]const u8, debug_line: []const u8, debug_line_str: ?[]const u8, debug_ranges: ?[]const u8, @@ -652,7 +662,7 @@ pub const DwarfInfo = struct { // Prevent endless loops while (depth > 0) : (depth -= 1) { if (this_die_obj.getAttr(AT.name)) |_| { - const name = try this_die_obj.getAttrString(di, AT.name); + const name = try this_die_obj.getAttrString(di, AT.name, is_64); break :x try allocator.dupe(u8, name); } else if (this_die_obj.getAttr(AT.abstract_origin)) |_| { // Follow the DIE it points to and repeat @@ -956,7 +966,7 @@ pub const DwarfInfo = struct { const in = &stream.reader(); const seekable = &stream.seekableStream(); - const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT.comp_dir); + const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT.comp_dir, compile_unit.is_64); const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list); try seekable.seekTo(line_info_offset); @@ -1144,6 +1154,20 @@ pub const DwarfInfo = struct { return error.InvalidDebugInfo; } + fn getStringOffset(di: *DwarfInfo, offset: u64, is_64: bool) !u64 { + if (di.debug_str_offsets) |debug_str_offsets| { + if (offset >= debug_str_offsets.len) { + return error.InvalidDebugInfo; + } + const offset_casted = @intCast(usize, offset); + if (is_64) { + return std.mem.readIntSlice(u64, debug_str_offsets[offset_casted .. offset_casted + 8], di.endian); + } + return @intCast(u64, std.mem.readIntSlice(u32, debug_str_offsets[offset_casted .. offset_casted + 4], di.endian)); + } + return error.InvalidDebugInfo; + } + fn getLineString(di: *DwarfInfo, offset: u64) ![]const u8 { const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo; if (offset > debug_line_str.len) |
