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 @@ -764,20 +764,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(); @@ -919,9 +920,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 @@ -929,7 +928,6 @@ ExtOffset, Len, Cursor.tell() - ExtOffset)); *OffsetPtr = End; } else if (Opcode < Prologue.OpcodeBase) { - DataExtractor::Cursor Cursor(*OffsetPtr); if (Verbose) *OS << LNStandardString(Opcode); switch (Opcode) { @@ -1103,15 +1101,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 = @@ -1126,12 +1115,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 @@ -239,11 +239,14 @@ ## Table with extended opcode that overruns table end. # NONFATAL: debug_line[0x0000039d] # 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 0x3ed while reading [0x3e6, 0x3ee) -# MORE-ERR: warning: last sequence in debug line table at offset 0x0000039d is not terminated +# NONFATAL-NEXT: 0x00000000feedfeed +# VERBOSE-NEXT: DW_LNE_set_address (0x0000000000000000) +# MORE-ERR-NEXT: warning: unexpected end of data at offset 0x3ed while reading [0x3e6, 0x3ee) +# MORE-ERR-NEXT: warning: last sequence in debug line table at offset 0x0000039d is not terminated # LAST: debug_line[0x000003ed] # VERBOSE: DW_LNE_set_address (0x00000000cafebabe)