authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-25 23:35:43+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-25 20:03:50-05:00
logaaa2f9ab2febf9e8be9bb284cd8d5e3f6c2c54f1
tree22228d74121d02d4618404244795c44d182632cb
parent8516ee392c8e1e29b3968a7c9c8812013414004c

Fix handling of DW_LNE_end_sequence

The DWARF specification states that LNE_end_sequence should just reset the state machine, it's not an error.

1 files changed, 27 insertions(+), 3 deletions(-)

lib/std/debug.zig+27-3
...@@ -1478,7 +1478,8 @@ pub const DwarfInfo = struct {...@@ -1478,7 +1478,8 @@ pub const DwarfInfo = struct {
14781478
1479 assert(line_info_offset < di.debug_line.size);1479 assert(line_info_offset < di.debug_line.size);
14801480
1481 try di.dwarf_seekable_stream.seekTo(di.debug_line.offset + line_info_offset);1481 const this_unit_offset = di.debug_line.offset + line_info_offset;
1482 try di.dwarf_seekable_stream.seekTo(this_unit_offset);
14821483
1483 var is_64: bool = undefined;1484 var is_64: bool = undefined;
1484 const unit_length = try readInitialLength(@TypeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);1485 const unit_length = try readInitialLength(@TypeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
...@@ -1546,7 +1547,9 @@ pub const DwarfInfo = struct {...@@ -1546,7 +1547,9 @@ pub const DwarfInfo = struct {
15461547
1547 try di.dwarf_seekable_stream.seekTo(prog_start_offset);1548 try di.dwarf_seekable_stream.seekTo(prog_start_offset);
15481549
1549 while (true) {1550 const next_unit_pos = this_unit_offset + next_offset;
1551
1552 while ((try di.dwarf_seekable_stream.getPos()) < next_unit_pos) {
1550 const opcode = try di.dwarf_in_stream.readByte();1553 const opcode = try di.dwarf_in_stream.readByte();
15511554
1552 if (opcode == DW.LNS_extended_op) {1555 if (opcode == DW.LNS_extended_op) {
...@@ -1557,7 +1560,7 @@ pub const DwarfInfo = struct {...@@ -1557,7 +1560,7 @@ pub const DwarfInfo = struct {
1557 DW.LNE_end_sequence => {1560 DW.LNE_end_sequence => {
1558 prog.end_sequence = true;1561 prog.end_sequence = true;
1559 if (try prog.checkLineMatch()) |info| return info;1562 if (try prog.checkLineMatch()) |info| return info;
1560 return error.MissingDebugInfo;1563 prog.reset();
1561 },1564 },
1562 DW.LNE_set_address => {1565 DW.LNE_set_address => {
1563 const addr = try di.dwarf_in_stream.readInt(usize, di.endian);1566 const addr = try di.dwarf_in_stream.readInt(usize, di.endian);
...@@ -1814,6 +1817,7 @@ const LineNumberProgram = struct {...@@ -1814,6 +1817,7 @@ const LineNumberProgram = struct {
1814 basic_block: bool,1817 basic_block: bool,
1815 end_sequence: bool,1818 end_sequence: bool,
18161819
1820 default_is_stmt: bool,
1817 target_address: usize,1821 target_address: usize,
1818 include_dirs: []const []const u8,1822 include_dirs: []const []const u8,
1819 file_entries: *ArrayList(FileEntry),1823 file_entries: *ArrayList(FileEntry),
...@@ -1826,6 +1830,25 @@ const LineNumberProgram = struct {...@@ -1826,6 +1830,25 @@ const LineNumberProgram = struct {
1826 prev_basic_block: bool,1830 prev_basic_block: bool,
1827 prev_end_sequence: bool,1831 prev_end_sequence: bool,
18281832
1833 // Reset the state machine following the DWARF specification
1834 pub fn reset(self: *LineNumberProgram) void {
1835 self.address = 0;
1836 self.file = 1;
1837 self.line = 1;
1838 self.column = 0;
1839 self.is_stmt = self.default_is_stmt;
1840 self.basic_block = false;
1841 self.end_sequence = false;
1842 // Invalidate all the remaining fields
1843 self.prev_address = 0;
1844 self.prev_file = undefined;
1845 self.prev_line = undefined;
1846 self.prev_column = undefined;
1847 self.prev_is_stmt = undefined;
1848 self.prev_basic_block = undefined;
1849 self.prev_end_sequence = undefined;
1850 }
1851
1829 pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: *ArrayList(FileEntry), target_address: usize) LineNumberProgram {1852 pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: *ArrayList(FileEntry), target_address: usize) LineNumberProgram {
1830 return LineNumberProgram{1853 return LineNumberProgram{
1831 .address = 0,1854 .address = 0,
...@@ -1837,6 +1860,7 @@ const LineNumberProgram = struct {...@@ -1837,6 +1860,7 @@ const LineNumberProgram = struct {
1837 .end_sequence = false,1860 .end_sequence = false,
1838 .include_dirs = include_dirs,1861 .include_dirs = include_dirs,
1839 .file_entries = file_entries,1862 .file_entries = file_entries,
1863 .default_is_stmt = is_stmt,
1840 .target_address = target_address,1864 .target_address = target_address,
1841 .prev_address = 0,1865 .prev_address = 0,
1842 .prev_file = undefined,1866 .prev_file = undefined,