|  | //===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H | 
|  | #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H | 
|  |  | 
|  | #include "llvm/Support/DataExtractor.h" | 
|  | #include <map> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | class raw_ostream; | 
|  |  | 
|  | class DWARFDebugLine { | 
|  | public: | 
|  | struct FileNameEntry { | 
|  | FileNameEntry() : DirIdx(0), ModTime(0), Length(0) {} | 
|  |  | 
|  | std::string Name; | 
|  | uint64_t DirIdx; | 
|  | uint64_t ModTime; | 
|  | uint64_t Length; | 
|  | }; | 
|  |  | 
|  | struct Prologue { | 
|  | Prologue() | 
|  | : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0), | 
|  | DefaultIsStmt(0), LineBase(0), LineRange(0), OpcodeBase(0) {} | 
|  |  | 
|  | // The size in bytes of the statement information for this compilation unit | 
|  | // (not including the total_length field itself). | 
|  | uint32_t TotalLength; | 
|  | // Version identifier for the statement information format. | 
|  | uint16_t Version; | 
|  | // The number of bytes following the prologue_length field to the beginning | 
|  | // of the first byte of the statement program itself. | 
|  | uint32_t PrologueLength; | 
|  | // The size in bytes of the smallest target machine instruction. Statement | 
|  | // program opcodes that alter the address register first multiply their | 
|  | // operands by this value. | 
|  | uint8_t MinInstLength; | 
|  | // The initial value of theis_stmtregister. | 
|  | uint8_t DefaultIsStmt; | 
|  | // This parameter affects the meaning of the special opcodes. See below. | 
|  | int8_t LineBase; | 
|  | // This parameter affects the meaning of the special opcodes. See below. | 
|  | uint8_t LineRange; | 
|  | // The number assigned to the first special opcode. | 
|  | uint8_t OpcodeBase; | 
|  | std::vector<uint8_t> StandardOpcodeLengths; | 
|  | std::vector<std::string> IncludeDirectories; | 
|  | std::vector<FileNameEntry> FileNames; | 
|  |  | 
|  | // Length of the prologue in bytes. | 
|  | uint32_t getLength() const { | 
|  | return PrologueLength + sizeof(TotalLength) + sizeof(Version) + | 
|  | sizeof(PrologueLength); | 
|  | } | 
|  | // Length of the line table data in bytes (not including the prologue). | 
|  | uint32_t getStatementTableLength() const { | 
|  | return TotalLength + sizeof(TotalLength) - getLength(); | 
|  | } | 
|  | int32_t getMaxLineIncrementForSpecialOpcode() const { | 
|  | return LineBase + (int8_t)LineRange - 1; | 
|  | } | 
|  | void dump(raw_ostream &OS) const; | 
|  | void clear() { | 
|  | TotalLength = Version = PrologueLength = 0; | 
|  | MinInstLength = LineBase = LineRange = OpcodeBase = 0; | 
|  | StandardOpcodeLengths.clear(); | 
|  | IncludeDirectories.clear(); | 
|  | FileNames.clear(); | 
|  | } | 
|  | }; | 
|  |  | 
|  | // Standard .debug_line state machine structure. | 
|  | struct Row { | 
|  | Row(bool default_is_stmt = false) { reset(default_is_stmt); } | 
|  | /// Called after a row is appended to the matrix. | 
|  | void postAppend(); | 
|  | void reset(bool default_is_stmt); | 
|  | void dump(raw_ostream &OS) const; | 
|  |  | 
|  | // The program-counter value corresponding to a machine instruction | 
|  | // generated by the compiler. | 
|  | uint64_t Address; | 
|  | // An unsigned integer indicating a source line number. Lines are numbered | 
|  | // beginning at 1. The compiler may emit the value 0 in cases where an | 
|  | // instruction cannot be attributed to any source line. | 
|  | uint32_t Line; | 
|  | // An unsigned integer indicating a column number within a source line. | 
|  | // Columns are numbered beginning at 1. The value 0 is reserved to indicate | 
|  | // that a statement begins at the 'left edge' of the line. | 
|  | uint16_t Column; | 
|  | // An unsigned integer indicating the identity of the source file | 
|  | // corresponding to a machine instruction. | 
|  | uint16_t File; | 
|  | // An unsigned integer whose value encodes the applicable instruction set | 
|  | // architecture for the current instruction. | 
|  | uint8_t Isa; | 
|  | // A boolean indicating that the current instruction is the beginning of a | 
|  | // statement. | 
|  | uint8_t IsStmt:1, | 
|  | // A boolean indicating that the current instruction is the | 
|  | // beginning of a basic block. | 
|  | BasicBlock:1, | 
|  | // A boolean indicating that the current address is that of the | 
|  | // first byte after the end of a sequence of target machine | 
|  | // instructions. | 
|  | EndSequence:1, | 
|  | // A boolean indicating that the current address is one (of possibly | 
|  | // many) where execution should be suspended for an entry breakpoint | 
|  | // of a function. | 
|  | PrologueEnd:1, | 
|  | // A boolean indicating that the current address is one (of possibly | 
|  | // many) where execution should be suspended for an exit breakpoint | 
|  | // of a function. | 
|  | EpilogueBegin:1; | 
|  | }; | 
|  |  | 
|  | struct LineTable { | 
|  | void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); } | 
|  | void clear() { | 
|  | Prologue.clear(); | 
|  | Rows.clear(); | 
|  | } | 
|  |  | 
|  | uint32_t lookupAddress(uint64_t address, uint64_t cu_high_pc) const; | 
|  | void dump(raw_ostream &OS) const; | 
|  |  | 
|  | struct Prologue Prologue; | 
|  | std::vector<Row> Rows; | 
|  | }; | 
|  |  | 
|  | struct State : public Row, public LineTable { | 
|  | // Special row codes. | 
|  | enum { | 
|  | StartParsingLineTable = 0, | 
|  | DoneParsingLineTable = -1 | 
|  | }; | 
|  |  | 
|  | State() : row(StartParsingLineTable) {} | 
|  | virtual ~State(); | 
|  |  | 
|  | virtual void appendRowToMatrix(uint32_t offset); | 
|  | virtual void finalize(uint32_t offset) { row = DoneParsingLineTable; } | 
|  | virtual void reset() { Row::reset(Prologue.DefaultIsStmt); } | 
|  |  | 
|  | // The row number that starts at zero for the prologue, and increases for | 
|  | // each row added to the matrix. | 
|  | unsigned row; | 
|  | }; | 
|  |  | 
|  | struct DumpingState : public State { | 
|  | DumpingState(raw_ostream &OS) : OS(OS) {} | 
|  | virtual ~DumpingState(); | 
|  | virtual void finalize(uint32_t offset); | 
|  | private: | 
|  | 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, | 
|  | uint32_t *offset_ptr, State &state); | 
|  |  | 
|  | const LineTable *getLineTable(uint32_t offset) const; | 
|  | const LineTable *getOrParseLineTable(DataExtractor debug_line_data, | 
|  | uint32_t offset); | 
|  |  | 
|  | private: | 
|  | typedef std::map<uint32_t, LineTable> LineTableMapTy; | 
|  | typedef LineTableMapTy::iterator LineTableIter; | 
|  | typedef LineTableMapTy::const_iterator LineTableConstIter; | 
|  |  | 
|  | LineTableMapTy LineTableMap; | 
|  | }; | 
|  |  | 
|  | } | 
|  |  | 
|  | #endif |