From 2387e9ecb164b00f0802697bd667a59fb5295626 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 29 Apr 2014 21:28:13 +0000 Subject: [DWARF parser] Cleanup code in DWARFDebugLine. Move several function definitions into .cpp, unify constructors and clear() methods (fixing a couple of latent bugs from copy-paste), turn static function parsePrologue() into Prologue::parse(). More work needed here to untangle weird multiple inheritance in table parsing and dumping. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207579 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARFContext.cpp | 2 +- lib/DebugInfo/DWARFDebugLine.cpp | 165 ++++++++++++++++++++++++--------------- lib/DebugInfo/DWARFDebugLine.h | 50 +++++------- 3 files changed, 119 insertions(+), 98 deletions(-) (limited to 'lib/DebugInfo') diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 08b7b91637..6503207dae 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -142,7 +142,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(), savedAddressByteSize); DWARFDebugLine::DumpingState state(OS); - while (DWARFDebugLine::parsePrologue(lineData, &stmtOffset, &state.Prologue)) + while (state.Prologue.parse(lineData, &stmtOffset)) state.finalize(); } diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp index de543eec2d..8ca7ec18d2 100644 --- a/lib/DebugInfo/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARFDebugLine.cpp @@ -16,6 +16,19 @@ using namespace llvm; using namespace dwarf; +DWARFDebugLine::Prologue::Prologue() { + clear(); +} + +void DWARFDebugLine::Prologue::clear() { + TotalLength = Version = PrologueLength = 0; + MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; + OpcodeBase = 0; + StandardOpcodeLengths.clear(); + IncludeDirectories.clear(); + FileNames.clear(); +} + void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { OS << "Line table prologue:\n" << format(" total_length: 0x%8.8x\n", TotalLength) @@ -51,6 +64,67 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { } } +bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, + uint32_t *offset_ptr) { + const uint32_t prologue_offset = *offset_ptr; + + clear(); + TotalLength = debug_line_data.getU32(offset_ptr); + Version = debug_line_data.getU16(offset_ptr); + if (Version < 2) + return false; + + PrologueLength = debug_line_data.getU32(offset_ptr); + const uint32_t end_prologue_offset = PrologueLength + *offset_ptr; + MinInstLength = debug_line_data.getU8(offset_ptr); + if (Version >= 4) + MaxOpsPerInst = debug_line_data.getU8(offset_ptr); + DefaultIsStmt = debug_line_data.getU8(offset_ptr); + LineBase = debug_line_data.getU8(offset_ptr); + LineRange = debug_line_data.getU8(offset_ptr); + OpcodeBase = debug_line_data.getU8(offset_ptr); + + StandardOpcodeLengths.reserve(OpcodeBase - 1); + for (uint32_t i = 1; i < OpcodeBase; ++i) { + uint8_t op_len = debug_line_data.getU8(offset_ptr); + StandardOpcodeLengths.push_back(op_len); + } + + while (*offset_ptr < end_prologue_offset) { + const char *s = debug_line_data.getCStr(offset_ptr); + if (s && s[0]) + IncludeDirectories.push_back(s); + else + break; + } + + while (*offset_ptr < end_prologue_offset) { + const char *name = debug_line_data.getCStr(offset_ptr); + if (name && name[0]) { + FileNameEntry fileEntry; + fileEntry.Name = name; + fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); + fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); + fileEntry.Length = debug_line_data.getULEB128(offset_ptr); + FileNames.push_back(fileEntry); + } else { + break; + } + } + + if (*offset_ptr != end_prologue_offset) { + fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should" + " have ended at 0x%8.8x but it ended at 0x%8.8x\n", + prologue_offset, end_prologue_offset, *offset_ptr); + return false; + } + return true; +} + +DWARFDebugLine::Row::Row(bool default_is_stmt) { + reset(default_is_stmt); +} + void DWARFDebugLine::Row::postAppend() { BasicBlock = false; PrologueEnd = false; @@ -82,6 +156,22 @@ void DWARFDebugLine::Row::dump(raw_ostream &OS) const { << '\n'; } +DWARFDebugLine::Sequence::Sequence() { + reset(); +} + +void DWARFDebugLine::Sequence::reset() { + LowPC = 0; + HighPC = 0; + FirstRowIndex = 0; + LastRowIndex = 0; + Empty = true; +} + +DWARFDebugLine::LineTable::LineTable() { + clear(); +} + void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { Prologue.dump(OS); OS << '\n'; @@ -96,6 +186,12 @@ void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { } } +void DWARFDebugLine::LineTable::clear() { + Prologue.clear(); + Rows.clear(); + Sequences.clear(); +} + DWARFDebugLine::State::~State() {} void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) { @@ -165,64 +261,6 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, return &pos.first->second; } -bool -DWARFDebugLine::parsePrologue(DataExtractor debug_line_data, - uint32_t *offset_ptr, Prologue *prologue) { - const uint32_t prologue_offset = *offset_ptr; - - prologue->clear(); - prologue->TotalLength = debug_line_data.getU32(offset_ptr); - prologue->Version = debug_line_data.getU16(offset_ptr); - if (prologue->Version < 2) - return false; - - prologue->PrologueLength = debug_line_data.getU32(offset_ptr); - const uint32_t end_prologue_offset = prologue->PrologueLength + *offset_ptr; - prologue->MinInstLength = debug_line_data.getU8(offset_ptr); - if (prologue->Version >= 4) - prologue->MaxOpsPerInst = debug_line_data.getU8(offset_ptr); - prologue->DefaultIsStmt = debug_line_data.getU8(offset_ptr); - prologue->LineBase = debug_line_data.getU8(offset_ptr); - prologue->LineRange = debug_line_data.getU8(offset_ptr); - prologue->OpcodeBase = debug_line_data.getU8(offset_ptr); - - prologue->StandardOpcodeLengths.reserve(prologue->OpcodeBase-1); - for (uint32_t i = 1; i < prologue->OpcodeBase; ++i) { - uint8_t op_len = debug_line_data.getU8(offset_ptr); - prologue->StandardOpcodeLengths.push_back(op_len); - } - - while (*offset_ptr < end_prologue_offset) { - const char *s = debug_line_data.getCStr(offset_ptr); - if (s && s[0]) - prologue->IncludeDirectories.push_back(s); - else - break; - } - - while (*offset_ptr < end_prologue_offset) { - const char *name = debug_line_data.getCStr(offset_ptr); - if (name && name[0]) { - FileNameEntry fileEntry; - fileEntry.Name = name; - fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); - fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); - fileEntry.Length = debug_line_data.getULEB128(offset_ptr); - prologue->FileNames.push_back(fileEntry); - } else { - break; - } - } - - if (*offset_ptr != end_prologue_offset) { - fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should" - " have ended at 0x%8.8x but it ended at 0x%8.8x\n", - prologue_offset, end_prologue_offset, *offset_ptr); - return false; - } - return true; -} - bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, const RelocAddrMap *RMap, uint32_t *offset_ptr, State &state) { @@ -230,7 +268,7 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, Prologue *prologue = &state.Prologue; - if (!parsePrologue(debug_line_data, offset_ptr, prologue)) { + if (!prologue->parse(debug_line_data, offset_ptr)) { // Restore our offset and return false to indicate failure! *offset_ptr = debug_line_offset; return false; @@ -486,8 +524,7 @@ bool DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, return end_offset; } -uint32_t -DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { +uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { uint32_t unknown_index = UINT32_MAX; if (Sequences.empty()) return unknown_index; @@ -532,10 +569,8 @@ DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { return index; } -bool -DWARFDebugLine::LineTable::lookupAddressRange(uint64_t address, - uint64_t size, - std::vector& result) const { +bool DWARFDebugLine::LineTable::lookupAddressRange( + uint64_t address, uint64_t size, std::vector &result) const { if (Sequences.empty()) return false; uint64_t end_addr = address + size; diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h index 890eb28c1e..ec73970f0f 100644 --- a/lib/DebugInfo/DWARFDebugLine.h +++ b/lib/DebugInfo/DWARFDebugLine.h @@ -33,10 +33,7 @@ public: }; struct Prologue { - Prologue() - : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0), - MaxOpsPerInst(0), DefaultIsStmt(0), LineBase(0), LineRange(0), - OpcodeBase(0) {} + Prologue(); // The size in bytes of the statement information for this compilation unit // (not including the total_length field itself). @@ -77,19 +74,16 @@ public: int32_t getMaxLineIncrementForSpecialOpcode() const { return LineBase + (int8_t)LineRange - 1; } + + void clear(); void dump(raw_ostream &OS) const; - void clear() { - TotalLength = Version = PrologueLength = 0; - MinInstLength = LineBase = LineRange = OpcodeBase = 0; - StandardOpcodeLengths.clear(); - IncludeDirectories.clear(); - FileNames.clear(); - } + bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr); }; // Standard .debug_line state machine structure. struct Row { - Row(bool default_is_stmt = false) { reset(default_is_stmt); } + explicit Row(bool default_is_stmt = false); + /// Called after a row is appended to the matrix. void postAppend(); void reset(bool default_is_stmt); @@ -151,14 +145,9 @@ public: unsigned LastRowIndex; bool Empty; - Sequence() { reset(); } - void reset() { - LowPC = 0; - HighPC = 0; - FirstRowIndex = 0; - LastRowIndex = 0; - Empty = true; - } + Sequence(); + void reset(); + static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) { return LHS.LowPC < RHS.LowPC; } @@ -171,23 +160,21 @@ public: }; struct LineTable { - void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); } - void appendSequence(const DWARFDebugLine::Sequence &sequence) { - Sequences.push_back(sequence); + LineTable(); + + void appendRow(const DWARFDebugLine::Row &R) { + Rows.push_back(R); } - void clear() { - Prologue.clear(); - Rows.clear(); - Sequences.clear(); + void appendSequence(const DWARFDebugLine::Sequence &S) { + Sequences.push_back(S); } // Returns the index of the row with file/line info for a given address, // or -1 if there is no such row. uint32_t lookupAddress(uint64_t address) const; - bool lookupAddressRange(uint64_t address, - uint64_t size, - std::vector& result) const; + bool lookupAddressRange(uint64_t address, uint64_t size, + std::vector &result) const; // Extracts filename by its index in filename table in prologue. // Returns true on success. @@ -196,6 +183,7 @@ public: std::string &Result) const; void dump(raw_ostream &OS) const; + void clear(); struct Prologue Prologue; typedef std::vector RowVector; @@ -236,8 +224,6 @@ public: raw_ostream &OS; }; - static bool parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr, - Prologue *prologue); /// Parse a single line table (prologue and all rows). static bool parseStatementTable(DataExtractor debug_line_data, const RelocAddrMap *RMap, -- cgit v1.2.3