Index: include/llvm/DebugInfo/DWARF/DWARFDebugLine.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -217,7 +217,8 @@ void clear(); /// Parse prologue and all rows. - bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr); + bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + raw_ostream *OS = nullptr); using RowVector = std::vector; using RowIter = RowVector::const_iterator; Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -337,8 +337,12 @@ isLittleEndian(), savedAddressByteSize); DWARFDebugLine::LineTable LineTable; uint32_t Offset = *StmtOffset; - LineTable.parse(lineData, &Offset); - LineTable.dump(OS); + if (DumpOpts.Verbose) { + LineTable.parse(lineData, &Offset, &OS); + } else { + LineTable.parse(lineData, &Offset); + LineTable.dump(OS); + } } } } Index: lib/DebugInfo/DWARF/DWARFDebugLine.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -394,7 +394,7 @@ } bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData, - uint32_t *OffsetPtr) { + uint32_t *OffsetPtr, raw_ostream *OS) { const uint32_t DebugLineOffset = *OffsetPtr; clear(); @@ -405,14 +405,23 @@ return false; } + if (OS) + Prologue.dump(*OS); + const uint32_t EndOffset = DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength(); ParsingState State(this); while (*OffsetPtr < EndOffset) { + if (OS) + *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr); + uint8_t Opcode = DebugLineData.getU8(OffsetPtr); + if (OS) + *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 @@ -432,6 +441,12 @@ // of the sequence. State.Row.EndSequence = true; State.appendRowToMatrix(*OffsetPtr); + if (OS) { + *OS << LNExtendedString(SubOpcode) << "\n"; + OS->indent(12); + State.Row.dump(*OS); + *OS << "\n"; + } State.resetRowAndSequence(); break; @@ -443,6 +458,9 @@ // that affect the address register add a delta to it. This instruction // stores a relocatable value into it instead. State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr); + if (OS) + *OS << LNExtendedString(SubOpcode) + << format(" (0x%16.16" PRIx64 ")\n", State.Row.Address); break; case DW_LNE_define_file: @@ -473,11 +491,19 @@ FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); Prologue.FileNames.push_back(FileEntry); + if (OS) + *OS << LNExtendedString(SubOpcode) << " (" << FileEntry.Name.str() + << ", dir=" << FileEntry.DirIdx << ", mod_time=" + << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime) + << ", length=" << FileEntry.Length << ")\n"; } break; case DW_LNE_set_discriminator: State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr); + if (OS) + *OS << LNExtendedString(SubOpcode) << " (" << State.Row.Discriminator + << ")\n"; break; default: @@ -494,44 +520,65 @@ // current values of the state-machine registers. Then set // the basic_block register to false. State.appendRowToMatrix(*OffsetPtr); + if (OS) { + *OS << LNStandardString(Opcode) << "\n"; + OS->indent(12); + State.Row.dump(*OS); + *OS << "\n"; + } break; case DW_LNS_advance_pc: // Takes a single unsigned LEB128 operand, multiplies it by the // min_inst_length field of the prologue, and adds the // result to the address register of the state machine. - State.Row.Address += - DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength; + { + uint64_t AddrOffset = + DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength; + State.Row.Address += AddrOffset; + if (OS) + *OS << LNStandardString(Opcode) << " (" << AddrOffset << ")\n"; + } break; case DW_LNS_advance_line: // Takes a single signed LEB128 operand and adds that value to // the line register of the state machine. State.Row.Line += DebugLineData.getSLEB128(OffsetPtr); + if (OS) + *OS << LNStandardString(Opcode) << " (" << State.Row.Line << ")\n"; break; case DW_LNS_set_file: // Takes a single unsigned LEB128 operand and stores it in the file // register of the state machine. State.Row.File = DebugLineData.getULEB128(OffsetPtr); + if (OS) + *OS << LNStandardString(Opcode) << " (" << State.Row.File << ")\n"; break; case DW_LNS_set_column: // Takes a single unsigned LEB128 operand and stores it in the // column register of the state machine. State.Row.Column = DebugLineData.getULEB128(OffsetPtr); + if (OS) + *OS << LNStandardString(Opcode) << " (" << State.Row.Column << ")\n"; break; case DW_LNS_negate_stmt: // Takes no arguments. Set the is_stmt register of the state // machine to the logical negation of its current value. State.Row.IsStmt = !State.Row.IsStmt; + if (OS) + *OS << LNStandardString(Opcode) << "\n"; break; case DW_LNS_set_basic_block: // Takes no arguments. Set the basic_block register of the // state machine to true State.Row.BasicBlock = true; + if (OS) + *OS << LNStandardString(Opcode) << "\n"; break; case DW_LNS_const_add_pc: @@ -551,6 +598,9 @@ uint64_t AddrOffset = (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength; State.Row.Address += AddrOffset; + if (OS) + *OS << LNStandardString(Opcode) + << format(" (0x%16.16" PRIx64 ")\n", AddrOffset); } break; @@ -564,25 +614,37 @@ // judge when the computation of a special opcode overflows and // requires the use of DW_LNS_advance_pc. Such assemblers, however, // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. - State.Row.Address += DebugLineData.getU16(OffsetPtr); + { + uint16_t PCOffset = DebugLineData.getU16(OffsetPtr); + State.Row.Address += PCOffset; + if (OS) + *OS << LNStandardString(Opcode) + << format(" (0x%16.16" PRIx64 ")\n", PCOffset); + } break; case DW_LNS_set_prologue_end: // Takes no arguments. Set the prologue_end register of the // state machine to true State.Row.PrologueEnd = true; + if (OS) + *OS << LNStandardString(Opcode) << "\n"; break; case DW_LNS_set_epilogue_begin: // Takes no arguments. Set the basic_block register of the // state machine to true State.Row.EpilogueBegin = true; + if (OS) + *OS << LNStandardString(Opcode) << "\n"; break; case DW_LNS_set_isa: // Takes a single unsigned LEB128 operand and stores it in the // column register of the state machine. State.Row.Isa = DebugLineData.getULEB128(OffsetPtr); + if (OS) + *OS << LNStandardString(Opcode) << " (" << State.Row.Isa << ")\n"; break; default: @@ -592,8 +654,12 @@ { assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size()); uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1]; - for (uint8_t I = 0; I < OpcodeLength; ++I) - DebugLineData.getULEB128(OffsetPtr); + for (uint8_t I = 0; I < OpcodeLength; ++I) { + uint64_t Value = DebugLineData.getULEB128(OffsetPtr); + if (OS) + *OS << format("Skipping ULEB128 value: 0x%16.16" PRIx64 ")\n", + Value); + } } break; } @@ -638,6 +704,15 @@ Prologue.LineBase + (AdjustOpcode % Prologue.LineRange); State.Row.Line += LineOffset; State.Row.Address += AddrOffset; + + if (OS) { + *OS << "address += " << ((uint32_t)AdjustOpcode) + << ", line += " << LineOffset << "\n"; + OS->indent(12); + State.Row.dump(*OS); + *OS << "\n"; + } + State.appendRowToMatrix(*OffsetPtr); // Reset discriminator to 0. State.Row.Discriminator = 0; Index: test/DebugInfo/MIR/X86/empty-inline.mir =================================================================== --- test/DebugInfo/MIR/X86/empty-inline.mir +++ test/DebugInfo/MIR/X86/empty-inline.mir @@ -11,47 +11,45 @@ # Here should not be an inlined subroutine with 0 length. # CHECK: NULL # -# CHECK: Address Line Column File ISA Discriminator Flags -# CHECK-NEXT: --- -# CHECK-NEXT: 25 0 1 0 0 is_stmt -# CHECK-NEXT: 29 28 1 0 0 is_stmt prologue_end -# CHECK-NEXT: 29 28 1 0 0 is_stmt end_sequence +# CHECK: 25 0 1 0 0 is_stmt +# CHECK: 29 28 1 0 0 is_stmt prologue_end +# CHECK: 29 28 1 0 0 is_stmt end_sequence --- | source_filename = "t.ll" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx" - + %class.E = type { %class.D } %class.D = type { %class.B } %class.B = type { %class.A, %class.A } %class.A = type { i8 } %class.C = type <{ %class.E*, %class.B, [2 x i8] }> - + @a = local_unnamed_addr global %class.E* null, align 4 - + define i32 @_ZN1C5m_fn3Ev(%class.C* nocapture) local_unnamed_addr align 2 !dbg !6 { %2 = alloca %class.B, align 1 %3 = load %class.E*, %class.E** @a, align 4 %4 = icmp eq %class.E* %3, null br i1 %4, label %10, label %5 - + ;