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 @@ -433,6 +442,12 @@ State.Row.EndSequence = true; State.appendRowToMatrix(*OffsetPtr); State.resetRowAndSequence(); + if (OS) { + *OS << "DW_LNE_end_sequence\n"; + OS->indent(12); + State.Row.dump(*OS); + *OS << "\n"; + } break; case DW_LNE_set_address: @@ -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 << format("DW_LNE_set_address (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 << "DW_LNE_define_file(" << 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 << "DW_LNE_set_discriminator (" << State.Row.Discriminator + << ")\n"; break; default: @@ -494,44 +520,61 @@ // current values of the state-machine registers. Then set // the basic_block register to false. State.appendRowToMatrix(*OffsetPtr); + if (OS) + *OS << "DW_LNS_copy\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 << "DW_LNS_advance_pc (" << 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 << "DW_LNS_advance_line (" << 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 << "DW_LNS_set_file (" << 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 << "DW_LNS_set_column (" << 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 << "DW_LNS_negate_stmt\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 << "DW_LNS_set_basic_block\n"; break; case DW_LNS_const_add_pc: @@ -551,6 +594,9 @@ uint64_t AddrOffset = (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength; State.Row.Address += AddrOffset; + if (OS) + *OS << format("DW_LNS_const_add_pc (0x%16.16" PRIx64 ")\n", + AddrOffset); } break; @@ -564,25 +610,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 << format("DW_LNS_fixed_advance_pc (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 << "DW_LNS_set_prologue_end\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 << "DW_LNS_set_epilogue_begin\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 << "DW_LNS_set_column (" << State.Row.Isa << ")\n"; break; default: @@ -592,8 +650,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 +700,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;