Skip to content

Commit

Permalink
Fix handling of DW_LNE_end_sequence
Browse files Browse the repository at this point in the history
The DWARF specification states that LNE_end_sequence should just reset
the state machine, it's not an error.
  • Loading branch information
LemonBoy authored and andrewrk committed Jan 26, 2020
1 parent 8516ee3 commit aaa2f9a
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,8 @@ pub const DwarfInfo = struct {

assert(line_info_offset < di.debug_line.size);

try di.dwarf_seekable_stream.seekTo(di.debug_line.offset + line_info_offset);
const this_unit_offset = di.debug_line.offset + line_info_offset;
try di.dwarf_seekable_stream.seekTo(this_unit_offset);

var is_64: bool = undefined;
const unit_length = try readInitialLength(@TypeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
Expand Down Expand Up @@ -1546,7 +1547,9 @@ pub const DwarfInfo = struct {

try di.dwarf_seekable_stream.seekTo(prog_start_offset);

while (true) {
const next_unit_pos = this_unit_offset + next_offset;

while ((try di.dwarf_seekable_stream.getPos()) < next_unit_pos) {
const opcode = try di.dwarf_in_stream.readByte();

if (opcode == DW.LNS_extended_op) {
Expand All @@ -1557,7 +1560,7 @@ pub const DwarfInfo = struct {
DW.LNE_end_sequence => {
prog.end_sequence = true;
if (try prog.checkLineMatch()) |info| return info;
return error.MissingDebugInfo;
prog.reset();
},
DW.LNE_set_address => {
const addr = try di.dwarf_in_stream.readInt(usize, di.endian);
Expand Down Expand Up @@ -1814,6 +1817,7 @@ const LineNumberProgram = struct {
basic_block: bool,
end_sequence: bool,

default_is_stmt: bool,
target_address: usize,
include_dirs: []const []const u8,
file_entries: *ArrayList(FileEntry),
Expand All @@ -1826,6 +1830,25 @@ const LineNumberProgram = struct {
prev_basic_block: bool,
prev_end_sequence: bool,

// Reset the state machine following the DWARF specification
pub fn reset(self: *LineNumberProgram) void {
self.address = 0;
self.file = 1;
self.line = 1;
self.column = 0;
self.is_stmt = self.default_is_stmt;
self.basic_block = false;
self.end_sequence = false;
// Invalidate all the remaining fields
self.prev_address = 0;
self.prev_file = undefined;
self.prev_line = undefined;
self.prev_column = undefined;
self.prev_is_stmt = undefined;
self.prev_basic_block = undefined;
self.prev_end_sequence = undefined;
}

pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: *ArrayList(FileEntry), target_address: usize) LineNumberProgram {
return LineNumberProgram{
.address = 0,
Expand All @@ -1837,6 +1860,7 @@ const LineNumberProgram = struct {
.end_sequence = false,
.include_dirs = include_dirs,
.file_entries = file_entries,
.default_is_stmt = is_stmt,
.target_address = target_address,
.prev_address = 0,
.prev_file = undefined,
Expand Down

0 comments on commit aaa2f9a

Please sign in to comment.