1 //===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H 11 #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H 12 13 #include "llvm/Support/DataExtractor.h" 14 #include <map> 15 #include <string> 16 #include <vector> 17 18 namespace llvm { 19 20 class raw_ostream; 21 22 class DWARFDebugLine { 23 public: 24 struct FileNameEntry { 25 FileNameEntry() : Name(0), DirIdx(0), ModTime(0), Length(0) {} 26 27 const char *Name; 28 uint64_t DirIdx; 29 uint64_t ModTime; 30 uint64_t Length; 31 }; 32 33 struct Prologue { 34 Prologue() 35 : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0), 36 DefaultIsStmt(0), LineBase(0), LineRange(0), OpcodeBase(0) {} 37 38 // The size in bytes of the statement information for this compilation unit 39 // (not including the total_length field itself). 40 uint32_t TotalLength; 41 // Version identifier for the statement information format. 42 uint16_t Version; 43 // The number of bytes following the prologue_length field to the beginning 44 // of the first byte of the statement program itself. 45 uint32_t PrologueLength; 46 // The size in bytes of the smallest target machine instruction. Statement 47 // program opcodes that alter the address register first multiply their 48 // operands by this value. 49 uint8_t MinInstLength; 50 // The initial value of theis_stmtregister. 51 uint8_t DefaultIsStmt; 52 // This parameter affects the meaning of the special opcodes. See below. 53 int8_t LineBase; 54 // This parameter affects the meaning of the special opcodes. See below. 55 uint8_t LineRange; 56 // The number assigned to the first special opcode. 57 uint8_t OpcodeBase; 58 std::vector<uint8_t> StandardOpcodeLengths; 59 std::vector<const char*> IncludeDirectories; 60 std::vector<FileNameEntry> FileNames; 61 62 // Length of the prologue in bytes. 63 uint32_t getLength() const { 64 return PrologueLength + sizeof(TotalLength) + sizeof(Version) + 65 sizeof(PrologueLength); 66 } 67 // Length of the line table data in bytes (not including the prologue). 68 uint32_t getStatementTableLength() const { 69 return TotalLength + sizeof(TotalLength) - getLength(); 70 } 71 int32_t getMaxLineIncrementForSpecialOpcode() const { 72 return LineBase + (int8_t)LineRange - 1; 73 } 74 void dump(raw_ostream &OS) const; 75 void clear() { 76 TotalLength = Version = PrologueLength = 0; 77 MinInstLength = LineBase = LineRange = OpcodeBase = 0; 78 StandardOpcodeLengths.clear(); 79 IncludeDirectories.clear(); 80 FileNames.clear(); 81 } 82 }; 83 84 // Standard .debug_line state machine structure. 85 struct Row { 86 Row(bool default_is_stmt = false) { reset(default_is_stmt); } 87 /// Called after a row is appended to the matrix. 88 void postAppend(); 89 void reset(bool default_is_stmt); 90 void dump(raw_ostream &OS) const; 91 92 static bool orderByAddress(const Row& LHS, const Row& RHS) { 93 return LHS.Address < RHS.Address; 94 } 95 96 // The program-counter value corresponding to a machine instruction 97 // generated by the compiler. 98 uint64_t Address; 99 // An unsigned integer indicating a source line number. Lines are numbered 100 // beginning at 1. The compiler may emit the value 0 in cases where an 101 // instruction cannot be attributed to any source line. 102 uint32_t Line; 103 // An unsigned integer indicating a column number within a source line. 104 // Columns are numbered beginning at 1. The value 0 is reserved to indicate 105 // that a statement begins at the 'left edge' of the line. 106 uint16_t Column; 107 // An unsigned integer indicating the identity of the source file 108 // corresponding to a machine instruction. 109 uint16_t File; 110 // An unsigned integer whose value encodes the applicable instruction set 111 // architecture for the current instruction. 112 uint8_t Isa; 113 // A boolean indicating that the current instruction is the beginning of a 114 // statement. 115 uint8_t IsStmt:1, 116 // A boolean indicating that the current instruction is the 117 // beginning of a basic block. 118 BasicBlock:1, 119 // A boolean indicating that the current address is that of the 120 // first byte after the end of a sequence of target machine 121 // instructions. 122 EndSequence:1, 123 // A boolean indicating that the current address is one (of possibly 124 // many) where execution should be suspended for an entry breakpoint 125 // of a function. 126 PrologueEnd:1, 127 // A boolean indicating that the current address is one (of possibly 128 // many) where execution should be suspended for an exit breakpoint 129 // of a function. 130 EpilogueBegin:1; 131 }; 132 133 // Represents a series of contiguous machine instructions. Line table for each 134 // compilation unit may consist of multiple sequences, which are not 135 // guaranteed to be in the order of ascending instruction address. 136 struct Sequence { 137 // Sequence describes instructions at address range [LowPC, HighPC) 138 // and is described by line table rows [FirstRowIndex, LastRowIndex). 139 uint64_t LowPC; 140 uint64_t HighPC; 141 unsigned FirstRowIndex; 142 unsigned LastRowIndex; 143 bool Empty; 144 145 Sequence() { reset(); } 146 void reset() { 147 LowPC = 0; 148 HighPC = 0; 149 FirstRowIndex = 0; 150 LastRowIndex = 0; 151 Empty = true; 152 } 153 static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) { 154 return LHS.LowPC < RHS.LowPC; 155 } 156 bool isValid() const { 157 return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex); 158 } 159 bool containsPC(uint64_t pc) const { 160 return (LowPC <= pc && pc < HighPC); 161 } 162 }; 163 164 struct LineTable { 165 void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); } 166 void appendSequence(const DWARFDebugLine::Sequence &sequence) { 167 Sequences.push_back(sequence); 168 } 169 void clear() { 170 Prologue.clear(); 171 Rows.clear(); 172 Sequences.clear(); 173 } 174 175 // Returns the index of the row with file/line info for a given address, 176 // or -1 if there is no such row. 177 uint32_t lookupAddress(uint64_t address) const; 178 179 // Extracts filename by its index in filename table in prologue. 180 // Returns true on success. 181 bool getFileNameByIndex(uint64_t FileIndex, 182 bool NeedsAbsoluteFilePath, 183 std::string &Result) const; 184 185 void dump(raw_ostream &OS) const; 186 187 struct Prologue Prologue; 188 typedef std::vector<Row> RowVector; 189 typedef RowVector::const_iterator RowIter; 190 typedef std::vector<Sequence> SequenceVector; 191 typedef SequenceVector::const_iterator SequenceIter; 192 RowVector Rows; 193 SequenceVector Sequences; 194 }; 195 196 struct State : public Row, public Sequence, public LineTable { 197 // Special row codes. 198 enum { 199 StartParsingLineTable = 0, 200 DoneParsingLineTable = -1 201 }; 202 203 State() : row(StartParsingLineTable) {} 204 virtual ~State(); 205 206 virtual void appendRowToMatrix(uint32_t offset); 207 virtual void finalize(); 208 virtual void reset() { 209 Row::reset(Prologue.DefaultIsStmt); 210 Sequence::reset(); 211 } 212 213 // The row number that starts at zero for the prologue, and increases for 214 // each row added to the matrix. 215 unsigned row; 216 }; 217 218 struct DumpingState : public State { 219 DumpingState(raw_ostream &OS) : OS(OS) {} 220 virtual ~DumpingState(); 221 virtual void finalize(); 222 private: 223 raw_ostream &OS; 224 }; 225 226 static bool parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr, 227 Prologue *prologue); 228 /// Parse a single line table (prologue and all rows). 229 static bool parseStatementTable(DataExtractor debug_line_data, 230 uint32_t *offset_ptr, State &state); 231 232 const LineTable *getLineTable(uint32_t offset) const; 233 const LineTable *getOrParseLineTable(DataExtractor debug_line_data, 234 uint32_t offset); 235 236 private: 237 typedef std::map<uint32_t, LineTable> LineTableMapTy; 238 typedef LineTableMapTy::iterator LineTableIter; 239 typedef LineTableMapTy::const_iterator LineTableConstIter; 240 241 LineTableMapTy LineTableMap; 242 }; 243 244 } 245 246 #endif 247