diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -761,20 +761,21 @@ Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0); } while (*OffsetPtr < EndOffset) { + DataExtractor::Cursor Cursor(*OffsetPtr); + if (Verbose) *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr); uint64_t OpcodeOffset = *OffsetPtr; - uint8_t Opcode = TableData.getU8(OffsetPtr); + uint8_t Opcode = TableData.getU8(Cursor); size_t RowCount = Rows.size(); - if (Verbose) + if (Cursor && Verbose) *OS << format("%02.02" PRIx8 " ", Opcode); if (Opcode == 0) { // Extended Opcodes always start with a zero opcode followed by // a uleb128 length so you can skip ones you don't know about - DataExtractor::Cursor Cursor(*OffsetPtr); uint64_t Len = TableData.getULEB128(Cursor); uint64_t ExtOffset = Cursor.tell(); @@ -916,9 +917,7 @@ // by the table. Similarly, continue from the claimed end in the event of // a parsing error. uint64_t End = ExtOffset + Len; - if (!Cursor) - RecoverableErrorHandler(Cursor.takeError()); - else if (Cursor.tell() != End) + if (Cursor && Cursor.tell() != End) RecoverableErrorHandler(createStringError( errc::illegal_byte_sequence, "unexpected line op length at offset 0x%8.8" PRIx64 @@ -926,7 +925,6 @@ ExtOffset, Len, Cursor.tell() - ExtOffset)); *OffsetPtr = End; } else if (Opcode < Prologue.OpcodeBase) { - DataExtractor::Cursor Cursor(*OffsetPtr); if (Verbose) *OS << LNStandardString(Opcode); switch (Opcode) { @@ -1108,15 +1106,6 @@ } *OffsetPtr = Cursor.tell(); - - // Most standard opcode failures are due to failures to read ULEBs. Bail - // out of parsing, since we don't know where to continue reading from as - // there is no stated length for such byte sequences. - if (!Cursor) { - if (Verbose) - *OS << "\n\n"; - return Cursor.takeError(); - } } else { // Special Opcodes. ParsingState::AddrAndLineDelta Delta = @@ -1131,12 +1120,26 @@ State.Row.dump(*OS); State.appendRowToMatrix(); + *OffsetPtr = Cursor.tell(); } // When a row is added to the matrix, it is also dumped, which includes a // new line already, so don't add an extra one. if (Verbose && Rows.size() == RowCount) *OS << "\n"; + + // Most parse failures other than when parsing extended opcodes are due to + // failures to read ULEBs. Bail out of parsing, since we don't know where to + // continue reading from as there is no stated length for such byte + // sequences. Print the final trailing new line if needed before doing so. + if (!Cursor && Opcode != 0) { + if (Verbose) + *OS << "\n"; + return Cursor.takeError(); + } + + if (!Cursor) + RecoverableErrorHandler(Cursor.takeError()); } if (!State.Sequence.Empty) diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test @@ -278,11 +278,14 @@ ## Table with extended opcode that overruns table end. # NONFATAL: debug_line[0x000003c9] # NONFATAL-NEXT: Line table prologue -# VERBOSE: DW_LNE_set_address (0x00000000feedfeed) +# NONFATAL: Address +# NONFATAL-NEXT: ------------------ +# VERBOSE-NEXT: DW_LNE_set_address (0x00000000feedfeed) # VERBOSE-NEXT: DW_LNS_copy -# VERBOSE: DW_LNE_set_address (0x0000000000000000) -# MORE-ERR: warning: unexpected end of data at offset 0x419 while reading [0x412, 0x41a) -# MORE-ERR: warning: last sequence in debug line table at offset 0x000003c9 is not terminated +# NONFATAL-NEXT: 0x00000000feedfeed +# VERBOSE-NEXT: DW_LNE_set_address (0x0000000000000000) +# MORE-ERR-NEXT: warning: unexpected end of data at offset 0x419 while reading [0x412, 0x41a) +# MORE-ERR-NEXT: warning: last sequence in debug line table at offset 0x000003c9 is not terminated # LAST: debug_line[0x00000419] # VERBOSE: DW_LNE_set_address (0x00000000cafebabe)