mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.dwarf: implement basic DWARF 5 parsing
DWARF 5 moves around some fields and adds a few new ones that can't be parsed or ignored by our current DWARF 4 parser. This isn't a complete implementation of DWARF 5, but this is enough to make stack traces mostly work. Line numbers from C++ don't show up, but I know the info is there. I think the answer is to iterate through .debug_line_str in getLineNumberInfo, but I didn't want to fall into an even deeper rabbit hole tonight.
This commit is contained in:
parent
47e004d975
commit
6de8b4bc3d
9 changed files with 309 additions and 126 deletions
|
|
@ -797,6 +797,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo
|
|||
const debug_abbrev_data = di.coff.getSectionData(".debug_abbrev", allocator) catch null;
|
||||
const debug_str_data = di.coff.getSectionData(".debug_str", allocator) catch null;
|
||||
const debug_line_data = di.coff.getSectionData(".debug_line", allocator) catch null;
|
||||
const debug_line_str_data = di.coff.getSectionData(".debug_line_str", allocator) catch null;
|
||||
const debug_ranges_data = di.coff.getSectionData(".debug_ranges", allocator) catch null;
|
||||
|
||||
var dwarf = DW.DwarfInfo{
|
||||
|
|
@ -805,6 +806,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo
|
|||
.debug_abbrev = debug_abbrev_data orelse return error.MissingDebugInfo,
|
||||
.debug_str = debug_str_data orelse return error.MissingDebugInfo,
|
||||
.debug_line = debug_line_data orelse return error.MissingDebugInfo,
|
||||
.debug_line_str = debug_line_str_data,
|
||||
.debug_ranges = debug_ranges_data,
|
||||
};
|
||||
try DW.openDwarfDebugInfo(&dwarf, allocator);
|
||||
|
|
@ -871,6 +873,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
|
|||
var opt_debug_abbrev: ?[]const u8 = null;
|
||||
var opt_debug_str: ?[]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;
|
||||
|
||||
for (shdrs) |*shdr| {
|
||||
|
|
@ -885,6 +888,8 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
|
|||
opt_debug_str = 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")) {
|
||||
opt_debug_line_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
|
||||
} else if (mem.eql(u8, name, ".debug_ranges")) {
|
||||
opt_debug_ranges = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size);
|
||||
}
|
||||
|
|
@ -896,6 +901,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn
|
|||
.debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo,
|
||||
.debug_str = opt_debug_str orelse return error.MissingDebugInfo,
|
||||
.debug_line = opt_debug_line orelse return error.MissingDebugInfo,
|
||||
.debug_line_str = opt_debug_line_str,
|
||||
.debug_ranges = opt_debug_ranges,
|
||||
};
|
||||
|
||||
|
|
@ -1434,6 +1440,7 @@ pub const ModuleDebugInfo = switch (native_os) {
|
|||
var opt_debug_info: ?*const macho.section_64 = null;
|
||||
var opt_debug_abbrev: ?*const macho.section_64 = null;
|
||||
var opt_debug_str: ?*const macho.section_64 = null;
|
||||
var opt_debug_line_str: ?*const macho.section_64 = null;
|
||||
var opt_debug_ranges: ?*const macho.section_64 = null;
|
||||
|
||||
const sections = @ptrCast(
|
||||
|
|
@ -1456,6 +1463,8 @@ pub const ModuleDebugInfo = switch (native_os) {
|
|||
opt_debug_abbrev = sect;
|
||||
} else if (mem.eql(u8, name, "__debug_str")) {
|
||||
opt_debug_str = sect;
|
||||
} else if (mem.eql(u8, name, "__debug_line_str")) {
|
||||
opt_debug_line_str = sect;
|
||||
} else if (mem.eql(u8, name, "__debug_ranges")) {
|
||||
opt_debug_ranges = sect;
|
||||
}
|
||||
|
|
@ -1476,6 +1485,10 @@ pub const ModuleDebugInfo = switch (native_os) {
|
|||
.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_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)
|
||||
else
|
||||
null,
|
||||
.debug_ranges = if (opt_debug_ranges) |debug_ranges|
|
||||
try chopSlice(mapped_mem, debug_ranges.offset, debug_ranges.size)
|
||||
else
|
||||
|
|
|
|||
|
|
@ -11,87 +11,20 @@ const ArrayList = std.ArrayList;
|
|||
pub const TAG = @import("dwarf/TAG.zig");
|
||||
pub const AT = @import("dwarf/AT.zig");
|
||||
pub const OP = @import("dwarf/OP.zig");
|
||||
pub const LANG = @import("dwarf/LANG.zig");
|
||||
pub const FORM = @import("dwarf/FORM.zig");
|
||||
pub const ATE = @import("dwarf/ATE.zig");
|
||||
|
||||
pub const FORM = struct {
|
||||
pub const addr = 0x01;
|
||||
pub const block2 = 0x03;
|
||||
pub const block4 = 0x04;
|
||||
pub const data2 = 0x05;
|
||||
pub const data4 = 0x06;
|
||||
pub const data8 = 0x07;
|
||||
pub const string = 0x08;
|
||||
pub const block = 0x09;
|
||||
pub const block1 = 0x0a;
|
||||
pub const data1 = 0x0b;
|
||||
pub const flag = 0x0c;
|
||||
pub const sdata = 0x0d;
|
||||
pub const strp = 0x0e;
|
||||
pub const udata = 0x0f;
|
||||
pub const ref_addr = 0x10;
|
||||
pub const ref1 = 0x11;
|
||||
pub const ref2 = 0x12;
|
||||
pub const ref4 = 0x13;
|
||||
pub const ref8 = 0x14;
|
||||
pub const ref_udata = 0x15;
|
||||
pub const indirect = 0x16;
|
||||
pub const sec_offset = 0x17;
|
||||
pub const exprloc = 0x18;
|
||||
pub const flag_present = 0x19;
|
||||
pub const ref_sig8 = 0x20;
|
||||
|
||||
// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
|
||||
pub const GNU_addr_index = 0x1f01;
|
||||
pub const GNU_str_index = 0x1f02;
|
||||
|
||||
// Extensions for DWZ multifile.
|
||||
// See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open .
|
||||
pub const GNU_ref_alt = 0x1f20;
|
||||
pub const GNU_strp_alt = 0x1f21;
|
||||
};
|
||||
|
||||
pub const ATE = struct {
|
||||
pub const @"void" = 0x0;
|
||||
pub const address = 0x1;
|
||||
pub const boolean = 0x2;
|
||||
pub const complex_float = 0x3;
|
||||
pub const float = 0x4;
|
||||
pub const signed = 0x5;
|
||||
pub const signed_char = 0x6;
|
||||
pub const unsigned = 0x7;
|
||||
pub const unsigned_char = 0x8;
|
||||
|
||||
// DWARF 3.
|
||||
pub const imaginary_float = 0x9;
|
||||
pub const packed_decimal = 0xa;
|
||||
pub const numeric_string = 0xb;
|
||||
pub const edited = 0xc;
|
||||
pub const signed_fixed = 0xd;
|
||||
pub const unsigned_fixed = 0xe;
|
||||
pub const decimal_float = 0xf;
|
||||
|
||||
// DWARF 4.
|
||||
pub const UTF = 0x10;
|
||||
|
||||
pub const lo_user = 0x80;
|
||||
pub const hi_user = 0xff;
|
||||
|
||||
// HP extensions.
|
||||
pub const HP_float80 = 0x80; // Floating-point (80 bit).
|
||||
pub const HP_complex_float80 = 0x81; // Complex floating-point (80 bit).
|
||||
pub const HP_float128 = 0x82; // Floating-point (128 bit).
|
||||
pub const HP_complex_float128 = 0x83; // Complex fp (128 bit).
|
||||
pub const HP_floathpintel = 0x84; // Floating-point (82 bit IA64).
|
||||
pub const HP_imaginary_float80 = 0x85;
|
||||
pub const HP_imaginary_float128 = 0x86;
|
||||
pub const HP_VAX_float = 0x88; // F or G floating.
|
||||
pub const HP_VAX_float_d = 0x89; // D floating.
|
||||
pub const HP_packed_decimal = 0x8a; // Cobol.
|
||||
pub const HP_zoned_decimal = 0x8b; // Cobol.
|
||||
pub const HP_edited = 0x8c; // Cobol.
|
||||
pub const HP_signed_fixed = 0x8d; // Cobol.
|
||||
pub const HP_unsigned_fixed = 0x8e; // Cobol.
|
||||
pub const HP_VAX_complex_float = 0x8f; // F or G floating complex.
|
||||
pub const HP_VAX_complex_float_d = 0x90; // D floating complex.
|
||||
pub const LLE = struct {
|
||||
pub const end_of_list = 0x00;
|
||||
pub const base_addressx = 0x01;
|
||||
pub const startx_endx = 0x02;
|
||||
pub const startx_length = 0x03;
|
||||
pub const offset_pair = 0x04;
|
||||
pub const default_location = 0x05;
|
||||
pub const base_address = 0x06;
|
||||
pub const start_end = 0x07;
|
||||
pub const start_length = 0x08;
|
||||
};
|
||||
|
||||
pub const CFA = struct {
|
||||
|
|
@ -166,45 +99,6 @@ pub const LNE = struct {
|
|||
pub const hi_user = 0xff;
|
||||
};
|
||||
|
||||
pub const LANG = struct {
|
||||
pub const C89 = 0x0001;
|
||||
pub const C = 0x0002;
|
||||
pub const Ada83 = 0x0003;
|
||||
pub const C_plus_plus = 0x0004;
|
||||
pub const Cobol74 = 0x0005;
|
||||
pub const Cobol85 = 0x0006;
|
||||
pub const Fortran77 = 0x0007;
|
||||
pub const Fortran90 = 0x0008;
|
||||
pub const Pascal83 = 0x0009;
|
||||
pub const Modula2 = 0x000a;
|
||||
pub const Java = 0x000b;
|
||||
pub const C99 = 0x000c;
|
||||
pub const Ada95 = 0x000d;
|
||||
pub const Fortran95 = 0x000e;
|
||||
pub const PLI = 0x000f;
|
||||
pub const ObjC = 0x0010;
|
||||
pub const ObjC_plus_plus = 0x0011;
|
||||
pub const UPC = 0x0012;
|
||||
pub const D = 0x0013;
|
||||
pub const Python = 0x0014;
|
||||
pub const Go = 0x0016;
|
||||
pub const C_plus_plus_11 = 0x001a;
|
||||
pub const Rust = 0x001c;
|
||||
pub const C11 = 0x001d;
|
||||
pub const C_plus_plus_14 = 0x0021;
|
||||
pub const Fortran03 = 0x0022;
|
||||
pub const Fortran08 = 0x0023;
|
||||
pub const lo_user = 0x8000;
|
||||
pub const hi_user = 0xffff;
|
||||
pub const Mips_Assembler = 0x8001;
|
||||
pub const Upc = 0x8765;
|
||||
pub const HP_Bliss = 0x8003;
|
||||
pub const HP_Basic91 = 0x8004;
|
||||
pub const HP_Pascal91 = 0x8005;
|
||||
pub const HP_IMacro = 0x8006;
|
||||
pub const HP_Assembler = 0x8007;
|
||||
};
|
||||
|
||||
pub const UT = struct {
|
||||
pub const compile = 0x01;
|
||||
pub const @"type" = 0x02;
|
||||
|
|
@ -212,6 +106,7 @@ pub const UT = struct {
|
|||
pub const skeleton = 0x04;
|
||||
pub const split_compile = 0x05;
|
||||
pub const split_type = 0x06;
|
||||
|
||||
pub const lo_user = 0x80;
|
||||
pub const hi_user = 0xff;
|
||||
};
|
||||
|
|
@ -222,10 +117,22 @@ pub const LNCT = struct {
|
|||
pub const timestamp = 0x3;
|
||||
pub const size = 0x4;
|
||||
pub const MD5 = 0x5;
|
||||
|
||||
pub const lo_user = 0x2000;
|
||||
pub const hi_user = 0x3fff;
|
||||
};
|
||||
|
||||
pub const RLE = struct {
|
||||
pub const end_of_list = 0x00;
|
||||
pub const base_addressx = 0x01;
|
||||
pub const startx_endx = 0x02;
|
||||
pub const startx_length = 0x03;
|
||||
pub const offset_pair = 0x04;
|
||||
pub const base_address = 0x05;
|
||||
pub const start_end = 0x06;
|
||||
pub const start_length = 0x07;
|
||||
};
|
||||
|
||||
pub const CC = enum(u8) {
|
||||
normal = 0x1,
|
||||
program = 0x2,
|
||||
|
|
@ -276,6 +183,8 @@ const AbbrevTableEntry = struct {
|
|||
const AbbrevAttr = struct {
|
||||
attr_id: u64,
|
||||
form_id: u64,
|
||||
/// Only valid if form_id is .implicit_const
|
||||
payload: i64,
|
||||
};
|
||||
|
||||
const FormValue = union(enum) {
|
||||
|
|
@ -289,6 +198,7 @@ const FormValue = union(enum) {
|
|||
RefAddr: u64,
|
||||
String: []const u8,
|
||||
StrPtr: u64,
|
||||
LineStrPtr: u64,
|
||||
};
|
||||
|
||||
const Constant = struct {
|
||||
|
|
@ -356,6 +266,7 @@ const Die = struct {
|
|||
return switch (form_value.*) {
|
||||
FormValue.String => |value| value,
|
||||
FormValue.StrPtr => |offset| di.getString(offset),
|
||||
FormValue.LineStrPtr => |offset| di.getLineString(offset),
|
||||
else => error.InvalidDebugInfo,
|
||||
};
|
||||
}
|
||||
|
|
@ -588,6 +499,7 @@ 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.line_strp => FormValue{ .LineStrPtr = try readAddress(in_stream, endian, is_64) },
|
||||
FORM.indirect => {
|
||||
const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
|
||||
const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));
|
||||
|
|
@ -595,7 +507,12 @@ fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, en
|
|||
defer allocator.destroy(frame);
|
||||
return await @asyncCall(frame, {}, parseFormValue, .{ allocator, in_stream, child_form_id, endian, is_64 });
|
||||
},
|
||||
else => error.InvalidDebugInfo,
|
||||
FORM.implicit_const => FormValue{ .Const = Constant{ .signed = true, .payload = undefined } },
|
||||
|
||||
else => {
|
||||
std.debug.print("dwarf: unhandled form_id: 0x{x}\n", .{form_id});
|
||||
return error.InvalidDebugInfo;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -613,6 +530,7 @@ pub const DwarfInfo = struct {
|
|||
debug_abbrev: []const u8,
|
||||
debug_str: []const u8,
|
||||
debug_line: []const u8,
|
||||
debug_line_str: ?[]const u8,
|
||||
debug_ranges: ?[]const u8,
|
||||
// Filled later by the initializer
|
||||
abbrev_table_list: ArrayList(AbbrevTableHeader) = undefined,
|
||||
|
|
@ -652,9 +570,20 @@ pub const DwarfInfo = struct {
|
|||
const version = try in.readInt(u16, di.endian);
|
||||
if (version < 2 or version > 5) return error.InvalidDebugInfo;
|
||||
|
||||
const debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian);
|
||||
|
||||
const address_size = try in.readByte();
|
||||
var address_size: u8 = undefined;
|
||||
var debug_abbrev_offset: u64 = undefined;
|
||||
switch (version) {
|
||||
5 => {
|
||||
const unit_type = try in.readInt(u8, di.endian);
|
||||
if (unit_type != UT.compile) return error.InvalidDebugInfo;
|
||||
address_size = try in.readByte();
|
||||
debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian);
|
||||
},
|
||||
else => {
|
||||
debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian);
|
||||
address_size = try in.readByte();
|
||||
},
|
||||
}
|
||||
if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
|
||||
|
||||
const compile_unit_pos = try seekable.getPos();
|
||||
|
|
@ -756,9 +685,20 @@ pub const DwarfInfo = struct {
|
|||
const version = try in.readInt(u16, di.endian);
|
||||
if (version < 2 or version > 5) return error.InvalidDebugInfo;
|
||||
|
||||
const debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian);
|
||||
|
||||
const address_size = try in.readByte();
|
||||
var address_size: u8 = undefined;
|
||||
var debug_abbrev_offset: u64 = undefined;
|
||||
switch (version) {
|
||||
5 => {
|
||||
const unit_type = try in.readInt(u8, di.endian);
|
||||
if (unit_type != UT.compile) return error.InvalidDebugInfo;
|
||||
address_size = try in.readByte();
|
||||
debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian);
|
||||
},
|
||||
else => {
|
||||
debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian);
|
||||
address_size = try in.readByte();
|
||||
},
|
||||
}
|
||||
if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
|
||||
|
||||
const compile_unit_pos = try seekable.getPos();
|
||||
|
|
@ -890,9 +830,12 @@ pub const DwarfInfo = struct {
|
|||
const attr_id = try leb.readULEB128(u64, in);
|
||||
const form_id = try leb.readULEB128(u64, in);
|
||||
if (attr_id == 0 and form_id == 0) break;
|
||||
// DW_FORM_implicit_const stores its value immediately after the attribute pair :(
|
||||
const payload = if (form_id == FORM.implicit_const) try leb.readILEB128(i64, in) else undefined;
|
||||
try attrs.append(AbbrevAttr{
|
||||
.attr_id = attr_id,
|
||||
.form_id = form_id,
|
||||
.payload = payload,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -914,6 +857,9 @@ pub const DwarfInfo = struct {
|
|||
.id = attr.attr_id,
|
||||
.value = try parseFormValue(di.allocator(), in_stream, attr.form_id, di.endian, is_64),
|
||||
};
|
||||
if (attr.form_id == FORM.implicit_const) {
|
||||
result.attrs.items[i].value.Const.payload = @bitCast(u64, attr.payload);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1101,6 +1047,21 @@ pub const DwarfInfo = struct {
|
|||
|
||||
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)
|
||||
return error.InvalidDebugInfo;
|
||||
const casted_offset = math.cast(usize, offset) catch
|
||||
return error.InvalidDebugInfo;
|
||||
|
||||
// Valid strings always have a terminating zero byte
|
||||
if (mem.indexOfScalarPos(u8, debug_line_str, casted_offset, 0)) |last| {
|
||||
return debug_line_str[casted_offset..last];
|
||||
}
|
||||
|
||||
return error.InvalidDebugInfo;
|
||||
}
|
||||
};
|
||||
|
||||
/// Initialize DWARF info. The caller has the responsibility to initialize most
|
||||
|
|
|
|||
|
|
@ -99,7 +99,35 @@ pub const enum_class = 0x6d;
|
|||
pub const linkage_name = 0x6e;
|
||||
|
||||
// DWARF 5
|
||||
pub const string_length_bit_size = 0x6f;
|
||||
pub const string_length_byte_size = 0x70;
|
||||
pub const rank = 0x71;
|
||||
pub const str_offsets_base = 0x72;
|
||||
pub const addr_base = 0x73;
|
||||
pub const rnglists_base = 0x74;
|
||||
pub const dwo_name = 0x76;
|
||||
pub const reference = 0x77;
|
||||
pub const rvalue_reference = 0x78;
|
||||
pub const macros = 0x79;
|
||||
pub const call_all_calls = 0x7a;
|
||||
pub const call_all_source_calls = 0x7b;
|
||||
pub const call_all_tail_calls = 0x7c;
|
||||
pub const call_return_pc = 0x7d;
|
||||
pub const call_value = 0x7e;
|
||||
pub const call_origin = 0x7f;
|
||||
pub const call_parameter = 0x80;
|
||||
pub const call_pc = 0x81;
|
||||
pub const call_tail_call = 0x82;
|
||||
pub const call_target = 0x83;
|
||||
pub const call_target_clobbered = 0x84;
|
||||
pub const call_data_location = 0x85;
|
||||
pub const call_data_value = 0x86;
|
||||
pub const @"noreturn" = 0x87;
|
||||
pub const alignment = 0x88;
|
||||
pub const export_symbols = 0x89;
|
||||
pub const deleted = 0x8a;
|
||||
pub const defaulted = 0x8b;
|
||||
pub const loclists_base = 0x8c;
|
||||
|
||||
pub const lo_user = 0x2000; // Implementation-defined range start.
|
||||
pub const hi_user = 0x3fff; // Implementation-defined range end.
|
||||
|
|
|
|||
46
lib/std/dwarf/ATE.zig
Normal file
46
lib/std/dwarf/ATE.zig
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
pub const @"void" = 0x0;
|
||||
pub const address = 0x1;
|
||||
pub const boolean = 0x2;
|
||||
pub const complex_float = 0x3;
|
||||
pub const float = 0x4;
|
||||
pub const signed = 0x5;
|
||||
pub const signed_char = 0x6;
|
||||
pub const unsigned = 0x7;
|
||||
pub const unsigned_char = 0x8;
|
||||
|
||||
// DWARF 3.
|
||||
pub const imaginary_float = 0x9;
|
||||
pub const packed_decimal = 0xa;
|
||||
pub const numeric_string = 0xb;
|
||||
pub const edited = 0xc;
|
||||
pub const signed_fixed = 0xd;
|
||||
pub const unsigned_fixed = 0xe;
|
||||
pub const decimal_float = 0xf;
|
||||
|
||||
// DWARF 4.
|
||||
pub const UTF = 0x10;
|
||||
|
||||
// DWARF 5.
|
||||
pub const UCS = 0x11;
|
||||
pub const ASCII = 0x12;
|
||||
|
||||
pub const lo_user = 0x80;
|
||||
pub const hi_user = 0xff;
|
||||
|
||||
// HP extensions.
|
||||
pub const HP_float80 = 0x80; // Floating-point (80 bit).
|
||||
pub const HP_complex_float80 = 0x81; // Complex floating-point (80 bit).
|
||||
pub const HP_float128 = 0x82; // Floating-point (128 bit).
|
||||
pub const HP_complex_float128 = 0x83; // Complex fp (128 bit).
|
||||
pub const HP_floathpintel = 0x84; // Floating-point (82 bit IA64).
|
||||
pub const HP_imaginary_float80 = 0x85;
|
||||
pub const HP_imaginary_float128 = 0x86;
|
||||
pub const HP_VAX_float = 0x88; // F or G floating.
|
||||
pub const HP_VAX_float_d = 0x89; // D floating.
|
||||
pub const HP_packed_decimal = 0x8a; // Cobol.
|
||||
pub const HP_zoned_decimal = 0x8b; // Cobol.
|
||||
pub const HP_edited = 0x8c; // Cobol.
|
||||
pub const HP_signed_fixed = 0x8d; // Cobol.
|
||||
pub const HP_unsigned_fixed = 0x8e; // Cobol.
|
||||
pub const HP_VAX_complex_float = 0x8f; // F or G floating complex.
|
||||
pub const HP_VAX_complex_float_d = 0x90; // D floating complex.
|
||||
52
lib/std/dwarf/FORM.zig
Normal file
52
lib/std/dwarf/FORM.zig
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
pub const addr = 0x01;
|
||||
pub const block2 = 0x03;
|
||||
pub const block4 = 0x04;
|
||||
pub const data2 = 0x05;
|
||||
pub const data4 = 0x06;
|
||||
pub const data8 = 0x07;
|
||||
pub const string = 0x08;
|
||||
pub const block = 0x09;
|
||||
pub const block1 = 0x0a;
|
||||
pub const data1 = 0x0b;
|
||||
pub const flag = 0x0c;
|
||||
pub const sdata = 0x0d;
|
||||
pub const strp = 0x0e;
|
||||
pub const udata = 0x0f;
|
||||
pub const ref_addr = 0x10;
|
||||
pub const ref1 = 0x11;
|
||||
pub const ref2 = 0x12;
|
||||
pub const ref4 = 0x13;
|
||||
pub const ref8 = 0x14;
|
||||
pub const ref_udata = 0x15;
|
||||
pub const indirect = 0x16;
|
||||
pub const sec_offset = 0x17;
|
||||
pub const exprloc = 0x18;
|
||||
pub const flag_present = 0x19;
|
||||
pub const strx = 0x1a;
|
||||
pub const addrx = 0x1b;
|
||||
pub const ref_sup4 = 0x1c;
|
||||
pub const strp_sup = 0x1d;
|
||||
pub const data16 = 0x1e;
|
||||
pub const line_strp = 0x1f;
|
||||
pub const ref_sig8 = 0x20;
|
||||
pub const implicit_const = 0x21;
|
||||
pub const loclistx = 0x22;
|
||||
pub const rnglistx = 0x23;
|
||||
pub const ref_sup8 = 0x24;
|
||||
pub const strx1 = 0x25;
|
||||
pub const strx2 = 0x26;
|
||||
pub const strx3 = 0x27;
|
||||
pub const strx4 = 0x28;
|
||||
pub const addrx1 = 0x29;
|
||||
pub const addrx2 = 0x2a;
|
||||
pub const addrx3 = 0x2b;
|
||||
pub const addrx4 = 0x2c;
|
||||
|
||||
// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
|
||||
pub const GNU_addr_index = 0x1f01;
|
||||
pub const GNU_str_index = 0x1f02;
|
||||
|
||||
// Extensions for DWZ multifile.
|
||||
// See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open .
|
||||
pub const GNU_ref_alt = 0x1f20;
|
||||
pub const GNU_strp_alt = 0x1f21;
|
||||
48
lib/std/dwarf/LANG.zig
Normal file
48
lib/std/dwarf/LANG.zig
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
pub const C89 = 0x0001;
|
||||
pub const C = 0x0002;
|
||||
pub const Ada83 = 0x0003;
|
||||
pub const C_plus_plus = 0x0004;
|
||||
pub const Cobol74 = 0x0005;
|
||||
pub const Cobol85 = 0x0006;
|
||||
pub const Fortran77 = 0x0007;
|
||||
pub const Fortran90 = 0x0008;
|
||||
pub const Pascal83 = 0x0009;
|
||||
pub const Modula2 = 0x000a;
|
||||
pub const Java = 0x000b;
|
||||
pub const C99 = 0x000c;
|
||||
pub const Ada95 = 0x000d;
|
||||
pub const Fortran95 = 0x000e;
|
||||
pub const PLI = 0x000f;
|
||||
pub const ObjC = 0x0010;
|
||||
pub const ObjC_plus_plus = 0x0011;
|
||||
pub const UPC = 0x0012;
|
||||
pub const D = 0x0013;
|
||||
pub const Python = 0x0014;
|
||||
pub const OpenCL = 0x0015;
|
||||
pub const Go = 0x0016;
|
||||
pub const Modula3 = 0x0017;
|
||||
pub const Haskell = 0x0018;
|
||||
pub const C_plus_plus_03 = 0x0019;
|
||||
pub const C_plus_plus_11 = 0x001a;
|
||||
pub const OCaml = 0x001b;
|
||||
pub const Rust = 0x001c;
|
||||
pub const C11 = 0x001d;
|
||||
pub const Swift = 0x001e;
|
||||
pub const Julia = 0x001f;
|
||||
pub const Dylan = 0x0020;
|
||||
pub const C_plus_plus_14 = 0x0021;
|
||||
pub const Fortran03 = 0x0022;
|
||||
pub const Fortran08 = 0x0023;
|
||||
pub const RenderScript = 0x0024;
|
||||
pub const BLISS = 0x0025;
|
||||
|
||||
pub const lo_user = 0x8000;
|
||||
pub const hi_user = 0xffff;
|
||||
|
||||
pub const Mips_Assembler = 0x8001;
|
||||
pub const Upc = 0x8765;
|
||||
pub const HP_Bliss = 0x8003;
|
||||
pub const HP_Basic91 = 0x8004;
|
||||
pub const HP_Pascal91 = 0x8005;
|
||||
pub const HP_IMacro = 0x8006;
|
||||
pub const HP_Assembler = 0x8007;
|
||||
|
|
@ -157,6 +157,18 @@ pub const bit_piece = 0x9d;
|
|||
pub const implicit_value = 0x9e;
|
||||
pub const stack_value = 0x9f;
|
||||
|
||||
// DWARF 5 extensions.
|
||||
pub const implicit_pointer = 0xa0;
|
||||
pub const addrx = 0xa1;
|
||||
pub const constx = 0xa2;
|
||||
pub const entry_value = 0xa3;
|
||||
pub const const_type = 0xa4;
|
||||
pub const regval_type = 0xa5;
|
||||
pub const deref_type = 0xa6;
|
||||
pub const xderef_type = 0xa7;
|
||||
pub const convert = 0xa8;
|
||||
pub const reinterpret = 0xa9;
|
||||
|
||||
pub const lo_user = 0xe0; // Implementation-defined range start.
|
||||
pub const hi_user = 0xff; // Implementation-defined range end.
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,16 @@ pub const type_unit = 0x41;
|
|||
pub const rvalue_reference_type = 0x42;
|
||||
pub const template_alias = 0x43;
|
||||
|
||||
// DWARF 5
|
||||
pub const coarray_type = 0x44;
|
||||
pub const generic_subrange = 0x45;
|
||||
pub const dynamic_type = 0x46;
|
||||
pub const atomic_type = 0x47;
|
||||
pub const call_site = 0x48;
|
||||
pub const call_site_parameter = 0x49;
|
||||
pub const skeleton_unit = 0x4a;
|
||||
pub const immutable_type = 0x4b;
|
||||
|
||||
pub const lo_user = 0x4080;
|
||||
pub const hi_user = 0xffff;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ dwarf_debug_info_index: ?u16 = null,
|
|||
dwarf_debug_abbrev_index: ?u16 = null,
|
||||
dwarf_debug_str_index: ?u16 = null,
|
||||
dwarf_debug_line_index: ?u16 = null,
|
||||
dwarf_debug_line_str_index: ?u16 = null,
|
||||
dwarf_debug_ranges_index: ?u16 = null,
|
||||
|
||||
symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{},
|
||||
|
|
@ -68,6 +69,7 @@ const DebugInfo = struct {
|
|||
debug_abbrev: []u8,
|
||||
debug_str: []u8,
|
||||
debug_line: []u8,
|
||||
debug_line_str: []u8,
|
||||
debug_ranges: []u8,
|
||||
|
||||
pub fn parseFromObject(allocator: Allocator, object: *const Object) !?DebugInfo {
|
||||
|
|
@ -87,6 +89,12 @@ const DebugInfo = struct {
|
|||
const index = object.dwarf_debug_line_index orelse return null;
|
||||
break :blk try object.readSection(allocator, index);
|
||||
};
|
||||
var debug_line_str = blk: {
|
||||
if (object.dwarf_debug_line_str_index) |ind| {
|
||||
break :blk try object.readSection(allocator, ind);
|
||||
}
|
||||
break :blk try allocator.alloc(u8, 0);
|
||||
};
|
||||
var debug_ranges = blk: {
|
||||
if (object.dwarf_debug_ranges_index) |ind| {
|
||||
break :blk try object.readSection(allocator, ind);
|
||||
|
|
@ -100,6 +108,7 @@ const DebugInfo = struct {
|
|||
.debug_abbrev = debug_abbrev,
|
||||
.debug_str = debug_str,
|
||||
.debug_line = debug_line,
|
||||
.debug_line_str = debug_line_str,
|
||||
.debug_ranges = debug_ranges,
|
||||
};
|
||||
try dwarf.openDwarfDebugInfo(&inner, allocator);
|
||||
|
|
@ -110,6 +119,7 @@ const DebugInfo = struct {
|
|||
.debug_abbrev = debug_abbrev,
|
||||
.debug_str = debug_str,
|
||||
.debug_line = debug_line,
|
||||
.debug_line_str = debug_line_str,
|
||||
.debug_ranges = debug_ranges,
|
||||
};
|
||||
}
|
||||
|
|
@ -119,6 +129,7 @@ const DebugInfo = struct {
|
|||
allocator.free(self.debug_abbrev);
|
||||
allocator.free(self.debug_str);
|
||||
allocator.free(self.debug_line);
|
||||
allocator.free(self.debug_line_str);
|
||||
allocator.free(self.debug_ranges);
|
||||
self.inner.abbrev_table_list.deinit();
|
||||
self.inner.compile_unit_list.deinit();
|
||||
|
|
@ -285,6 +296,8 @@ pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !v
|
|||
self.dwarf_debug_str_index = index;
|
||||
} else if (mem.eql(u8, sectname, "__debug_line")) {
|
||||
self.dwarf_debug_line_index = index;
|
||||
} else if (mem.eql(u8, sectname, "__debug_line_str")) {
|
||||
self.dwarf_debug_line_str_index = index;
|
||||
} else if (mem.eql(u8, sectname, "__debug_ranges")) {
|
||||
self.dwarf_debug_ranges_index = index;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue