diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -276,7 +276,7 @@ Error parse(DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const DWARFContext &Ctx, const DWARFUnit *U, function_ref RecoverableErrorHandler, - raw_ostream *OS = nullptr); + raw_ostream *OS = nullptr, bool Verbose = false); using RowVector = std::vector; using RowIter = RowVector::const_iterator; @@ -325,9 +325,11 @@ /// parsing of the table will be reported through this handler. /// \param OS - if not null, the parser will print information about the /// table as it parses it. + /// \param Verbose - if true, the parser will print verbose information when + /// printing to the output. LineTable parseNext(function_ref RecoverableErrorHandler, function_ref UnrecoverableErrorHandler, - raw_ostream *OS = nullptr); + raw_ostream *OS = nullptr, bool Verbose = false); /// Skip the current line table and go to the following line table (if /// present) immediately. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -513,13 +513,8 @@ } OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset()) << "]\n"; - if (DumpOpts.Verbose) { - Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS); - } else { - DWARFDebugLine::LineTable LineTable = - Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler); - LineTable.dump(OS, DumpOpts); - } + Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS, + DumpOpts.Verbose); } }; 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 @@ -690,7 +690,9 @@ Error DWARFDebugLine::LineTable::parse( DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const DWARFContext &Ctx, const DWARFUnit *U, - function_ref RecoverableErrorHandler, raw_ostream *OS) { + function_ref RecoverableErrorHandler, raw_ostream *OS, + bool Verbose) { + assert((OS || !Verbose) && "cannot have verbose output without stream"); const uint64_t DebugLineOffset = *OffsetPtr; clear(); @@ -699,9 +701,8 @@ Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U); if (OS) { - // The presence of OS signals verbose dumping. DIDumpOptions DumpOptions; - DumpOptions.Verbose = true; + DumpOptions.Verbose = Verbose; Prologue.dump(*OS, DumpOptions); } @@ -741,16 +742,16 @@ *OffsetPtr = DebugLineOffset + Prologue.getLength(); if (OS && *OffsetPtr < EndOffset) { *OS << '\n'; - Row::dumpTableHeader(*OS, 12); + Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0); } while (*OffsetPtr < EndOffset) { - if (OS) + if (Verbose) *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr); uint64_t OpcodeOffset = *OffsetPtr; uint8_t Opcode = TableData.getU8(OffsetPtr); - if (OS) + if (Verbose) *OS << format("%02.02" PRIx8 " ", Opcode); if (Opcode == 0) { @@ -762,7 +763,7 @@ // Tolerate zero-length; assume length is correct and soldier on. if (Len == 0) { - if (OS) + if (Verbose) *OS << "Badly formed extended line op (length 0)\n"; if (!Cursor) RecoverableErrorHandler(Cursor.takeError()); @@ -771,7 +772,7 @@ } uint8_t SubOpcode = TableData.getU8(Cursor); - if (OS) + if (Verbose) *OS << LNExtendedString(SubOpcode); switch (SubOpcode) { case DW_LNE_end_sequence: @@ -783,11 +784,12 @@ // address is that of the byte after the last target machine instruction // of the sequence. State.Row.EndSequence = true; - if (OS) { + if (Verbose) { *OS << "\n"; OS->indent(12); - State.Row.dump(*OS); } + if (OS) + State.Row.dump(*OS); State.appendRowToMatrix(); State.resetRowAndSequence(); break; @@ -835,7 +837,7 @@ TableData.setAddressSize(ExtractorAddressSize); } - if (OS) + if (Verbose) *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address); } break; @@ -870,7 +872,7 @@ FileEntry.ModTime = TableData.getULEB128(Cursor); FileEntry.Length = TableData.getULEB128(Cursor); Prologue.FileNames.push_back(FileEntry); - if (OS) + if (Verbose) *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time=" << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime) << ", length=" << FileEntry.Length << ")"; @@ -879,12 +881,12 @@ case DW_LNE_set_discriminator: State.Row.Discriminator = TableData.getULEB128(Cursor); - if (OS) + if (Verbose) *OS << " (" << State.Row.Discriminator << ")"; break; default: - if (OS) + if (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 @@ -907,19 +909,21 @@ ExtOffset, Len, Cursor.tell() - ExtOffset)); *OffsetPtr = End; } else if (Opcode < Prologue.OpcodeBase) { - if (OS) + if (Verbose) *OS << LNStandardString(Opcode); switch (Opcode) { // Standard Opcodes case DW_LNS_copy: // Takes no arguments. Append a row to the matrix using the // current values of the state-machine registers. - if (OS) { + if (Verbose) { *OS << "\n"; OS->indent(12); + } + if (OS) State.Row.dump(*OS); + if (Verbose) // FIXME: Don't print this newline. *OS << "\n"; - } State.appendRowToMatrix(); break; @@ -930,7 +934,7 @@ { uint64_t AddrOffset = State.advanceAddr( TableData.getULEB128(OffsetPtr), Opcode, OpcodeOffset); - if (OS) + if (Verbose) *OS << " (" << AddrOffset << ")"; } break; @@ -939,7 +943,7 @@ // Takes a single signed LEB128 operand and adds that value to // the line register of the state machine. State.Row.Line += TableData.getSLEB128(OffsetPtr); - if (OS) + if (Verbose) *OS << " (" << State.Row.Line << ")"; break; @@ -947,7 +951,7 @@ // Takes a single unsigned LEB128 operand and stores it in the file // register of the state machine. State.Row.File = TableData.getULEB128(OffsetPtr); - if (OS) + if (Verbose) *OS << " (" << State.Row.File << ")"; break; @@ -955,7 +959,7 @@ // Takes a single unsigned LEB128 operand and stores it in the // column register of the state machine. State.Row.Column = TableData.getULEB128(OffsetPtr); - if (OS) + if (Verbose) *OS << " (" << State.Row.Column << ")"; break; @@ -986,7 +990,7 @@ { uint64_t AddrOffset = State.advanceAddrForOpcode(Opcode, OpcodeOffset).AddrDelta; - if (OS) + if (Verbose) *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset); } break; @@ -1004,9 +1008,8 @@ { uint16_t PCOffset = TableData.getRelocatedValue(2, OffsetPtr); State.Row.Address.Address += PCOffset; - if (OS) - *OS - << format(" (0x%4.4" PRIx16 ")", PCOffset); + if (Verbose) + *OS << format(" (0x%4.4" PRIx16 ")", PCOffset); } break; @@ -1026,7 +1029,7 @@ // Takes a single unsigned LEB128 operand and stores it in the // column register of the state machine. State.Row.Isa = TableData.getULEB128(OffsetPtr); - if (OS) + if (Verbose) *OS << " (" << (uint64_t)State.Row.Isa << ")"; break; @@ -1039,7 +1042,7 @@ uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1]; for (uint8_t I = 0; I < OpcodeLength; ++I) { uint64_t Value = TableData.getULEB128(OffsetPtr); - if (OS) + if (Verbose) *OS << format("Skipping ULEB128 value: 0x%16.16" PRIx64 ")\n", Value); } @@ -1051,16 +1054,17 @@ ParsingState::AddrAndLineDelta Delta = State.handleSpecialOpcode(Opcode, OpcodeOffset); - if (OS) { + if (Verbose) { *OS << "address += " << Delta.Address << ", line += " << Delta.Line << "\n"; OS->indent(12); - State.Row.dump(*OS); } + if (OS) + State.Row.dump(*OS); State.appendRowToMatrix(); } - if(OS) + if(Verbose) *OS << "\n"; } @@ -1082,6 +1086,11 @@ // rudimentary sequences for address ranges [0x0, 0xsomething). } + // Terminate the table with a final blank line to clearly delineate it from + // later dumps. + if (OS) + *OS << "\n"; + return Error::success(); } @@ -1323,14 +1332,15 @@ DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext( function_ref RecoverableErrorHandler, - function_ref UnrecoverableErrorHandler, raw_ostream *OS) { + function_ref UnrecoverableErrorHandler, raw_ostream *OS, + bool Verbose) { assert(DebugLineData.isValidOffset(Offset) && "parsing should have terminated"); DWARFUnit *U = prepareToParse(Offset); uint64_t OldOffset = Offset; LineTable LT; if (Error Err = LT.parse(DebugLineData, &Offset, Context, U, - RecoverableErrorHandler, OS)) + RecoverableErrorHandler, OS, Verbose)) UnrecoverableErrorHandler(std::move(Err)); moveToNextTable(OldOffset, LT.Prologue); return LT; diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_dwarf64_large_table.s @@ -6,12 +6,17 @@ # RUN: llvm-dwarfdump %t -debug-line 2>&1 | FileCheck %s # CHECK: debug_line[0x00000000] -# CHECK-NEXT: warning: line table program with offset 0x00000000 has length 0xfffffffc but only 0x0000003a bytes are available # CHECK-NEXT: Line table prologue: # CHECK-NEXT: total_length: 0x00000000fffffff0 # CHECK-NEXT: format: DWARF64 # CHECK-NEXT: version: 4 # CHECK-NEXT: prologue_length: 0x0000000000000016 +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: "file1" +# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: mod_time: 0x00000000 +# CHECK-NEXT: length: 0x00000000 +# CHECK-NEXT: warning: line table program with offset 0x00000000 has length 0xfffffffc but only 0x0000003a bytes are available # CHECK: 0x000000000badbeef 1 0 1 0 0 is_stmt end_sequence 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 @@ -19,23 +19,23 @@ ## Show that non-fatal errors do not prevent parsing the rest of the section. # RUN: llvm-mc -triple x86_64-pc-linux %S/Inputs/debug_line_malformed.s -filetype=obj -o %t-malformed.o -# RUN: llvm-dwarfdump -debug-line %t-malformed.o 2> %t-malformed.err \ -# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]' -# RUN: FileCheck %s --input-file=%t-malformed.err --check-prefixes=ALL,OTHER -# RUN: llvm-dwarfdump -debug-line %t-malformed.o -verbose 2> %t-malformed-verbose.err \ -# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,VERBOSE,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]' \ -# RUN: --implicit-check-not=' DW_LNS' --implicit-check-not=' DW_LNE' --implicit-check-not='address +=' -# RUN: FileCheck %s --input-file=%t-malformed-verbose.err --check-prefixes=ALL,OTHER +# RUN: llvm-dwarfdump -debug-line %t-malformed.o 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NONFATAL,LAST,SOME-ERR,MORE-ERR \ +# RUN: --implicit-check-not='debug_line[{{.*}}]' --implicit-check-not='warning:' +# RUN: llvm-dwarfdump -debug-line %t-malformed.o -verbose 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,VERBOSE,NONFATAL,LAST,SOME-ERR,MORE-ERR \ +# RUN: --implicit-check-not='debug_line[{{.*}}]' --implicit-check-not=' DW_LNS' \ +# RUN: --implicit-check-not=' DW_LNE' --implicit-check-not='address +=' \ +# RUN: --implicit-check-not='warning:' ## We should still produce warnings for malformed tables after the specified unit. -# RUN: llvm-dwarfdump -debug-line=0 %t-malformed.o 2> %t-malformed-off-first.err \ -# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NOLATER -# RUN: FileCheck %s --input-file=%t-malformed-off-first.err --check-prefix=ALL +# RUN: llvm-dwarfdump -debug-line=0 %t-malformed.o 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NOLATER,SOME-ERR --implicit-check-not='warning:' ## Don't stop looking for the later unit if non-fatal issues are found. -# RUN: llvm-dwarfdump -debug-line=0x419 %t-malformed.o 2> %t-malformed-off-last.err \ -# RUN: | FileCheck %s --check-prefixes=HEADER,LAST --implicit-check-not='debug_line[{{.*}}]' -# RUN: FileCheck %s --input-file=%t-malformed-off-last.err --check-prefix=ALL +# RUN: llvm-dwarfdump -debug-line=0x419 %t-malformed.o 2>&1 \ +# RUN: | FileCheck %s --check-prefixes=HEADER,LAST,SOME-ERR --implicit-check-not='debug_line[{{.*}}]' \ +# RUN: --implicit-check-not='warning:' # HEADER: .debug_line contents: @@ -45,6 +45,7 @@ # VERBOSE-NEXT: DW_LNE_set_address (0x000000000badbeef) # VERBOSE-NEXT: DW_LNE_end_sequence # FIRST: 0x000000000badbeef {{.*}} end_sequence +# FIRST-EMPTY: # NOFIRST-NOT: debug_line[0x00000000] # NOFIRST-NOT: 0x000000000badbeef {{.*}} end_sequence # NOLATER-NOT: debug_line[{{.*}}] @@ -66,6 +67,7 @@ # NONFATAL-NEXT: total_length: 0x00000002 # NONFATAL-NEXT: format: DWARF32 # NONFATAL-NEXT: version: 0 +# SOME-ERR-NEXT: warning: parsing line table prologue at offset 0x00000048: unsupported version 0 # NONFATAL-NOT: prologue_length ## Version 1 table. @@ -74,10 +76,13 @@ # NONFATAL-NEXT: total_length: 0x00000002 # NONFATAL-NEXT: format: DWARF32 # NONFATAL-NEXT: version: 1 +# SOME-ERR-NEXT: warning: parsing line table prologue at offset 0x0000004e: unsupported version 1 # NONFATAL-NOT: prologue_length ## Malformed directory format with no path component. # NONFATAL: debug_line[0x00000054] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000054 found an invalid directory or file table description at 0x00000073 +# SOME-ERR-NEXT: warning: failed to parse entry content descriptions because no path was found # NONFATAL-NEXT: Line table prologue # NONFATAL: prologue_length: 0x00000013 # NONFATAL-NOT: include_directories @@ -87,6 +92,8 @@ ## Prologue with length shorter than parsed. # NONFATAL: debug_line[0x00000081] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba +# SOME-ERR-NEXT: warning: file names table was not null terminated before the end of the prologue # NONFATAL-NEXT: Line table prologue # NONFATAL: file_names[ 1]: # NONFATAL-NEXT: name: "file1" @@ -99,6 +106,7 @@ ## Prologue with length longer than parsed. # NONFATAL: debug_line[0x000000c8] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000000c8 should have ended at 0x00000103 but it ended at 0x00000102 # NONFATAL-NEXT: Line table prologue # NONFATAL: file_names[ 2]: # NONFATAL-NEXT: name: "file2" @@ -115,8 +123,10 @@ # NONFATAL: prologue_length: 0x00000030 # VERBOSE: DW_LNE_set_address (0x00000000abbadaba) # VERBOSE-NEXT: DW_LNE_end_sequence +# MORE-ERR: warning: unexpected line op length at offset 0x00000158 expected 0x02 found 0x01 # VERBOSE: DW_LNE_set_discriminator (10) -# VERBOSE-NEXT: DW_LNS_set_prologue_end +# MORE-ERR: warning: unexpected line op length at offset 0x0000015c expected 0x01 found 0x02 +# VERBOSE: DW_LNS_set_prologue_end # VERBOSE-NEXT: DW_LNE_set_address (0x00000000babb1e45) # VERBOSE-NEXT: DW_LNE_end_sequence @@ -126,9 +136,11 @@ # NONFATAL: prologue_length: 0x00000030 # VERBOSE: DW_LNE_set_address (0x00000000deadfade) # VERBOSE-NEXT: DW_LNS_copy +# MORE-ERR: warning: last sequence in debug line table at offset 0x0000016c is not terminated ## Very short prologue length for V5 (ends during parameters). # NONFATAL: debug_line[0x000001b2] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000001b2 should have ended at 0x000001ce but it ended at 0x000001e1 # NONFATAL-NEXT: Line table prologue # NONFATAL: standard_opcode_lengths[DW_LNS_set_isa] = 1 # NONFATAL-NEXT: include_directories[ 0] = "/tmp" @@ -153,6 +165,7 @@ ## V5 prologue ends during file table. # NONFATAL: debug_line[0x000001ee] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000001ee should have ended at 0x00000219 but it ended at 0x00000220 # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 0] = "/tmp" # NONFATAL-NEXT: file_names[ 0]: @@ -169,6 +182,7 @@ ## V5 prologue ends during directory table. # NONFATAL: debug_line[0x0000022f] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x0000022f should have ended at 0x00000251 but it ended at 0x0000025e # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 0] = "/tmp" # NONFATAL-NEXT: file_names[ 0]: @@ -188,6 +202,8 @@ ## V5 invalid MD5 hash form when there is still data to be read. # NONFATAL: debug_line[0x0000026b] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x0000026b found an invalid directory or file table description at 0x0000029f +# SOME-ERR-NEXT: warning: failed to parse file entry because the MD5 hash is invalid # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 0] = "/tmp" # NONFATAL-NOT: file_names @@ -197,6 +213,8 @@ ## V5 invalid MD5 hash form when data beyond the prologue length has ## been read before the MD5 problem is identified. # NONFATAL: debug_line[0x000002ae] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000002ae found an invalid directory or file table description at 0x000002e0 +# SOME-ERR-NEXT: warning: failed to parse file entry because the MD5 hash is invalid # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 0] = "/tmp" # NONFATAL-NOT: file_names @@ -210,6 +228,8 @@ ## V5 invalid directory content description has unsupported form. # NONFATAL: debug_line[0x000002ec] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x000002ec found an invalid directory or file table description at 0x00000315 +# SOME-ERR-NEXT: warning: failed to parse directory entry because skipping the form value failed. # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 0] = "/foo" # NONFATAL-NOT: include_directories @@ -219,6 +239,7 @@ ## Opcode base field of value zero. # NONFATAL: debug_line[0x00000332] +# SOME-ERR-NEXT: warning: parsing line table prologue at offset 0x00000332 found opcode base of 0. Assuming no standard opcodes # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 1] = "dir1" # NONFATAL-NEXT: file_names[ 1]: @@ -232,6 +253,8 @@ ## V4 table with unterminated include directory table. # NONFATAL: debug_line[0x00000361] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000361 found an invalid directory or file table description at 0x00000383 +# SOME-ERR-NEXT: warning: include directories table was not null terminated before the end of the prologue # NONFATAL-NEXT: Line table prologue # NONFATAL: include_directories[ 1] = "dir1" # NONFATAL-NOT: file_names @@ -240,6 +263,8 @@ ## V4 table with unterminated file name table. # NONFATAL: debug_line[0x00000390] +# SOME-ERR-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bf +# SOME-ERR-NEXT: warning: file names table was not null terminated before the end of the prologue # NONFATAL-NEXT: Line table prologue # NONFATAL: file_names[ 1]: # NONFATAL-NEXT: name: "foo.c" @@ -256,36 +281,9 @@ # VERBOSE: 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 # LAST: debug_line[0x00000419] # VERBOSE: DW_LNE_set_address (0x00000000cafebabe) # VERBOSE-NEXT: DW_LNE_end_sequence - -# ALL-NOT: warning: -# ALL: warning: parsing line table prologue at offset 0x00000048: unsupported version 0 -# ALL-NEXT: warning: parsing line table prologue at offset 0x0000004e: unsupported version 1 -# ALL-NEXT: warning: parsing line table prologue at 0x00000054 found an invalid directory or file table description at 0x00000073 -# ALL-NEXT: warning: failed to parse entry content descriptions because no path was found -# ALL-NEXT: warning: parsing line table prologue at 0x00000081 found an invalid directory or file table description at 0x000000ba -# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue -# ALL-NEXT: warning: parsing line table prologue at 0x000000c8 should have ended at 0x00000103 but it ended at 0x00000102 -# OTHER-NEXT: warning: unexpected line op length at offset 0x00000158 expected 0x02 found 0x01 -# OTHER-NEXT: warning: unexpected line op length at offset 0x0000015c expected 0x01 found 0x02 -# OTHER-NEXT: warning: last sequence in debug line table at offset 0x0000016c is not terminated -# ALL-NEXT: warning: parsing line table prologue at 0x000001b2 should have ended at 0x000001ce but it ended at 0x000001e1 -# ALL-NEXT: warning: parsing line table prologue at 0x000001ee should have ended at 0x00000219 but it ended at 0x00000220 -# ALL-NEXT: warning: parsing line table prologue at 0x0000022f should have ended at 0x00000251 but it ended at 0x0000025e -# ALL-NEXT: warning: parsing line table prologue at 0x0000026b found an invalid directory or file table description at 0x0000029f -# ALL-NEXT: warning: failed to parse file entry because the MD5 hash is invalid -# ALL-NEXT: warning: parsing line table prologue at 0x000002ae found an invalid directory or file table description at 0x000002e0 -# ALL-NEXT: warning: failed to parse file entry because the MD5 hash is invalid -# ALL-NEXT: warning: parsing line table prologue at 0x000002ec found an invalid directory or file table description at 0x00000315 -# ALL-NEXT: warning: failed to parse directory entry because skipping the form value failed. -# ALL-NEXT: warning: parsing line table prologue at offset 0x00000332 found opcode base of 0. Assuming no standard opcodes -# ALL-NEXT: warning: parsing line table prologue at 0x00000361 found an invalid directory or file table description at 0x00000383 -# ALL-NEXT: warning: include directories table was not null terminated before the end of the prologue -# ALL-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bf -# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue -# OTHER-NEXT: warning: unexpected end of data at offset 0x419 while reading [0x412, 0x41a) -# OTHER-NEXT: warning: last sequence in debug line table at offset 0x000003c9 is not terminated -# ALL-NOT: warning: 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 @@ -1271,7 +1271,8 @@ DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); std::string Output; raw_string_ostream OS(Output); - Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS); + Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS, + /*Verbose=*/true); OS.flush(); EXPECT_FALSE(Recoverable); @@ -1323,13 +1324,16 @@ DWARFDebugLine::SectionParser Parser(LineData, *Context, CUs, TUs); std::string Output; raw_string_ostream OS(Output); - Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS); + Parser.parseNext(RecordRecoverable, RecordUnrecoverable, &OS, + /*Verbose=*/true); OS.flush(); StringRef LinePrefix = "0x0000002e: 00 "; StringRef OutputRef(Output); StringRef OutputToCheck = OutputRef.split(LinePrefix).second; - EXPECT_EQ((ExpectedOutput + "\n").str(), OutputToCheck); + // Each extended opcode ends with a new line and then the table ends with an + // additional blank line. + EXPECT_EQ((ExpectedOutput + "\n\n").str(), OutputToCheck); EXPECT_THAT_ERROR(std::move(Recoverable), FailedWithMessage(ExpectedErr.str())); }