| //===-- 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 |