| author | |
| committer | |
| log | 6de8b4bc3d105c15cd473c5bf100db4c9328dd54 |
| tree | 6f15f1b038b04aaf50ed03d7663c7e54d255a9b4 |
| parent | 47e004d975669fea1297224e33a868742178c4b4 |
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.9 files changed, 310 insertions(+), 127 deletions(-)
lib/std/debug.zig+13| ... | @@ -797,6 +797,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo | ... | @@ -797,6 +797,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo |
| 797 | const debug_abbrev_data = di.coff.getSectionData(".debug_abbrev", allocator) catch null; | 797 | const debug_abbrev_data = di.coff.getSectionData(".debug_abbrev", allocator) catch null; |
| 798 | const debug_str_data = di.coff.getSectionData(".debug_str", allocator) catch null; | 798 | const debug_str_data = di.coff.getSectionData(".debug_str", allocator) catch null; |
| 799 | const debug_line_data = di.coff.getSectionData(".debug_line", allocator) catch null; | 799 | const debug_line_data = di.coff.getSectionData(".debug_line", allocator) catch null; |
| 800 | const debug_line_str_data = di.coff.getSectionData(".debug_line_str", allocator) catch null; | ||
| 800 | const debug_ranges_data = di.coff.getSectionData(".debug_ranges", allocator) catch null; | 801 | const debug_ranges_data = di.coff.getSectionData(".debug_ranges", allocator) catch null; |
| 801 | 802 | ||
| 802 | var dwarf = DW.DwarfInfo{ | 803 | var dwarf = DW.DwarfInfo{ |
| ... | @@ -805,6 +806,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo | ... | @@ -805,6 +806,7 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_file: File) !ModuleDebugInfo |
| 805 | .debug_abbrev = debug_abbrev_data orelse return error.MissingDebugInfo, | 806 | .debug_abbrev = debug_abbrev_data orelse return error.MissingDebugInfo, |
| 806 | .debug_str = debug_str_data orelse return error.MissingDebugInfo, | 807 | .debug_str = debug_str_data orelse return error.MissingDebugInfo, |
| 807 | .debug_line = debug_line_data orelse return error.MissingDebugInfo, | 808 | .debug_line = debug_line_data orelse return error.MissingDebugInfo, |
| 809 | .debug_line_str = debug_line_str_data, | ||
| 808 | .debug_ranges = debug_ranges_data, | 810 | .debug_ranges = debug_ranges_data, |
| 809 | }; | 811 | }; |
| 810 | try DW.openDwarfDebugInfo(&dwarf, allocator); | 812 | try DW.openDwarfDebugInfo(&dwarf, allocator); |
| ... | @@ -871,6 +873,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn | ... | @@ -871,6 +873,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn |
| 871 | var opt_debug_abbrev: ?[]const u8 = null; | 873 | var opt_debug_abbrev: ?[]const u8 = null; |
| 872 | var opt_debug_str: ?[]const u8 = null; | 874 | var opt_debug_str: ?[]const u8 = null; |
| 873 | var opt_debug_line: ?[]const u8 = null; | 875 | var opt_debug_line: ?[]const u8 = null; |
| 876 | var opt_debug_line_str: ?[]const u8 = null; | ||
| 874 | var opt_debug_ranges: ?[]const u8 = null; | 877 | var opt_debug_ranges: ?[]const u8 = null; |
| 875 | 878 | ||
| 876 | for (shdrs) |*shdr| { | 879 | for (shdrs) |*shdr| { |
| ... | @@ -885,6 +888,8 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn | ... | @@ -885,6 +888,8 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn |
| 885 | opt_debug_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); | 888 | opt_debug_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); |
| 886 | } else if (mem.eql(u8, name, ".debug_line")) { | 889 | } else if (mem.eql(u8, name, ".debug_line")) { |
| 887 | opt_debug_line = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); | 890 | opt_debug_line = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); |
| 891 | } else if (mem.eql(u8, name, ".debug_line_str")) { | ||
| 892 | opt_debug_line_str = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); | ||
| 888 | } else if (mem.eql(u8, name, ".debug_ranges")) { | 893 | } else if (mem.eql(u8, name, ".debug_ranges")) { |
| 889 | opt_debug_ranges = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); | 894 | opt_debug_ranges = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); |
| 890 | } | 895 | } |
| ... | @@ -896,6 +901,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn | ... | @@ -896,6 +901,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn |
| 896 | .debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo, | 901 | .debug_abbrev = opt_debug_abbrev orelse return error.MissingDebugInfo, |
| 897 | .debug_str = opt_debug_str orelse return error.MissingDebugInfo, | 902 | .debug_str = opt_debug_str orelse return error.MissingDebugInfo, |
| 898 | .debug_line = opt_debug_line orelse return error.MissingDebugInfo, | 903 | .debug_line = opt_debug_line orelse return error.MissingDebugInfo, |
| 904 | .debug_line_str = opt_debug_line_str, | ||
| 899 | .debug_ranges = opt_debug_ranges, | 905 | .debug_ranges = opt_debug_ranges, |
| 900 | }; | 906 | }; |
| 901 | 907 | ||
| ... | @@ -1434,6 +1440,7 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -1434,6 +1440,7 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1434 | var opt_debug_info: ?*const macho.section_64 = null; | 1440 | var opt_debug_info: ?*const macho.section_64 = null; |
| 1435 | var opt_debug_abbrev: ?*const macho.section_64 = null; | 1441 | var opt_debug_abbrev: ?*const macho.section_64 = null; |
| 1436 | var opt_debug_str: ?*const macho.section_64 = null; | 1442 | var opt_debug_str: ?*const macho.section_64 = null; |
| 1443 | var opt_debug_line_str: ?*const macho.section_64 = null; | ||
| 1437 | var opt_debug_ranges: ?*const macho.section_64 = null; | 1444 | var opt_debug_ranges: ?*const macho.section_64 = null; |
| 1438 | 1445 | ||
| 1439 | const sections = @ptrCast( | 1446 | const sections = @ptrCast( |
| ... | @@ -1456,6 +1463,8 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -1456,6 +1463,8 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1456 | opt_debug_abbrev = sect; | 1463 | opt_debug_abbrev = sect; |
| 1457 | } else if (mem.eql(u8, name, "__debug_str")) { | 1464 | } else if (mem.eql(u8, name, "__debug_str")) { |
| 1458 | opt_debug_str = sect; | 1465 | opt_debug_str = sect; |
| 1466 | } else if (mem.eql(u8, name, "__debug_line_str")) { | ||
| 1467 | opt_debug_line_str = sect; | ||
| 1459 | } else if (mem.eql(u8, name, "__debug_ranges")) { | 1468 | } else if (mem.eql(u8, name, "__debug_ranges")) { |
| 1460 | opt_debug_ranges = sect; | 1469 | opt_debug_ranges = sect; |
| 1461 | } | 1470 | } |
| ... | @@ -1476,6 +1485,10 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -1476,6 +1485,10 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1476 | .debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.offset, debug_abbrev.size), | 1485 | .debug_abbrev = try chopSlice(mapped_mem, debug_abbrev.offset, debug_abbrev.size), |
| 1477 | .debug_str = try chopSlice(mapped_mem, debug_str.offset, debug_str.size), | 1486 | .debug_str = try chopSlice(mapped_mem, debug_str.offset, debug_str.size), |
| 1478 | .debug_line = try chopSlice(mapped_mem, debug_line.offset, debug_line.size), | 1487 | .debug_line = try chopSlice(mapped_mem, debug_line.offset, debug_line.size), |
| 1488 | .debug_line_str = if (opt_debug_line_str) |debug_line_str| | ||
| 1489 | try chopSlice(mapped_mem, debug_line_str.offset, debug_line_str.size) | ||
| 1490 | else | ||
| 1491 | null, | ||
| 1479 | .debug_ranges = if (opt_debug_ranges) |debug_ranges| | 1492 | .debug_ranges = if (opt_debug_ranges) |debug_ranges| |
| 1480 | try chopSlice(mapped_mem, debug_ranges.offset, debug_ranges.size) | 1493 | try chopSlice(mapped_mem, debug_ranges.offset, debug_ranges.size) |
| 1481 | else | 1494 | else |
lib/std/dwarf.zig+88-127| ... | @@ -11,87 +11,20 @@ const ArrayList = std.ArrayList; | ... | @@ -11,87 +11,20 @@ const ArrayList = std.ArrayList; |
| 11 | pub const TAG = @import("dwarf/TAG.zig"); | 11 | pub const TAG = @import("dwarf/TAG.zig"); |
| 12 | pub const AT = @import("dwarf/AT.zig"); | 12 | pub const AT = @import("dwarf/AT.zig"); |
| 13 | pub const OP = @import("dwarf/OP.zig"); | 13 | pub const OP = @import("dwarf/OP.zig"); |
| 14 | 14 | pub const LANG = @import("dwarf/LANG.zig"); | |
| 15 | pub const FORM = struct { | 15 | pub const FORM = @import("dwarf/FORM.zig"); |
| 16 | pub const addr = 0x01; | 16 | pub const ATE = @import("dwarf/ATE.zig"); |
| 17 | pub const block2 = 0x03; | 17 | |
| 18 | pub const block4 = 0x04; | 18 | pub const LLE = struct { |
| 19 | pub const data2 = 0x05; | 19 | pub const end_of_list = 0x00; |
| 20 | pub const data4 = 0x06; | 20 | pub const base_addressx = 0x01; |
| 21 | pub const data8 = 0x07; | 21 | pub const startx_endx = 0x02; |
| 22 | pub const string = 0x08; | 22 | pub const startx_length = 0x03; |
| 23 | pub const block = 0x09; | 23 | pub const offset_pair = 0x04; |
| 24 | pub const block1 = 0x0a; | 24 | pub const default_location = 0x05; |
| 25 | pub const data1 = 0x0b; | 25 | pub const base_address = 0x06; |
| 26 | pub const flag = 0x0c; | 26 | pub const start_end = 0x07; |
| 27 | pub const sdata = 0x0d; | 27 | pub const start_length = 0x08; |
| 28 | pub const strp = 0x0e; | ||
| 29 | pub const udata = 0x0f; | ||
| 30 | pub const ref_addr = 0x10; | ||
| 31 | pub const ref1 = 0x11; | ||
| 32 | pub const ref2 = 0x12; | ||
| 33 | pub const ref4 = 0x13; | ||
| 34 | pub const ref8 = 0x14; | ||
| 35 | pub const ref_udata = 0x15; | ||
| 36 | pub const indirect = 0x16; | ||
| 37 | pub const sec_offset = 0x17; | ||
| 38 | pub const exprloc = 0x18; | ||
| 39 | pub const flag_present = 0x19; | ||
| 40 | pub const ref_sig8 = 0x20; | ||
| 41 | |||
| 42 | // Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. | ||
| 43 | pub const GNU_addr_index = 0x1f01; | ||
| 44 | pub const GNU_str_index = 0x1f02; | ||
| 45 | |||
| 46 | // Extensions for DWZ multifile. | ||
| 47 | // See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . | ||
| 48 | pub const GNU_ref_alt = 0x1f20; | ||
| 49 | pub const GNU_strp_alt = 0x1f21; | ||
| 50 | }; | ||
| 51 | |||
| 52 | pub const ATE = struct { | ||
| 53 | pub const @"void" = 0x0; | ||
| 54 | pub const address = 0x1; | ||
| 55 | pub const boolean = 0x2; | ||
| 56 | pub const complex_float = 0x3; | ||
| 57 | pub const float = 0x4; | ||
| 58 | pub const signed = 0x5; | ||
| 59 | pub const signed_char = 0x6; | ||
| 60 | pub const unsigned = 0x7; | ||
| 61 | pub const unsigned_char = 0x8; | ||
| 62 | |||
| 63 | // DWARF 3. | ||
| 64 | pub const imaginary_float = 0x9; | ||
| 65 | pub const packed_decimal = 0xa; | ||
| 66 | pub const numeric_string = 0xb; | ||
| 67 | pub const edited = 0xc; | ||
| 68 | pub const signed_fixed = 0xd; | ||
| 69 | pub const unsigned_fixed = 0xe; | ||
| 70 | pub const decimal_float = 0xf; | ||
| 71 | |||
| 72 | // DWARF 4. | ||
| 73 | pub const UTF = 0x10; | ||
| 74 | |||
| 75 | pub const lo_user = 0x80; | ||
| 76 | pub const hi_user = 0xff; | ||
| 77 | |||
| 78 | // HP extensions. | ||
| 79 | pub const HP_float80 = 0x80; // Floating-point (80 bit). | ||
| 80 | pub const HP_complex_float80 = 0x81; // Complex floating-point (80 bit). | ||
| 81 | pub const HP_float128 = 0x82; // Floating-point (128 bit). | ||
| 82 | pub const HP_complex_float128 = 0x83; // Complex fp (128 bit). | ||
| 83 | pub const HP_floathpintel = 0x84; // Floating-point (82 bit IA64). | ||
| 84 | pub const HP_imaginary_float80 = 0x85; | ||
| 85 | pub const HP_imaginary_float128 = 0x86; | ||
| 86 | pub const HP_VAX_float = 0x88; // F or G floating. | ||
| 87 | pub const HP_VAX_float_d = 0x89; // D floating. | ||
| 88 | pub const HP_packed_decimal = 0x8a; // Cobol. | ||
| 89 | pub const HP_zoned_decimal = 0x8b; // Cobol. | ||
| 90 | pub const HP_edited = 0x8c; // Cobol. | ||
| 91 | pub const HP_signed_fixed = 0x8d; // Cobol. | ||
| 92 | pub const HP_unsigned_fixed = 0x8e; // Cobol. | ||
| 93 | pub const HP_VAX_complex_float = 0x8f; // F or G floating complex. | ||
| 94 | pub const HP_VAX_complex_float_d = 0x90; // D floating complex. | ||
| 95 | }; | 28 | }; |
| 96 | 29 | ||
| 97 | pub const CFA = struct { | 30 | pub const CFA = struct { |
| ... | @@ -166,45 +99,6 @@ pub const LNE = struct { | ... | @@ -166,45 +99,6 @@ pub const LNE = struct { |
| 166 | pub const hi_user = 0xff; | 99 | pub const hi_user = 0xff; |
| 167 | }; | 100 | }; |
| 168 | 101 | ||
| 169 | pub const LANG = struct { | ||
| 170 | pub const C89 = 0x0001; | ||
| 171 | pub const C = 0x0002; | ||
| 172 | pub const Ada83 = 0x0003; | ||
| 173 | pub const C_plus_plus = 0x0004; | ||
| 174 | pub const Cobol74 = 0x0005; | ||
| 175 | pub const Cobol85 = 0x0006; | ||
| 176 | pub const Fortran77 = 0x0007; | ||
| 177 | pub const Fortran90 = 0x0008; | ||
| 178 | pub const Pascal83 = 0x0009; | ||
| 179 | pub const Modula2 = 0x000a; | ||
| 180 | pub const Java = 0x000b; | ||
| 181 | pub const C99 = 0x000c; | ||
| 182 | pub const Ada95 = 0x000d; | ||
| 183 | pub const Fortran95 = 0x000e; | ||
| 184 | pub const PLI = 0x000f; | ||
| 185 | pub const ObjC = 0x0010; | ||
| 186 | pub const ObjC_plus_plus = 0x0011; | ||
| 187 | pub const UPC = 0x0012; | ||
| 188 | pub const D = 0x0013; | ||
| 189 | pub const Python = 0x0014; | ||
| 190 | pub const Go = 0x0016; | ||
| 191 | pub const C_plus_plus_11 = 0x001a; | ||
| 192 | pub const Rust = 0x001c; | ||
| 193 | pub const C11 = 0x001d; | ||
| 194 | pub const C_plus_plus_14 = 0x0021; | ||
| 195 | pub const Fortran03 = 0x0022; | ||
| 196 | pub const Fortran08 = 0x0023; | ||
| 197 | pub const lo_user = 0x8000; | ||
| 198 | pub const hi_user = 0xffff; | ||
| 199 | pub const Mips_Assembler = 0x8001; | ||
| 200 | pub const Upc = 0x8765; | ||
| 201 | pub const HP_Bliss = 0x8003; | ||
| 202 | pub const HP_Basic91 = 0x8004; | ||
| 203 | pub const HP_Pascal91 = 0x8005; | ||
| 204 | pub const HP_IMacro = 0x8006; | ||
| 205 | pub const HP_Assembler = 0x8007; | ||
| 206 | }; | ||
| 207 | |||
| 208 | pub const UT = struct { | 102 | pub const UT = struct { |
| 209 | pub const compile = 0x01; | 103 | pub const compile = 0x01; |
| 210 | pub const @"type" = 0x02; | 104 | pub const @"type" = 0x02; |
| ... | @@ -212,6 +106,7 @@ pub const UT = struct { | ... | @@ -212,6 +106,7 @@ pub const UT = struct { |
| 212 | pub const skeleton = 0x04; | 106 | pub const skeleton = 0x04; |
| 213 | pub const split_compile = 0x05; | 107 | pub const split_compile = 0x05; |
| 214 | pub const split_type = 0x06; | 108 | pub const split_type = 0x06; |
| 109 | |||
| 215 | pub const lo_user = 0x80; | 110 | pub const lo_user = 0x80; |
| 216 | pub const hi_user = 0xff; | 111 | pub const hi_user = 0xff; |
| 217 | }; | 112 | }; |
| ... | @@ -222,10 +117,22 @@ pub const LNCT = struct { | ... | @@ -222,10 +117,22 @@ pub const LNCT = struct { |
| 222 | pub const timestamp = 0x3; | 117 | pub const timestamp = 0x3; |
| 223 | pub const size = 0x4; | 118 | pub const size = 0x4; |
| 224 | pub const MD5 = 0x5; | 119 | pub const MD5 = 0x5; |
| 120 | |||
| 225 | pub const lo_user = 0x2000; | 121 | pub const lo_user = 0x2000; |
| 226 | pub const hi_user = 0x3fff; | 122 | pub const hi_user = 0x3fff; |
| 227 | }; | 123 | }; |
| 228 | 124 | ||
| 125 | pub const RLE = struct { | ||
| 126 | pub const end_of_list = 0x00; | ||
| 127 | pub const base_addressx = 0x01; | ||
| 128 | pub const startx_endx = 0x02; | ||
| 129 | pub const startx_length = 0x03; | ||
| 130 | pub const offset_pair = 0x04; | ||
| 131 | pub const base_address = 0x05; | ||
| 132 | pub const start_end = 0x06; | ||
| 133 | pub const start_length = 0x07; | ||
| 134 | }; | ||
| 135 | |||
| 229 | pub const CC = enum(u8) { | 136 | pub const CC = enum(u8) { |
| 230 | normal = 0x1, | 137 | normal = 0x1, |
| 231 | program = 0x2, | 138 | program = 0x2, |
| ... | @@ -276,6 +183,8 @@ const AbbrevTableEntry = struct { | ... | @@ -276,6 +183,8 @@ const AbbrevTableEntry = struct { |
| 276 | const AbbrevAttr = struct { | 183 | const AbbrevAttr = struct { |
| 277 | attr_id: u64, | 184 | attr_id: u64, |
| 278 | form_id: u64, | 185 | form_id: u64, |
| 186 | /// Only valid if form_id is .implicit_const | ||
| 187 | payload: i64, | ||
| 279 | }; | 188 | }; |
| 280 | 189 | ||
| 281 | const FormValue = union(enum) { | 190 | const FormValue = union(enum) { |
| ... | @@ -289,6 +198,7 @@ const FormValue = union(enum) { | ... | @@ -289,6 +198,7 @@ const FormValue = union(enum) { |
| 289 | RefAddr: u64, | 198 | RefAddr: u64, |
| 290 | String: []const u8, | 199 | String: []const u8, |
| 291 | StrPtr: u64, | 200 | StrPtr: u64, |
| 201 | LineStrPtr: u64, | ||
| 292 | }; | 202 | }; |
| 293 | 203 | ||
| 294 | const Constant = struct { | 204 | const Constant = struct { |
| ... | @@ -356,6 +266,7 @@ const Die = struct { | ... | @@ -356,6 +266,7 @@ const Die = struct { |
| 356 | return switch (form_value.*) { | 266 | return switch (form_value.*) { |
| 357 | FormValue.String => |value| value, | 267 | FormValue.String => |value| value, |
| 358 | FormValue.StrPtr => |offset| di.getString(offset), | 268 | FormValue.StrPtr => |offset| di.getString(offset), |
| 269 | FormValue.LineStrPtr => |offset| di.getLineString(offset), | ||
| 359 | else => error.InvalidDebugInfo, | 270 | else => error.InvalidDebugInfo, |
| 360 | }; | 271 | }; |
| 361 | } | 272 | } |
| ... | @@ -588,6 +499,7 @@ fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, en | ... | @@ -588,6 +499,7 @@ fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, en |
| 588 | 499 | ||
| 589 | FORM.string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) }, | 500 | FORM.string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) }, |
| 590 | FORM.strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) }, | 501 | FORM.strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) }, |
| 502 | FORM.line_strp => FormValue{ .LineStrPtr = try readAddress(in_stream, endian, is_64) }, | ||
| 591 | FORM.indirect => { | 503 | FORM.indirect => { |
| 592 | const child_form_id = try nosuspend leb.readULEB128(u64, in_stream); | 504 | const child_form_id = try nosuspend leb.readULEB128(u64, in_stream); |
| 593 | const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64)); | 505 | 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 | ... | @@ -595,7 +507,12 @@ fn parseFormValue(allocator: mem.Allocator, in_stream: anytype, form_id: u64, en |
| 595 | defer allocator.destroy(frame); | 507 | defer allocator.destroy(frame); |
| 596 | return await @asyncCall(frame, {}, parseFormValue, .{ allocator, in_stream, child_form_id, endian, is_64 }); | 508 | return await @asyncCall(frame, {}, parseFormValue, .{ allocator, in_stream, child_form_id, endian, is_64 }); |
| 597 | }, | 509 | }, |
| 598 | else => error.InvalidDebugInfo, | 510 | FORM.implicit_const => FormValue{ .Const = Constant{ .signed = true, .payload = undefined } }, |
| 511 | |||
| 512 | else => { | ||
| 513 | std.debug.print("dwarf: unhandled form_id: 0x{x}\n", .{form_id}); | ||
| 514 | return error.InvalidDebugInfo; | ||
| 515 | }, | ||
| 599 | }; | 516 | }; |
| 600 | } | 517 | } |
| 601 | 518 | ||
| ... | @@ -613,6 +530,7 @@ pub const DwarfInfo = struct { | ... | @@ -613,6 +530,7 @@ pub const DwarfInfo = struct { |
| 613 | debug_abbrev: []const u8, | 530 | debug_abbrev: []const u8, |
| 614 | debug_str: []const u8, | 531 | debug_str: []const u8, |
| 615 | debug_line: []const u8, | 532 | debug_line: []const u8, |
| 533 | debug_line_str: ?[]const u8, | ||
| 616 | debug_ranges: ?[]const u8, | 534 | debug_ranges: ?[]const u8, |
| 617 | // Filled later by the initializer | 535 | // Filled later by the initializer |
| 618 | abbrev_table_list: ArrayList(AbbrevTableHeader) = undefined, | 536 | abbrev_table_list: ArrayList(AbbrevTableHeader) = undefined, |
| ... | @@ -652,9 +570,20 @@ pub const DwarfInfo = struct { | ... | @@ -652,9 +570,20 @@ pub const DwarfInfo = struct { |
| 652 | const version = try in.readInt(u16, di.endian); | 570 | const version = try in.readInt(u16, di.endian); |
| 653 | if (version < 2 or version > 5) return error.InvalidDebugInfo; | 571 | if (version < 2 or version > 5) return error.InvalidDebugInfo; |
| 654 | 572 | ||
| 655 | const debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian); | 573 | var address_size: u8 = undefined; |
| 656 | 574 | var debug_abbrev_offset: u64 = undefined; | |
| 657 | const address_size = try in.readByte(); | 575 | switch (version) { |
| 576 | 5 => { | ||
| 577 | const unit_type = try in.readInt(u8, di.endian); | ||
| 578 | if (unit_type != UT.compile) return error.InvalidDebugInfo; | ||
| 579 | address_size = try in.readByte(); | ||
| 580 | debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian); | ||
| 581 | }, | ||
| 582 | else => { | ||
| 583 | debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian); | ||
| 584 | address_size = try in.readByte(); | ||
| 585 | }, | ||
| 586 | } | ||
| 658 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; | 587 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; |
| 659 | 588 | ||
| 660 | const compile_unit_pos = try seekable.getPos(); | 589 | const compile_unit_pos = try seekable.getPos(); |
| ... | @@ -756,9 +685,20 @@ pub const DwarfInfo = struct { | ... | @@ -756,9 +685,20 @@ pub const DwarfInfo = struct { |
| 756 | const version = try in.readInt(u16, di.endian); | 685 | const version = try in.readInt(u16, di.endian); |
| 757 | if (version < 2 or version > 5) return error.InvalidDebugInfo; | 686 | if (version < 2 or version > 5) return error.InvalidDebugInfo; |
| 758 | 687 | ||
| 759 | const debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian); | 688 | var address_size: u8 = undefined; |
| 760 | 689 | var debug_abbrev_offset: u64 = undefined; | |
| 761 | const address_size = try in.readByte(); | 690 | switch (version) { |
| 691 | 5 => { | ||
| 692 | const unit_type = try in.readInt(u8, di.endian); | ||
| 693 | if (unit_type != UT.compile) return error.InvalidDebugInfo; | ||
| 694 | address_size = try in.readByte(); | ||
| 695 | debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian); | ||
| 696 | }, | ||
| 697 | else => { | ||
| 698 | debug_abbrev_offset = if (is_64) try in.readInt(u64, di.endian) else try in.readInt(u32, di.endian); | ||
| 699 | address_size = try in.readByte(); | ||
| 700 | }, | ||
| 701 | } | ||
| 762 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; | 702 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; |
| 763 | 703 | ||
| 764 | const compile_unit_pos = try seekable.getPos(); | 704 | const compile_unit_pos = try seekable.getPos(); |
| ... | @@ -890,9 +830,12 @@ pub const DwarfInfo = struct { | ... | @@ -890,9 +830,12 @@ pub const DwarfInfo = struct { |
| 890 | const attr_id = try leb.readULEB128(u64, in); | 830 | const attr_id = try leb.readULEB128(u64, in); |
| 891 | const form_id = try leb.readULEB128(u64, in); | 831 | const form_id = try leb.readULEB128(u64, in); |
| 892 | if (attr_id == 0 and form_id == 0) break; | 832 | if (attr_id == 0 and form_id == 0) break; |
| 833 | // DW_FORM_implicit_const stores its value immediately after the attribute pair :( | ||
| 834 | const payload = if (form_id == FORM.implicit_const) try leb.readILEB128(i64, in) else undefined; | ||
| 893 | try attrs.append(AbbrevAttr{ | 835 | try attrs.append(AbbrevAttr{ |
| 894 | .attr_id = attr_id, | 836 | .attr_id = attr_id, |
| 895 | .form_id = form_id, | 837 | .form_id = form_id, |
| 838 | .payload = payload, | ||
| 896 | }); | 839 | }); |
| 897 | } | 840 | } |
| 898 | } | 841 | } |
| ... | @@ -914,6 +857,9 @@ pub const DwarfInfo = struct { | ... | @@ -914,6 +857,9 @@ pub const DwarfInfo = struct { |
| 914 | .id = attr.attr_id, | 857 | .id = attr.attr_id, |
| 915 | .value = try parseFormValue(di.allocator(), in_stream, attr.form_id, di.endian, is_64), | 858 | .value = try parseFormValue(di.allocator(), in_stream, attr.form_id, di.endian, is_64), |
| 916 | }; | 859 | }; |
| 860 | if (attr.form_id == FORM.implicit_const) { | ||
| 861 | result.attrs.items[i].value.Const.payload = @bitCast(u64, attr.payload); | ||
| 862 | } | ||
| 917 | } | 863 | } |
| 918 | return result; | 864 | return result; |
| 919 | } | 865 | } |
| ... | @@ -1101,6 +1047,21 @@ pub const DwarfInfo = struct { | ... | @@ -1101,6 +1047,21 @@ pub const DwarfInfo = struct { |
| 1101 | 1047 | ||
| 1102 | return error.InvalidDebugInfo; | 1048 | return error.InvalidDebugInfo; |
| 1103 | } | 1049 | } |
| 1050 | |||
| 1051 | fn getLineString(di: *DwarfInfo, offset: u64) ![]const u8 { | ||
| 1052 | const debug_line_str = di.debug_line_str orelse return error.InvalidDebugInfo; | ||
| 1053 | if (offset > debug_line_str.len) | ||
| 1054 | return error.InvalidDebugInfo; | ||
| 1055 | const casted_offset = math.cast(usize, offset) catch | ||
| 1056 | return error.InvalidDebugInfo; | ||
| 1057 | |||
| 1058 | // Valid strings always have a terminating zero byte | ||
| 1059 | if (mem.indexOfScalarPos(u8, debug_line_str, casted_offset, 0)) |last| { | ||
| 1060 | return debug_line_str[casted_offset..last]; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | return error.InvalidDebugInfo; | ||
| 1064 | } | ||
| 1104 | }; | 1065 | }; |
| 1105 | 1066 | ||
| 1106 | /// Initialize DWARF info. The caller has the responsibility to initialize most | 1067 | /// Initialize DWARF info. The caller has the responsibility to initialize most |
lib/std/dwarf/AT.zig+28| ... | @@ -99,7 +99,35 @@ pub const enum_class = 0x6d; | ... | @@ -99,7 +99,35 @@ pub const enum_class = 0x6d; |
| 99 | pub const linkage_name = 0x6e; | 99 | pub const linkage_name = 0x6e; |
| 100 | 100 | ||
| 101 | // DWARF 5 | 101 | // DWARF 5 |
| 102 | pub const string_length_bit_size = 0x6f; | ||
| 103 | pub const string_length_byte_size = 0x70; | ||
| 104 | pub const rank = 0x71; | ||
| 105 | pub const str_offsets_base = 0x72; | ||
| 106 | pub const addr_base = 0x73; | ||
| 107 | pub const rnglists_base = 0x74; | ||
| 108 | pub const dwo_name = 0x76; | ||
| 109 | pub const reference = 0x77; | ||
| 110 | pub const rvalue_reference = 0x78; | ||
| 111 | pub const macros = 0x79; | ||
| 112 | pub const call_all_calls = 0x7a; | ||
| 113 | pub const call_all_source_calls = 0x7b; | ||
| 114 | pub const call_all_tail_calls = 0x7c; | ||
| 115 | pub const call_return_pc = 0x7d; | ||
| 116 | pub const call_value = 0x7e; | ||
| 117 | pub const call_origin = 0x7f; | ||
| 118 | pub const call_parameter = 0x80; | ||
| 119 | pub const call_pc = 0x81; | ||
| 120 | pub const call_tail_call = 0x82; | ||
| 121 | pub const call_target = 0x83; | ||
| 122 | pub const call_target_clobbered = 0x84; | ||
| 123 | pub const call_data_location = 0x85; | ||
| 124 | pub const call_data_value = 0x86; | ||
| 125 | pub const @"noreturn" = 0x87; | ||
| 102 | pub const alignment = 0x88; | 126 | pub const alignment = 0x88; |
| 127 | pub const export_symbols = 0x89; | ||
| 128 | pub const deleted = 0x8a; | ||
| 129 | pub const defaulted = 0x8b; | ||
| 130 | pub const loclists_base = 0x8c; | ||
| 103 | 131 | ||
| 104 | pub const lo_user = 0x2000; // Implementation-defined range start. | 132 | pub const lo_user = 0x2000; // Implementation-defined range start. |
| 105 | pub const hi_user = 0x3fff; // Implementation-defined range end. | 133 | pub const hi_user = 0x3fff; // Implementation-defined range end. |
lib/std/dwarf/ATE.zig created+46| ... | @@ -0,0 +1,46 @@ | ||
| 1 | pub const @"void" = 0x0; | ||
| 2 | pub const address = 0x1; | ||
| 3 | pub const boolean = 0x2; | ||
| 4 | pub const complex_float = 0x3; | ||
| 5 | pub const float = 0x4; | ||
| 6 | pub const signed = 0x5; | ||
| 7 | pub const signed_char = 0x6; | ||
| 8 | pub const unsigned = 0x7; | ||
| 9 | pub const unsigned_char = 0x8; | ||
| 10 | |||
| 11 | // DWARF 3. | ||
| 12 | pub const imaginary_float = 0x9; | ||
| 13 | pub const packed_decimal = 0xa; | ||
| 14 | pub const numeric_string = 0xb; | ||
| 15 | pub const edited = 0xc; | ||
| 16 | pub const signed_fixed = 0xd; | ||
| 17 | pub const unsigned_fixed = 0xe; | ||
| 18 | pub const decimal_float = 0xf; | ||
| 19 | |||
| 20 | // DWARF 4. | ||
| 21 | pub const UTF = 0x10; | ||
| 22 | |||
| 23 | // DWARF 5. | ||
| 24 | pub const UCS = 0x11; | ||
| 25 | pub const ASCII = 0x12; | ||
| 26 | |||
| 27 | pub const lo_user = 0x80; | ||
| 28 | pub const hi_user = 0xff; | ||
| 29 | |||
| 30 | // HP extensions. | ||
| 31 | pub const HP_float80 = 0x80; // Floating-point (80 bit). | ||
| 32 | pub const HP_complex_float80 = 0x81; // Complex floating-point (80 bit). | ||
| 33 | pub const HP_float128 = 0x82; // Floating-point (128 bit). | ||
| 34 | pub const HP_complex_float128 = 0x83; // Complex fp (128 bit). | ||
| 35 | pub const HP_floathpintel = 0x84; // Floating-point (82 bit IA64). | ||
| 36 | pub const HP_imaginary_float80 = 0x85; | ||
| 37 | pub const HP_imaginary_float128 = 0x86; | ||
| 38 | pub const HP_VAX_float = 0x88; // F or G floating. | ||
| 39 | pub const HP_VAX_float_d = 0x89; // D floating. | ||
| 40 | pub const HP_packed_decimal = 0x8a; // Cobol. | ||
| 41 | pub const HP_zoned_decimal = 0x8b; // Cobol. | ||
| 42 | pub const HP_edited = 0x8c; // Cobol. | ||
| 43 | pub const HP_signed_fixed = 0x8d; // Cobol. | ||
| 44 | pub const HP_unsigned_fixed = 0x8e; // Cobol. | ||
| 45 | pub const HP_VAX_complex_float = 0x8f; // F or G floating complex. | ||
| 46 | pub const HP_VAX_complex_float_d = 0x90; // D floating complex. | ||
lib/std/dwarf/FORM.zig created+52| ... | @@ -0,0 +1,52 @@ | ||
| 1 | pub const addr = 0x01; | ||
| 2 | pub const block2 = 0x03; | ||
| 3 | pub const block4 = 0x04; | ||
| 4 | pub const data2 = 0x05; | ||
| 5 | pub const data4 = 0x06; | ||
| 6 | pub const data8 = 0x07; | ||
| 7 | pub const string = 0x08; | ||
| 8 | pub const block = 0x09; | ||
| 9 | pub const block1 = 0x0a; | ||
| 10 | pub const data1 = 0x0b; | ||
| 11 | pub const flag = 0x0c; | ||
| 12 | pub const sdata = 0x0d; | ||
| 13 | pub const strp = 0x0e; | ||
| 14 | pub const udata = 0x0f; | ||
| 15 | pub const ref_addr = 0x10; | ||
| 16 | pub const ref1 = 0x11; | ||
| 17 | pub const ref2 = 0x12; | ||
| 18 | pub const ref4 = 0x13; | ||
| 19 | pub const ref8 = 0x14; | ||
| 20 | pub const ref_udata = 0x15; | ||
| 21 | pub const indirect = 0x16; | ||
| 22 | pub const sec_offset = 0x17; | ||
| 23 | pub const exprloc = 0x18; | ||
| 24 | pub const flag_present = 0x19; | ||
| 25 | pub const strx = 0x1a; | ||
| 26 | pub const addrx = 0x1b; | ||
| 27 | pub const ref_sup4 = 0x1c; | ||
| 28 | pub const strp_sup = 0x1d; | ||
| 29 | pub const data16 = 0x1e; | ||
| 30 | pub const line_strp = 0x1f; | ||
| 31 | pub const ref_sig8 = 0x20; | ||
| 32 | pub const implicit_const = 0x21; | ||
| 33 | pub const loclistx = 0x22; | ||
| 34 | pub const rnglistx = 0x23; | ||
| 35 | pub const ref_sup8 = 0x24; | ||
| 36 | pub const strx1 = 0x25; | ||
| 37 | pub const strx2 = 0x26; | ||
| 38 | pub const strx3 = 0x27; | ||
| 39 | pub const strx4 = 0x28; | ||
| 40 | pub const addrx1 = 0x29; | ||
| 41 | pub const addrx2 = 0x2a; | ||
| 42 | pub const addrx3 = 0x2b; | ||
| 43 | pub const addrx4 = 0x2c; | ||
| 44 | |||
| 45 | // Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. | ||
| 46 | pub const GNU_addr_index = 0x1f01; | ||
| 47 | pub const GNU_str_index = 0x1f02; | ||
| 48 | |||
| 49 | // Extensions for DWZ multifile. | ||
| 50 | // See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . | ||
| 51 | pub const GNU_ref_alt = 0x1f20; | ||
| 52 | pub const GNU_strp_alt = 0x1f21; | ||
lib/std/dwarf/LANG.zig created+48| ... | @@ -0,0 +1,48 @@ | ||
| 1 | pub const C89 = 0x0001; | ||
| 2 | pub const C = 0x0002; | ||
| 3 | pub const Ada83 = 0x0003; | ||
| 4 | pub const C_plus_plus = 0x0004; | ||
| 5 | pub const Cobol74 = 0x0005; | ||
| 6 | pub const Cobol85 = 0x0006; | ||
| 7 | pub const Fortran77 = 0x0007; | ||
| 8 | pub const Fortran90 = 0x0008; | ||
| 9 | pub const Pascal83 = 0x0009; | ||
| 10 | pub const Modula2 = 0x000a; | ||
| 11 | pub const Java = 0x000b; | ||
| 12 | pub const C99 = 0x000c; | ||
| 13 | pub const Ada95 = 0x000d; | ||
| 14 | pub const Fortran95 = 0x000e; | ||
| 15 | pub const PLI = 0x000f; | ||
| 16 | pub const ObjC = 0x0010; | ||
| 17 | pub const ObjC_plus_plus = 0x0011; | ||
| 18 | pub const UPC = 0x0012; | ||
| 19 | pub const D = 0x0013; | ||
| 20 | pub const Python = 0x0014; | ||
| 21 | pub const OpenCL = 0x0015; | ||
| 22 | pub const Go = 0x0016; | ||
| 23 | pub const Modula3 = 0x0017; | ||
| 24 | pub const Haskell = 0x0018; | ||
| 25 | pub const C_plus_plus_03 = 0x0019; | ||
| 26 | pub const C_plus_plus_11 = 0x001a; | ||
| 27 | pub const OCaml = 0x001b; | ||
| 28 | pub const Rust = 0x001c; | ||
| 29 | pub const C11 = 0x001d; | ||
| 30 | pub const Swift = 0x001e; | ||
| 31 | pub const Julia = 0x001f; | ||
| 32 | pub const Dylan = 0x0020; | ||
| 33 | pub const C_plus_plus_14 = 0x0021; | ||
| 34 | pub const Fortran03 = 0x0022; | ||
| 35 | pub const Fortran08 = 0x0023; | ||
| 36 | pub const RenderScript = 0x0024; | ||
| 37 | pub const BLISS = 0x0025; | ||
| 38 | |||
| 39 | pub const lo_user = 0x8000; | ||
| 40 | pub const hi_user = 0xffff; | ||
| 41 | |||
| 42 | pub const Mips_Assembler = 0x8001; | ||
| 43 | pub const Upc = 0x8765; | ||
| 44 | pub const HP_Bliss = 0x8003; | ||
| 45 | pub const HP_Basic91 = 0x8004; | ||
| 46 | pub const HP_Pascal91 = 0x8005; | ||
| 47 | pub const HP_IMacro = 0x8006; | ||
| 48 | pub const HP_Assembler = 0x8007; | ||
lib/std/dwarf/OP.zig+12| ... | @@ -157,6 +157,18 @@ pub const bit_piece = 0x9d; | ... | @@ -157,6 +157,18 @@ pub const bit_piece = 0x9d; |
| 157 | pub const implicit_value = 0x9e; | 157 | pub const implicit_value = 0x9e; |
| 158 | pub const stack_value = 0x9f; | 158 | pub const stack_value = 0x9f; |
| 159 | 159 | ||
| 160 | // DWARF 5 extensions. | ||
| 161 | pub const implicit_pointer = 0xa0; | ||
| 162 | pub const addrx = 0xa1; | ||
| 163 | pub const constx = 0xa2; | ||
| 164 | pub const entry_value = 0xa3; | ||
| 165 | pub const const_type = 0xa4; | ||
| 166 | pub const regval_type = 0xa5; | ||
| 167 | pub const deref_type = 0xa6; | ||
| 168 | pub const xderef_type = 0xa7; | ||
| 169 | pub const convert = 0xa8; | ||
| 170 | pub const reinterpret = 0xa9; | ||
| 171 | |||
| 160 | pub const lo_user = 0xe0; // Implementation-defined range start. | 172 | pub const lo_user = 0xe0; // Implementation-defined range start. |
| 161 | pub const hi_user = 0xff; // Implementation-defined range end. | 173 | pub const hi_user = 0xff; // Implementation-defined range end. |
| 162 | 174 |
lib/std/dwarf/TAG.zig+10| ... | @@ -65,6 +65,16 @@ pub const type_unit = 0x41; | ... | @@ -65,6 +65,16 @@ pub const type_unit = 0x41; |
| 65 | pub const rvalue_reference_type = 0x42; | 65 | pub const rvalue_reference_type = 0x42; |
| 66 | pub const template_alias = 0x43; | 66 | pub const template_alias = 0x43; |
| 67 | 67 | ||
| 68 | // DWARF 5 | ||
| 69 | pub const coarray_type = 0x44; | ||
| 70 | pub const generic_subrange = 0x45; | ||
| 71 | pub const dynamic_type = 0x46; | ||
| 72 | pub const atomic_type = 0x47; | ||
| 73 | pub const call_site = 0x48; | ||
| 74 | pub const call_site_parameter = 0x49; | ||
| 75 | pub const skeleton_unit = 0x4a; | ||
| 76 | pub const immutable_type = 0x4b; | ||
| 77 | |||
| 68 | pub const lo_user = 0x4080; | 78 | pub const lo_user = 0x4080; |
| 69 | pub const hi_user = 0xffff; | 79 | pub const hi_user = 0xffff; |
| 70 | 80 |
src/link/MachO/Object.zig+13| ... | @@ -38,6 +38,7 @@ dwarf_debug_info_index: ?u16 = null, | ... | @@ -38,6 +38,7 @@ dwarf_debug_info_index: ?u16 = null, |
| 38 | dwarf_debug_abbrev_index: ?u16 = null, | 38 | dwarf_debug_abbrev_index: ?u16 = null, |
| 39 | dwarf_debug_str_index: ?u16 = null, | 39 | dwarf_debug_str_index: ?u16 = null, |
| 40 | dwarf_debug_line_index: ?u16 = null, | 40 | dwarf_debug_line_index: ?u16 = null, |
| 41 | dwarf_debug_line_str_index: ?u16 = null, | ||
| 41 | dwarf_debug_ranges_index: ?u16 = null, | 42 | dwarf_debug_ranges_index: ?u16 = null, |
| 42 | 43 | ||
| 43 | symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 44 | symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| ... | @@ -68,6 +69,7 @@ const DebugInfo = struct { | ... | @@ -68,6 +69,7 @@ const DebugInfo = struct { |
| 68 | debug_abbrev: []u8, | 69 | debug_abbrev: []u8, |
| 69 | debug_str: []u8, | 70 | debug_str: []u8, |
| 70 | debug_line: []u8, | 71 | debug_line: []u8, |
| 72 | debug_line_str: []u8, | ||
| 71 | debug_ranges: []u8, | 73 | debug_ranges: []u8, |
| 72 | 74 | ||
| 73 | pub fn parseFromObject(allocator: Allocator, object: *const Object) !?DebugInfo { | 75 | pub fn parseFromObject(allocator: Allocator, object: *const Object) !?DebugInfo { |
| ... | @@ -87,6 +89,12 @@ const DebugInfo = struct { | ... | @@ -87,6 +89,12 @@ const DebugInfo = struct { |
| 87 | const index = object.dwarf_debug_line_index orelse return null; | 89 | const index = object.dwarf_debug_line_index orelse return null; |
| 88 | break :blk try object.readSection(allocator, index); | 90 | break :blk try object.readSection(allocator, index); |
| 89 | }; | 91 | }; |
| 92 | var debug_line_str = blk: { | ||
| 93 | if (object.dwarf_debug_line_str_index) |ind| { | ||
| 94 | break :blk try object.readSection(allocator, ind); | ||
| 95 | } | ||
| 96 | break :blk try allocator.alloc(u8, 0); | ||
| 97 | }; | ||
| 90 | var debug_ranges = blk: { | 98 | var debug_ranges = blk: { |
| 91 | if (object.dwarf_debug_ranges_index) |ind| { | 99 | if (object.dwarf_debug_ranges_index) |ind| { |
| 92 | break :blk try object.readSection(allocator, ind); | 100 | break :blk try object.readSection(allocator, ind); |
| ... | @@ -100,6 +108,7 @@ const DebugInfo = struct { | ... | @@ -100,6 +108,7 @@ const DebugInfo = struct { |
| 100 | .debug_abbrev = debug_abbrev, | 108 | .debug_abbrev = debug_abbrev, |
| 101 | .debug_str = debug_str, | 109 | .debug_str = debug_str, |
| 102 | .debug_line = debug_line, | 110 | .debug_line = debug_line, |
| 111 | .debug_line_str = debug_line_str, | ||
| 103 | .debug_ranges = debug_ranges, | 112 | .debug_ranges = debug_ranges, |
| 104 | }; | 113 | }; |
| 105 | try dwarf.openDwarfDebugInfo(&inner, allocator); | 114 | try dwarf.openDwarfDebugInfo(&inner, allocator); |
| ... | @@ -110,6 +119,7 @@ const DebugInfo = struct { | ... | @@ -110,6 +119,7 @@ const DebugInfo = struct { |
| 110 | .debug_abbrev = debug_abbrev, | 119 | .debug_abbrev = debug_abbrev, |
| 111 | .debug_str = debug_str, | 120 | .debug_str = debug_str, |
| 112 | .debug_line = debug_line, | 121 | .debug_line = debug_line, |
| 122 | .debug_line_str = debug_line_str, | ||
| 113 | .debug_ranges = debug_ranges, | 123 | .debug_ranges = debug_ranges, |
| 114 | }; | 124 | }; |
| 115 | } | 125 | } |
| ... | @@ -119,6 +129,7 @@ const DebugInfo = struct { | ... | @@ -119,6 +129,7 @@ const DebugInfo = struct { |
| 119 | allocator.free(self.debug_abbrev); | 129 | allocator.free(self.debug_abbrev); |
| 120 | allocator.free(self.debug_str); | 130 | allocator.free(self.debug_str); |
| 121 | allocator.free(self.debug_line); | 131 | allocator.free(self.debug_line); |
| 132 | allocator.free(self.debug_line_str); | ||
| 122 | allocator.free(self.debug_ranges); | 133 | allocator.free(self.debug_ranges); |
| 123 | self.inner.abbrev_table_list.deinit(); | 134 | self.inner.abbrev_table_list.deinit(); |
| 124 | self.inner.compile_unit_list.deinit(); | 135 | self.inner.compile_unit_list.deinit(); |
| ... | @@ -285,6 +296,8 @@ pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !v | ... | @@ -285,6 +296,8 @@ pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !v |
| 285 | self.dwarf_debug_str_index = index; | 296 | self.dwarf_debug_str_index = index; |
| 286 | } else if (mem.eql(u8, sectname, "__debug_line")) { | 297 | } else if (mem.eql(u8, sectname, "__debug_line")) { |
| 287 | self.dwarf_debug_line_index = index; | 298 | self.dwarf_debug_line_index = index; |
| 299 | } else if (mem.eql(u8, sectname, "__debug_line_str")) { | ||
| 300 | self.dwarf_debug_line_str_index = index; | ||
| 288 | } else if (mem.eql(u8, sectname, "__debug_ranges")) { | 301 | } else if (mem.eql(u8, sectname, "__debug_ranges")) { |
| 289 | self.dwarf_debug_ranges_index = index; | 302 | self.dwarf_debug_ranges_index = index; |
| 290 | } | 303 | } |