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