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