| ... | @@ -1213,7 +1213,6 @@ const CompileUnit = struct { | ... | @@ -1213,7 +1213,6 @@ const CompileUnit = struct { |
| 1213 | version: u16, | 1213 | version: u16, |
| 1214 | is_64: bool, | 1214 | is_64: bool, |
| 1215 | die: *Die, | 1215 | die: *Die, |
| 1216 | index: usize, | | |
| 1217 | pc_range: ?PcRange, | 1216 | pc_range: ?PcRange, |
| 1218 | }; | 1217 | }; |
| 1219 | | 1218 | |
| ... | @@ -1244,21 +1243,19 @@ const FormValue = union(enum) { | ... | @@ -1244,21 +1243,19 @@ const FormValue = union(enum) { |
| 1244 | ExprLoc: []u8, | 1243 | ExprLoc: []u8, |
| 1245 | Flag: bool, | 1244 | Flag: bool, |
| 1246 | SecOffset: u64, | 1245 | SecOffset: u64, |
| 1247 | Ref: []u8, | 1246 | Ref: u64, |
| 1248 | RefAddr: u64, | 1247 | RefAddr: u64, |
| 1249 | RefSig8: u64, | | |
| 1250 | String: []u8, | 1248 | String: []u8, |
| 1251 | StrPtr: u64, | 1249 | StrPtr: u64, |
| 1252 | }; | 1250 | }; |
| 1253 | | 1251 | |
| 1254 | const Constant = struct { | 1252 | const Constant = struct { |
| 1255 | payload: []u8, | 1253 | payload: u64, |
| 1256 | signed: bool, | 1254 | signed: bool, |
| 1257 | | 1255 | |
| 1258 | fn asUnsignedLe(self: *const Constant) !u64 { | 1256 | fn asUnsignedLe(self: *const Constant) !u64 { |
| 1259 | if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo; | | |
| 1260 | if (self.signed) return error.InvalidDebugInfo; | 1257 | if (self.signed) return error.InvalidDebugInfo; |
| 1261 | return mem.readVarInt(u64, self.payload, builtin.Endian.Little); | 1258 | return self.payload; |
| 1262 | } | 1259 | } |
| 1263 | }; | 1260 | }; |
| 1264 | | 1261 | |
| ... | @@ -1443,11 +1440,18 @@ fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) ! | ... | @@ -1443,11 +1440,18 @@ fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) ! |
| 1443 | return parseFormValueBlockLen(allocator, in_stream, block_len); | 1440 | return parseFormValueBlockLen(allocator, in_stream, block_len); |
| 1444 | } | 1441 | } |
| 1445 | | 1442 | |
| 1446 | fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue { | 1443 | fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, size: i32) !FormValue { |
| 1447 | return FormValue{ | 1444 | return FormValue{ |
| 1448 | .Const = Constant{ | 1445 | .Const = Constant{ |
| 1449 | .signed = signed, | 1446 | .signed = signed, |
| 1450 | .payload = try readAllocBytes(allocator, in_stream, size), | 1447 | .payload = switch (size) { |
| | 1448 | 1 => try in_stream.readIntLittle(u8), |
| | 1449 | 2 => try in_stream.readIntLittle(u16), |
| | 1450 | 4 => try in_stream.readIntLittle(u32), |
| | 1451 | 8 => try in_stream.readIntLittle(u64), |
| | 1452 | -1 => if (signed) try readULeb128(in_stream) else @intCast(u64, try readILeb128(in_stream)), |
| | 1453 | else => unreachable, |
| | 1454 | }, |
| 1451 | }, | 1455 | }, |
| 1452 | }; | 1456 | }; |
| 1453 | } | 1457 | } |
| ... | @@ -1460,14 +1464,17 @@ fn parseFormValueTargetAddrSize(in_stream: var) !u64 { | ... | @@ -1460,14 +1464,17 @@ fn parseFormValueTargetAddrSize(in_stream: var) !u64 { |
| 1460 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLittle(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLittle(u64) else unreachable; | 1464 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLittle(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLittle(u64) else unreachable; |
| 1461 | } | 1465 | } |
| 1462 | | 1466 | |
| 1463 | fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue { | 1467 | fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, size: i32) !FormValue { |
| 1464 | const buf = try readAllocBytes(allocator, in_stream, size); | 1468 | return FormValue{ |
| 1465 | return FormValue{ .Ref = buf }; | 1469 | .Ref = switch (size) { |
| 1466 | } | 1470 | 1 => try in_stream.readIntLittle(u8), |
| 1467 | | 1471 | 2 => try in_stream.readIntLittle(u16), |
| 1468 | fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, comptime T: type) !FormValue { | 1472 | 4 => try in_stream.readIntLittle(u32), |
| 1469 | const block_len = try in_stream.readIntLittle(T); | 1473 | 8 => try in_stream.readIntLittle(u64), |
| 1470 | return parseFormValueRefLen(allocator, in_stream, block_len); | 1474 | -1 => try readULeb128(in_stream), |
| | 1475 | else => unreachable, |
| | 1476 | }, |
| | 1477 | }; |
| 1471 | } | 1478 | } |
| 1472 | | 1479 | |
| 1473 | fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) anyerror!FormValue { | 1480 | fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) anyerror!FormValue { |
| ... | @@ -1485,9 +1492,8 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 | ... | @@ -1485,9 +1492,8 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 |
| 1485 | DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), | 1492 | DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), |
| 1486 | DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8), | 1493 | DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8), |
| 1487 | DW.FORM_udata, DW.FORM_sdata => { | 1494 | DW.FORM_udata, DW.FORM_sdata => { |
| 1488 | const block_len = try readULeb128(in_stream); | | |
| 1489 | const signed = form_id == DW.FORM_sdata; | 1495 | const signed = form_id == DW.FORM_sdata; |
| 1490 | return parseFormValueConstant(allocator, in_stream, signed, block_len); | 1496 | return parseFormValueConstant(allocator, in_stream, signed, -1); |
| 1491 | }, | 1497 | }, |
| 1492 | DW.FORM_exprloc => { | 1498 | DW.FORM_exprloc => { |
| 1493 | const size = try readULeb128(in_stream); | 1499 | const size = try readULeb128(in_stream); |
| ... | @@ -1498,17 +1504,14 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 | ... | @@ -1498,17 +1504,14 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 |
| 1498 | DW.FORM_flag_present => FormValue{ .Flag = true }, | 1504 | DW.FORM_flag_present => FormValue{ .Flag = true }, |
| 1499 | DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 1505 | DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| 1500 | | 1506 | |
| 1501 | DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8), | 1507 | DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, 1), |
| 1502 | DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16), | 1508 | DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, 2), |
| 1503 | DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32), | 1509 | DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, 4), |
| 1504 | DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64), | 1510 | DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, 8), |
| 1505 | DW.FORM_ref_udata => { | 1511 | DW.FORM_ref_udata => parseFormValueRef(allocator, in_stream, -1), |
| 1506 | const ref_len = try readULeb128(in_stream); | | |
| 1507 | return parseFormValueRefLen(allocator, in_stream, ref_len); | | |
| 1508 | }, | | |
| 1509 | | 1512 | |
| 1510 | DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 1513 | DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| 1511 | DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLittle(u64) }, | 1514 | DW.FORM_ref_sig8 => FormValue{ .Ref = try in_stream.readIntLittle(u64) }, |
| 1512 | | 1515 | |
| 1513 | DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, | 1516 | DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, |
| 1514 | DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | 1517 | DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, |
| ... | @@ -1787,173 +1790,165 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u | ... | @@ -1787,173 +1790,165 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u |
| 1787 | | 1790 | |
| 1788 | fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo { | 1791 | fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo { |
| 1789 | const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir); | 1792 | const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir); |
| | 1793 | const line_info_offset = try compile_unit.die.getAttrSecOffset(DW.AT_stmt_list); |
| 1790 | | 1794 | |
| 1791 | const debug_line_end = di.debug_line.offset + di.debug_line.size; | 1795 | assert(line_info_offset < di.debug_line.size); |
| 1792 | var this_offset = di.debug_line.offset; | | |
| 1793 | var this_index: usize = 0; | | |
| 1794 | | | |
| 1795 | while (this_offset < debug_line_end) : (this_index += 1) { | | |
| 1796 | try di.dwarf_seekable_stream.seekTo(this_offset); | | |
| 1797 | | 1796 | |
| 1798 | var is_64: bool = undefined; | 1797 | try di.dwarf_seekable_stream.seekTo(di.debug_line.offset + line_info_offset); |
| 1799 | const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64); | | |
| 1800 | if (unit_length == 0) return error.MissingDebugInfo; | | |
| 1801 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); | | |
| 1802 | | 1798 | |
| 1803 | if (compile_unit.index != this_index) { | 1799 | var is_64: bool = undefined; |
| 1804 | this_offset += next_offset; | 1800 | const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64); |
| 1805 | continue; | 1801 | if (unit_length == 0) { |
| 1806 | } | 1802 | return error.MissingDebugInfo; |
| | 1803 | } |
| | 1804 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| 1807 | | 1805 | |
| 1808 | const version = try di.dwarf_in_stream.readInt(u16, di.endian); | 1806 | const version = try di.dwarf_in_stream.readInt(u16, di.endian); |
| 1809 | // TODO support 3 and 5 | 1807 | // TODO support 3 and 5 |
| 1810 | if (version != 2 and version != 4) return error.InvalidDebugInfo; | 1808 | if (version != 2 and version != 4) return error.InvalidDebugInfo; |
| 1811 | | 1809 | |
| 1812 | const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian); | 1810 | const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian); |
| 1813 | const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length; | 1811 | const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length; |
| 1814 | | 1812 | |
| 1815 | const minimum_instruction_length = try di.dwarf_in_stream.readByte(); | 1813 | const minimum_instruction_length = try di.dwarf_in_stream.readByte(); |
| 1816 | if (minimum_instruction_length == 0) return error.InvalidDebugInfo; | 1814 | if (minimum_instruction_length == 0) return error.InvalidDebugInfo; |
| 1817 | | 1815 | |
| 1818 | if (version >= 4) { | 1816 | if (version >= 4) { |
| 1819 | // maximum_operations_per_instruction | 1817 | // maximum_operations_per_instruction |
| 1820 | _ = try di.dwarf_in_stream.readByte(); | 1818 | _ = try di.dwarf_in_stream.readByte(); |
| 1821 | } | 1819 | } |
| 1822 | | 1820 | |
| 1823 | const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0; | 1821 | const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0; |
| 1824 | const line_base = try di.dwarf_in_stream.readByteSigned(); | 1822 | const line_base = try di.dwarf_in_stream.readByteSigned(); |
| 1825 | | 1823 | |
| 1826 | const line_range = try di.dwarf_in_stream.readByte(); | 1824 | const line_range = try di.dwarf_in_stream.readByte(); |
| 1827 | if (line_range == 0) return error.InvalidDebugInfo; | 1825 | if (line_range == 0) return error.InvalidDebugInfo; |
| 1828 | | 1826 | |
| 1829 | const opcode_base = try di.dwarf_in_stream.readByte(); | 1827 | const opcode_base = try di.dwarf_in_stream.readByte(); |
| 1830 | | 1828 | |
| 1831 | const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1); | 1829 | const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1); |
| 1832 | | 1830 | |
| 1833 | { | 1831 | { |
| 1834 | var i: usize = 0; | 1832 | var i: usize = 0; |
| 1835 | while (i < opcode_base - 1) : (i += 1) { | 1833 | while (i < opcode_base - 1) : (i += 1) { |
| 1836 | standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte(); | 1834 | standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte(); |
| 1837 | } | | |
| 1838 | } | 1835 | } |
| | 1836 | } |
| 1839 | | 1837 | |
| 1840 | var include_directories = ArrayList([]u8).init(di.allocator()); | 1838 | var include_directories = ArrayList([]u8).init(di.allocator()); |
| 1841 | try include_directories.append(compile_unit_cwd); | 1839 | try include_directories.append(compile_unit_cwd); |
| 1842 | while (true) { | 1840 | while (true) { |
| 1843 | const dir = try di.readString(); | 1841 | const dir = try di.readString(); |
| 1844 | if (dir.len == 0) break; | 1842 | if (dir.len == 0) break; |
| 1845 | try include_directories.append(dir); | 1843 | try include_directories.append(dir); |
| 1846 | } | 1844 | } |
| 1847 | | 1845 | |
| 1848 | var file_entries = ArrayList(FileEntry).init(di.allocator()); | 1846 | var file_entries = ArrayList(FileEntry).init(di.allocator()); |
| 1849 | var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address); | 1847 | var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address); |
| 1850 | | 1848 | |
| 1851 | while (true) { | 1849 | while (true) { |
| 1852 | const file_name = try di.readString(); | 1850 | const file_name = try di.readString(); |
| 1853 | if (file_name.len == 0) break; | 1851 | if (file_name.len == 0) break; |
| 1854 | const dir_index = try readULeb128(di.dwarf_in_stream); | 1852 | const dir_index = try readULeb128(di.dwarf_in_stream); |
| 1855 | const mtime = try readULeb128(di.dwarf_in_stream); | 1853 | const mtime = try readULeb128(di.dwarf_in_stream); |
| 1856 | const len_bytes = try readULeb128(di.dwarf_in_stream); | 1854 | const len_bytes = try readULeb128(di.dwarf_in_stream); |
| 1857 | try file_entries.append(FileEntry{ | 1855 | try file_entries.append(FileEntry{ |
| 1858 | .file_name = file_name, | 1856 | .file_name = file_name, |
| 1859 | .dir_index = dir_index, | 1857 | .dir_index = dir_index, |
| 1860 | .mtime = mtime, | 1858 | .mtime = mtime, |
| 1861 | .len_bytes = len_bytes, | 1859 | .len_bytes = len_bytes, |
| 1862 | }); | 1860 | }); |
| 1863 | } | 1861 | } |
| 1864 | | 1862 | |
| 1865 | try di.dwarf_seekable_stream.seekTo(prog_start_offset); | 1863 | try di.dwarf_seekable_stream.seekTo(prog_start_offset); |
| 1866 | | 1864 | |
| 1867 | while (true) { | 1865 | while (true) { |
| 1868 | const opcode = try di.dwarf_in_stream.readByte(); | 1866 | const opcode = try di.dwarf_in_stream.readByte(); |
| 1869 | | 1867 | |
| 1870 | if (opcode == DW.LNS_extended_op) { | 1868 | if (opcode == DW.LNS_extended_op) { |
| 1871 | const op_size = try readULeb128(di.dwarf_in_stream); | 1869 | const op_size = try readULeb128(di.dwarf_in_stream); |
| 1872 | if (op_size < 1) return error.InvalidDebugInfo; | 1870 | if (op_size < 1) return error.InvalidDebugInfo; |
| 1873 | var sub_op = try di.dwarf_in_stream.readByte(); | 1871 | var sub_op = try di.dwarf_in_stream.readByte(); |
| 1874 | switch (sub_op) { | 1872 | switch (sub_op) { |
| 1875 | DW.LNE_end_sequence => { | 1873 | DW.LNE_end_sequence => { |
| 1876 | prog.end_sequence = true; | 1874 | prog.end_sequence = true; |
| 1877 | if (try prog.checkLineMatch()) |info| return info; | 1875 | if (try prog.checkLineMatch()) |info| return info; |
| 1878 | return error.MissingDebugInfo; | 1876 | return error.MissingDebugInfo; |
| 1879 | }, | 1877 | }, |
| 1880 | DW.LNE_set_address => { | 1878 | DW.LNE_set_address => { |
| 1881 | const addr = try di.dwarf_in_stream.readInt(usize, di.endian); | 1879 | const addr = try di.dwarf_in_stream.readInt(usize, di.endian); |
| 1882 | prog.address = addr; | 1880 | prog.address = addr; |
| 1883 | }, | 1881 | }, |
| 1884 | DW.LNE_define_file => { | 1882 | DW.LNE_define_file => { |
| 1885 | const file_name = try di.readString(); | 1883 | const file_name = try di.readString(); |
| 1886 | const dir_index = try readULeb128(di.dwarf_in_stream); | 1884 | const dir_index = try readULeb128(di.dwarf_in_stream); |
| 1887 | const mtime = try readULeb128(di.dwarf_in_stream); | 1885 | const mtime = try readULeb128(di.dwarf_in_stream); |
| 1888 | const len_bytes = try readULeb128(di.dwarf_in_stream); | 1886 | const len_bytes = try readULeb128(di.dwarf_in_stream); |
| 1889 | try file_entries.append(FileEntry{ | 1887 | try file_entries.append(FileEntry{ |
| 1890 | .file_name = file_name, | 1888 | .file_name = file_name, |
| 1891 | .dir_index = dir_index, | 1889 | .dir_index = dir_index, |
| 1892 | .mtime = mtime, | 1890 | .mtime = mtime, |
| 1893 | .len_bytes = len_bytes, | 1891 | .len_bytes = len_bytes, |
| 1894 | }); | 1892 | }); |
| 1895 | }, | 1893 | }, |
| 1896 | else => { | 1894 | else => { |
| 1897 | const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo; | 1895 | const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo; |
| 1898 | try di.dwarf_seekable_stream.seekForward(fwd_amt); | 1896 | try di.dwarf_seekable_stream.seekForward(fwd_amt); |
| 1899 | }, | 1897 | }, |
| 1900 | } | 1898 | } |
| 1901 | } else if (opcode >= opcode_base) { | 1899 | } else if (opcode >= opcode_base) { |
| 1902 | // special opcodes | 1900 | // special opcodes |
| 1903 | const adjusted_opcode = opcode - opcode_base; | 1901 | const adjusted_opcode = opcode - opcode_base; |
| 1904 | const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range); | 1902 | const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range); |
| 1905 | const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); | 1903 | const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); |
| 1906 | prog.line += inc_line; | 1904 | prog.line += inc_line; |
| 1907 | prog.address += inc_addr; | 1905 | prog.address += inc_addr; |
| 1908 | if (try prog.checkLineMatch()) |info| return info; | 1906 | if (try prog.checkLineMatch()) |info| return info; |
| 1909 | prog.basic_block = false; | 1907 | prog.basic_block = false; |
| 1910 | } else { | 1908 | } else { |
| 1911 | switch (opcode) { | 1909 | switch (opcode) { |
| 1912 | DW.LNS_copy => { | 1910 | DW.LNS_copy => { |
| 1913 | if (try prog.checkLineMatch()) |info| return info; | 1911 | if (try prog.checkLineMatch()) |info| return info; |
| 1914 | prog.basic_block = false; | 1912 | prog.basic_block = false; |
| 1915 | }, | 1913 | }, |
| 1916 | DW.LNS_advance_pc => { | 1914 | DW.LNS_advance_pc => { |
| 1917 | const arg = try readULeb128(di.dwarf_in_stream); | 1915 | const arg = try readULeb128(di.dwarf_in_stream); |
| 1918 | prog.address += arg * minimum_instruction_length; | 1916 | prog.address += arg * minimum_instruction_length; |
| 1919 | }, | 1917 | }, |
| 1920 | DW.LNS_advance_line => { | 1918 | DW.LNS_advance_line => { |
| 1921 | const arg = try readILeb128(di.dwarf_in_stream); | 1919 | const arg = try readILeb128(di.dwarf_in_stream); |
| 1922 | prog.line += arg; | 1920 | prog.line += arg; |
| 1923 | }, | 1921 | }, |
| 1924 | DW.LNS_set_file => { | 1922 | DW.LNS_set_file => { |
| 1925 | const arg = try readULeb128(di.dwarf_in_stream); | 1923 | const arg = try readULeb128(di.dwarf_in_stream); |
| 1926 | prog.file = arg; | 1924 | prog.file = arg; |
| 1927 | }, | 1925 | }, |
| 1928 | DW.LNS_set_column => { | 1926 | DW.LNS_set_column => { |
| 1929 | const arg = try readULeb128(di.dwarf_in_stream); | 1927 | const arg = try readULeb128(di.dwarf_in_stream); |
| 1930 | prog.column = arg; | 1928 | prog.column = arg; |
| 1931 | }, | 1929 | }, |
| 1932 | DW.LNS_negate_stmt => { | 1930 | DW.LNS_negate_stmt => { |
| 1933 | prog.is_stmt = !prog.is_stmt; | 1931 | prog.is_stmt = !prog.is_stmt; |
| 1934 | }, | 1932 | }, |
| 1935 | DW.LNS_set_basic_block => { | 1933 | DW.LNS_set_basic_block => { |
| 1936 | prog.basic_block = true; | 1934 | prog.basic_block = true; |
| 1937 | }, | 1935 | }, |
| 1938 | DW.LNS_const_add_pc => { | 1936 | DW.LNS_const_add_pc => { |
| 1939 | const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range); | 1937 | const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range); |
| 1940 | prog.address += inc_addr; | 1938 | prog.address += inc_addr; |
| 1941 | }, | 1939 | }, |
| 1942 | DW.LNS_fixed_advance_pc => { | 1940 | DW.LNS_fixed_advance_pc => { |
| 1943 | const arg = try di.dwarf_in_stream.readInt(u16, di.endian); | 1941 | const arg = try di.dwarf_in_stream.readInt(u16, di.endian); |
| 1944 | prog.address += arg; | 1942 | prog.address += arg; |
| 1945 | }, | 1943 | }, |
| 1946 | DW.LNS_set_prologue_end => {}, | 1944 | DW.LNS_set_prologue_end => {}, |
| 1947 | else => { | 1945 | else => { |
| 1948 | if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo; | 1946 | if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo; |
| 1949 | const len_bytes = standard_opcode_lengths[opcode - 1]; | 1947 | const len_bytes = standard_opcode_lengths[opcode - 1]; |
| 1950 | try di.dwarf_seekable_stream.seekForward(len_bytes); | 1948 | try di.dwarf_seekable_stream.seekForward(len_bytes); |
| 1951 | }, | 1949 | }, |
| 1952 | } | | |
| 1953 | } | 1950 | } |
| 1954 | } | 1951 | } |
| 1955 | | | |
| 1956 | this_offset += next_offset; | | |
| 1957 | } | 1952 | } |
| 1958 | | 1953 | |
| 1959 | return error.MissingDebugInfo; | 1954 | return error.MissingDebugInfo; |
| ... | @@ -1962,7 +1957,6 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr | ... | @@ -1962,7 +1957,6 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr |
| 1962 | fn scanAllCompileUnits(di: *DwarfInfo) !void { | 1957 | fn scanAllCompileUnits(di: *DwarfInfo) !void { |
| 1963 | const debug_info_end = di.debug_info.offset + di.debug_info.size; | 1958 | const debug_info_end = di.debug_info.offset + di.debug_info.size; |
| 1964 | var this_unit_offset = di.debug_info.offset; | 1959 | var this_unit_offset = di.debug_info.offset; |
| 1965 | var cu_index: usize = 0; | | |
| 1966 | | 1960 | |
| 1967 | while (this_unit_offset < debug_info_end) { | 1961 | while (this_unit_offset < debug_info_end) { |
| 1968 | try di.dwarf_seekable_stream.seekTo(this_unit_offset); | 1962 | try di.dwarf_seekable_stream.seekTo(this_unit_offset); |
| ... | @@ -2019,11 +2013,9 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void { | ... | @@ -2019,11 +2013,9 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void { |
| 2019 | .is_64 = is_64, | 2013 | .is_64 = is_64, |
| 2020 | .pc_range = pc_range, | 2014 | .pc_range = pc_range, |
| 2021 | .die = compile_unit_die, | 2015 | .die = compile_unit_die, |
| 2022 | .index = cu_index, | | |
| 2023 | }); | 2016 | }); |
| 2024 | | 2017 | |
| 2025 | this_unit_offset += next_offset; | 2018 | this_unit_offset += next_offset; |
| 2026 | cu_index += 1; | | |
| 2027 | } | 2019 | } |
| 2028 | } | 2020 | } |
| 2029 | | 2021 | |