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