mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
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
This commit is contained in:
parent
6d679eb2bc
commit
96737ef499
@ -846,6 +846,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo
|
|||||||
.debug_info = debug_info_data orelse return error.MissingDebugInfo,
|
.debug_info = debug_info_data orelse return error.MissingDebugInfo,
|
||||||
.debug_abbrev = debug_abbrev_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 = debug_str_data orelse return error.MissingDebugInfo,
|
||||||
|
.debug_str_offsets = null,
|
||||||
.debug_line = debug_line_data orelse return error.MissingDebugInfo,
|
.debug_line = debug_line_data orelse return error.MissingDebugInfo,
|
||||||
.debug_line_str = debug_line_str_data,
|
.debug_line_str = debug_line_str_data,
|
||||||
.debug_ranges = debug_ranges_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_info: ?[]const u8 = null;
|
||||||
var opt_debug_abbrev: ?[]const u8 = null;
|
var opt_debug_abbrev: ?[]const u8 = null;
|
||||||
var opt_debug_str: ?[]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: ?[]const u8 = null;
|
||||||
var opt_debug_line_str: ?[]const u8 = null;
|
var opt_debug_line_str: ?[]const u8 = null;
|
||||||
var opt_debug_ranges: ?[]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);
|
opt_debug_abbrev = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
|
||||||
} else if (mem.eql(u8, name, ".debug_str")) {
|
} else if (mem.eql(u8, name, ".debug_str")) {
|
||||||
opt_debug_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
|
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")) {
|
} else if (mem.eql(u8, name, ".debug_line")) {
|
||||||
opt_debug_line = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
|
opt_debug_line = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
|
||||||
} else if (mem.eql(u8, name, ".debug_line_str")) {
|
} 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_info = opt_debug_info orelse return error.MissingDebugInfo,
|
||||||
.debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo,
|
.debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo,
|
||||||
.debug_str = opt_debug_str 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 = opt_debug_line orelse return error.MissingDebugInfo,
|
||||||
.debug_line_str = opt_debug_line_str,
|
.debug_line_str = opt_debug_line_str,
|
||||||
.debug_ranges = opt_debug_ranges,
|
.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_info = try chopSlice(mapped_mem, debug_info.offset, debug_info.size),
|
||||||
.debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.offset, debug_abbrev.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 = 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 = try chopSlice(mapped_mem, debug_line.offset, debug_line.size),
|
||||||
.debug_line_str = if (opt_debug_line_str) |debug_line_str|
|
.debug_line_str = if (opt_debug_line_str) |debug_line_str|
|
||||||
try chopSlice(mapped_mem, debug_line_str.offset, debug_line_str.size)
|
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(
|
.compile_unit_name = compile_unit.die.getAttrString(
|
||||||
o_file_di,
|
o_file_di,
|
||||||
DW.AT.name,
|
DW.AT.name,
|
||||||
|
compile_unit.is_64,
|
||||||
) catch |err| switch (err) {
|
) catch |err| switch (err) {
|
||||||
error.MissingDebugInfo, error.InvalidDebugInfo => "???",
|
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| {
|
if (nosuspend di.findCompileUnit(address)) |compile_unit| {
|
||||||
return SymbolInfo{
|
return SymbolInfo{
|
||||||
.symbol_name = nosuspend di.getSymbolName(address) orelse "???",
|
.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 => "???",
|
error.MissingDebugInfo, error.InvalidDebugInfo => "???",
|
||||||
},
|
},
|
||||||
.line_info = nosuspend di.getLineNumberInfo(allocator, compile_unit.*, address) catch |err| switch (err) {
|
.line_info = nosuspend di.getLineNumberInfo(allocator, compile_unit.*, address) catch |err| switch (err) {
|
||||||
|
|||||||
@ -214,6 +214,7 @@ const FormValue = union(enum) {
|
|||||||
RefAddr: u64,
|
RefAddr: u64,
|
||||||
String: []const u8,
|
String: []const u8,
|
||||||
StrPtr: u64,
|
StrPtr: u64,
|
||||||
|
StrOffset: u64,
|
||||||
LineStrPtr: 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;
|
const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
|
||||||
return switch (form_value.*) {
|
return switch (form_value.*) {
|
||||||
FormValue.String => |value| value,
|
FormValue.String => |value| value,
|
||||||
FormValue.StrPtr => |offset| di.getString(offset),
|
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),
|
FormValue.LineStrPtr => |offset| di.getLineString(offset),
|
||||||
else => error.InvalidDebugInfo,
|
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.string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
|
||||||
FORM.strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
|
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.line_strp => FormValue{ .LineStrPtr = try readAddress(in_stream, endian, is_64) },
|
||||||
FORM.indirect => {
|
FORM.indirect => {
|
||||||
const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
|
const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
|
||||||
@ -554,6 +563,7 @@ pub const DwarfInfo = struct {
|
|||||||
debug_info: []const u8,
|
debug_info: []const u8,
|
||||||
debug_abbrev: []const u8,
|
debug_abbrev: []const u8,
|
||||||
debug_str: []const u8,
|
debug_str: []const u8,
|
||||||
|
debug_str_offsets: ?[]const u8,
|
||||||
debug_line: []const u8,
|
debug_line: []const u8,
|
||||||
debug_line_str: ?[]const u8,
|
debug_line_str: ?[]const u8,
|
||||||
debug_ranges: ?[]const u8,
|
debug_ranges: ?[]const u8,
|
||||||
@ -652,7 +662,7 @@ pub const DwarfInfo = struct {
|
|||||||
// Prevent endless loops
|
// Prevent endless loops
|
||||||
while (depth > 0) : (depth -= 1) {
|
while (depth > 0) : (depth -= 1) {
|
||||||
if (this_die_obj.getAttr(AT.name)) |_| {
|
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);
|
break :x try allocator.dupe(u8, name);
|
||||||
} else if (this_die_obj.getAttr(AT.abstract_origin)) |_| {
|
} else if (this_die_obj.getAttr(AT.abstract_origin)) |_| {
|
||||||
// Follow the DIE it points to and repeat
|
// Follow the DIE it points to and repeat
|
||||||
@ -956,7 +966,7 @@ pub const DwarfInfo = struct {
|
|||||||
const in = &stream.reader();
|
const in = &stream.reader();
|
||||||
const seekable = &stream.seekableStream();
|
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);
|
const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list);
|
||||||
|
|
||||||
try seekable.seekTo(line_info_offset);
|
try seekable.seekTo(line_info_offset);
|
||||||
@ -1144,6 +1154,20 @@ pub const DwarfInfo = struct {
|
|||||||
return error.InvalidDebugInfo;
|
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 {
|
fn getLineString(di: *DwarfInfo, offset: u64) ![]const u8 {
|
||||||
const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo;
|
const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo;
|
||||||
if (offset > debug_line_str.len)
|
if (offset > debug_line_str.len)
|
||||||
|
|||||||
@ -5861,8 +5861,9 @@ pub fn generateSymbolStabs(
|
|||||||
},
|
},
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
const tu_name = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.name);
|
|
||||||
const tu_comp_dir = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.comp_dir);
|
const tu_name = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.name, compile_unit.is_64);
|
||||||
|
const tu_comp_dir = try compile_unit.die.getAttrString(&debug_info, dwarf.AT.comp_dir, compile_unit.is_64);
|
||||||
|
|
||||||
// Open scope
|
// Open scope
|
||||||
try locals.ensureUnusedCapacity(3);
|
try locals.ensureUnusedCapacity(3);
|
||||||
|
|||||||
@ -580,6 +580,7 @@ pub fn parseDwarfInfo(self: Object) error{Overflow}!dwarf.DwarfInfo {
|
|||||||
.debug_info = &[0]u8{},
|
.debug_info = &[0]u8{},
|
||||||
.debug_abbrev = &[0]u8{},
|
.debug_abbrev = &[0]u8{},
|
||||||
.debug_str = &[0]u8{},
|
.debug_str = &[0]u8{},
|
||||||
|
.debug_str_offsets = null,
|
||||||
.debug_line = &[0]u8{},
|
.debug_line = &[0]u8{},
|
||||||
.debug_line_str = &[0]u8{},
|
.debug_line_str = &[0]u8{},
|
||||||
.debug_ranges = &[0]u8{},
|
.debug_ranges = &[0]u8{},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user