authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-11 14:34:13-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-04-11 14:34:13-04:00
log3ce024dd857b4b139651258b5339e32ddad87ade
tree687112ace822fa036ecc828515eeb927bade15d9
parenta895c59971d16481a85b6bff7618a3f9e2a4e0ae
parent51eb4ebec1435dc0050bd1d40c48416019972e65
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

A bunch of fixes for the DWARF parser (#2254)

* Correct parsing of DWARF line_info section * Fix reading of udata/sdata encoded attributes * Add definition for DW_AT_alignment Even though it's been standardized in DWARF5 some compilers produce it anyway for DWARF4 infos too. * Fix reading of reference attributes * Distinguish between absolute/relative addresses

2 files changed, 172 insertions(+), 177 deletions(-)

std/debug.zig+169-177
...@@ -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};
12191218
...@@ -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};
12531251
1254const Constant = struct {1252const Constant = struct {
1255 payload: []u8,1253 payload: u64,
1256 signed: bool,1254 signed: bool,
12571255
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};
12641261
...@@ -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}
14451442
1446fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {1443fn 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}
14621466
1463fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue {1467fn 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),
14671471 2 => try in_stream.readIntLittle(u16),
1468fn 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}
14721479
1473fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) anyerror!FormValue {1480fn 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) },
15001506
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 },
15091512
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) },
15121515
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
17871790
1788fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo {1791fn 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);
17901794
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);
17971796
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));
18021798
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));
18071805
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 51807 // 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;
18111809
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;
18141812
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;
18171815
1818 if (version >= 4) {1816 if (version >= 4) {
1819 // maximum_operations_per_instruction1817 // maximum_operations_per_instruction
1820 _ = try di.dwarf_in_stream.readByte();1818 _ = try di.dwarf_in_stream.readByte();
1821 }1819 }
18221820
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();
18251823
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;
18281826
1829 const opcode_base = try di.dwarf_in_stream.readByte();1827 const opcode_base = try di.dwarf_in_stream.readByte();
18301828
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);
18321830
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 }
18391837
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 }
18471845
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);
18501848
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 }
18641862
1865 try di.dwarf_seekable_stream.seekTo(prog_start_offset);1863 try di.dwarf_seekable_stream.seekTo(prog_start_offset);
18661864
1867 while (true) {1865 while (true) {
1868 const opcode = try di.dwarf_in_stream.readByte();1866 const opcode = try di.dwarf_in_stream.readByte();
18691867
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 opcodes1900 // 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 }
19581953
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
1962fn scanAllCompileUnits(di: *DwarfInfo) !void {1957fn 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;
19661960
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 });
20242017
2025 this_unit_offset += next_offset;2018 this_unit_offset += next_offset;
2026 cu_index += 1;
2027 }2019 }
2028}2020}
20292021
std/dwarf.zig+3
...@@ -241,6 +241,9 @@ pub const AT_const_expr = 0x6c;...@@ -241,6 +241,9 @@ pub const AT_const_expr = 0x6c;
241pub const AT_enum_class = 0x6d;241pub const AT_enum_class = 0x6d;
242pub const AT_linkage_name = 0x6e;242pub const AT_linkage_name = 0x6e;
243243
244// DWARF 5
245pub const AT_alignment = 0x88;
246
244pub const AT_lo_user = 0x2000; // Implementation-defined range start.247pub const AT_lo_user = 0x2000; // Implementation-defined range start.
245pub const AT_hi_user = 0x3fff; // Implementation-defined range end.248pub const AT_hi_user = 0x3fff; // Implementation-defined range end.
246249