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 @@ -784,15 +784,21 @@ // Tolerate zero-length; assume length is correct and soldier on. if (Len == 0) { - if (Verbose) + if (Cursor && Verbose) *OS << "Badly formed extended line op (length 0)\n"; - if (!Cursor) + if (!Cursor) { + if (Verbose) + *OS << "\n"; RecoverableErrorHandler(Cursor.takeError()); + } *OffsetPtr = Cursor.tell(); continue; } uint8_t SubOpcode = TableData.getU8(Cursor); + // OperandOffset will be the same as ExtOffset, if it was not possible to + // read the SubOpcode. + uint64_t OperandOffset = Cursor.tell(); if (Verbose) *OS << LNExtendedString(SubOpcode); switch (SubOpcode) { @@ -805,11 +811,11 @@ // address is that of the byte after the last target machine instruction // of the sequence. State.Row.EndSequence = true; - if (Verbose) { + if (Cursor && Verbose) { *OS << "\n"; OS->indent(12); } - if (OS) + if (Cursor && OS) State.Row.dump(*OS); State.appendRowToMatrix(); State.resetRowAndSequence(); @@ -858,7 +864,7 @@ TableData.setAddressSize(ExtractorAddressSize); } - if (Verbose) + if (Cursor && Verbose) *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address); } break; @@ -893,7 +899,7 @@ FileEntry.ModTime = TableData.getULEB128(Cursor); FileEntry.Length = TableData.getULEB128(Cursor); Prologue.FileNames.push_back(FileEntry); - if (Verbose) + if (Cursor && Verbose) *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time=" << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime) << ", length=" << FileEntry.Length << ")"; @@ -902,12 +908,12 @@ case DW_LNE_set_discriminator: State.Row.Discriminator = TableData.getULEB128(Cursor); - if (Verbose) + if (Cursor && Verbose) *OS << " (" << State.Row.Discriminator << ")"; break; default: - if (Verbose) + if (Cursor && Verbose) *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode) << format(" length %" PRIx64, Len); // Len doesn't include the zero opcode byte or the length itself, but @@ -926,6 +932,20 @@ "unexpected line op length at offset 0x%8.8" PRIx64 " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64, ExtOffset, Len, Cursor.tell() - ExtOffset)); + if (!Cursor && Verbose) { + *OS << " ("; + DWARFDataExtractor::Cursor ByteCursor(OperandOffset); + uint8_t Byte = TableData.getU8(ByteCursor); + while (ByteCursor && ByteCursor.tell() < End) { + *OS << format(" %2.2" PRIx8, Byte); + Byte = TableData.getU8(ByteCursor); + } + *OS << ")"; + // The only parse failure in this case should be if the end was reached + // prematurely. In that case, throw away the error, as the main Cursor's + // error will be sufficient. + consumeError(ByteCursor.takeError()); + } *OffsetPtr = End; } else if (Opcode < Prologue.OpcodeBase) { if (Verbose) 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 @@ -244,7 +244,7 @@ # VERBOSE-NEXT: DW_LNE_set_address (0x00000000feedfeed) # VERBOSE-NEXT: DW_LNS_copy # NONFATAL-NEXT: 0x00000000feedfeed -# VERBOSE-NEXT: DW_LNE_set_address (0x0000000000000000) +# VERBOSE-NEXT: DW_LNE_set_address ( 00 f0 01 f0 f0 00 01) # 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 diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp @@ -1461,62 +1461,62 @@ INSTANTIATE_TEST_CASE_P( TruncatedExtendedOpcodeParams, TruncatedExtendedOpcodeFixture, Values( - std::make_tuple(1, 1, DW_LNE_end_sequence, ValueAndLengths(), - "Badly formed extended line op (length 0)", + std::make_tuple(1, 1, DW_LNE_end_sequence, ValueAndLengths(), "", "unable to decode LEB128 at offset 0x00000030: " "malformed uleb128, extends past end"), std::make_tuple( 2, 9, DW_LNE_set_address, ValueAndLengths{{0x12345678, LineTable::Quad}}, - "Unrecognized extended op 0x00 length 9", + " ()", "unexpected end of data at offset 0x31 while reading [0x31, 0x32)"), std::make_tuple( 3, 9, DW_LNE_set_address, ValueAndLengths{{0x12345678, LineTable::Quad}}, - "DW_LNE_set_address (0x0000000000000000)", + "DW_LNE_set_address ()", "unexpected end of data at offset 0x32 while reading [0x32, 0x3a)"), - std::make_tuple(3, 5, DW_LNE_define_file, + std::make_tuple( + 5, 9, DW_LNE_set_address, + ValueAndLengths{{0x12345678, LineTable::Quad}}, + "DW_LNE_set_address ( 78 56)", + "unexpected end of data at offset 0x34 while reading [0x32, 0x3a)"), + std::make_tuple(3, 6, DW_LNE_define_file, ValueAndLengths{{'a', LineTable::Byte}, {'\0', LineTable::Byte}, {1, LineTable::ULEB}, {1, LineTable::ULEB}, {1, LineTable::ULEB}}, - "DW_LNE_define_file (, dir=0, " - "mod_time=(0x0000000000000000), length=0)", + "DW_LNE_define_file ()", "no null terminated string at offset 0x32"), - std::make_tuple(5, 5, DW_LNE_define_file, + std::make_tuple(5, 6, DW_LNE_define_file, ValueAndLengths{{'a', LineTable::Byte}, {'\0', LineTable::Byte}, {1, LineTable::ULEB}, {1, LineTable::ULEB}, {1, LineTable::ULEB}}, - "DW_LNE_define_file (a, dir=0, " - "mod_time=(0x0000000000000000), length=0)", + "DW_LNE_define_file ( 61 00)", "unable to decode LEB128 at offset 0x00000034: " "malformed uleb128, extends past end"), - std::make_tuple(6, 5, DW_LNE_define_file, + std::make_tuple(6, 6, DW_LNE_define_file, ValueAndLengths{{'a', LineTable::Byte}, {'\0', LineTable::Byte}, {1, LineTable::ULEB}, {1, LineTable::ULEB}, {1, LineTable::ULEB}}, - "DW_LNE_define_file (a, dir=1, " - "mod_time=(0x0000000000000000), length=0)", + "DW_LNE_define_file ( 61 00 01)", "unable to decode LEB128 at offset 0x00000035: " "malformed uleb128, extends past end"), - std::make_tuple(7, 5, DW_LNE_define_file, + std::make_tuple(7, 6, DW_LNE_define_file, ValueAndLengths{{'a', LineTable::Byte}, {'\0', LineTable::Byte}, {1, LineTable::ULEB}, {1, LineTable::ULEB}, {1, LineTable::ULEB}}, - "DW_LNE_define_file (a, dir=1, " - "mod_time=(0x0000000000000001), length=0)", + "DW_LNE_define_file ( 61 00 01 01)", "unable to decode LEB128 at offset 0x00000036: " "malformed uleb128, extends past end"), std::make_tuple(3, 2, DW_LNE_set_discriminator, ValueAndLengths{{1, LineTable::ULEB}}, - "DW_LNE_set_discriminator (0)", + "DW_LNE_set_discriminator ()", "unable to decode LEB128 at offset 0x00000032: " "malformed uleb128, extends past end")), );