1 //===- DWARFDebugLine.h -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H 10 #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H 11 12 #include "llvm/ADT/Optional.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/DebugInfo/DIContext.h" 15 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 16 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 17 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 18 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 19 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" 20 #include "llvm/Support/MD5.h" 21 #include <cstdint> 22 #include <map> 23 #include <string> 24 #include <vector> 25 26 namespace llvm { 27 28 class DWARFUnit; 29 class raw_ostream; 30 31 class DWARFDebugLine { 32 public: 33 struct FileNameEntry { 34 FileNameEntry() = default; 35 36 DWARFFormValue Name; 37 uint64_t DirIdx = 0; 38 uint64_t ModTime = 0; 39 uint64_t Length = 0; 40 MD5::MD5Result Checksum; 41 DWARFFormValue Source; 42 }; 43 44 /// Tracks which optional content types are present in a DWARF file name 45 /// entry format. 46 struct ContentTypeTracker { 47 ContentTypeTracker() = default; 48 49 /// Whether filename entries provide a modification timestamp. 50 bool HasModTime = false; 51 /// Whether filename entries provide a file size. 52 bool HasLength = false; 53 /// For v5, whether filename entries provide an MD5 checksum. 54 bool HasMD5 = false; 55 /// For v5, whether filename entries provide source text. 56 bool HasSource = false; 57 58 /// Update tracked content types with \p ContentType. 59 void trackContentType(dwarf::LineNumberEntryFormat ContentType); 60 }; 61 62 struct Prologue { 63 Prologue(); 64 65 /// The size in bytes of the statement information for this compilation unit 66 /// (not including the total_length field itself). 67 uint64_t TotalLength; 68 /// Version, address size (starting in v5), and DWARF32/64 format; these 69 /// parameters affect interpretation of forms (used in the directory and 70 /// file tables starting with v5). 71 dwarf::FormParams FormParams; 72 /// The number of bytes following the prologue_length field to the beginning 73 /// of the first byte of the statement program itself. 74 uint64_t PrologueLength; 75 /// In v5, size in bytes of a segment selector. 76 uint8_t SegSelectorSize; 77 /// The size in bytes of the smallest target machine instruction. Statement 78 /// program opcodes that alter the address register first multiply their 79 /// operands by this value. 80 uint8_t MinInstLength; 81 /// The maximum number of individual operations that may be encoded in an 82 /// instruction. 83 uint8_t MaxOpsPerInst; 84 /// The initial value of theis_stmtregister. 85 uint8_t DefaultIsStmt; 86 /// This parameter affects the meaning of the special opcodes. See below. 87 int8_t LineBase; 88 /// This parameter affects the meaning of the special opcodes. See below. 89 uint8_t LineRange; 90 /// The number assigned to the first special opcode. 91 uint8_t OpcodeBase; 92 /// This tracks which optional file format content types are present. 93 ContentTypeTracker ContentTypes; 94 std::vector<uint8_t> StandardOpcodeLengths; 95 std::vector<DWARFFormValue> IncludeDirectories; 96 std::vector<FileNameEntry> FileNames; 97 98 const dwarf::FormParams getFormParams() const { return FormParams; } 99 uint16_t getVersion() const { return FormParams.Version; } 100 uint8_t getAddressSize() const { return FormParams.AddrSize; } 101 bool isDWARF64() const { return FormParams.Format == dwarf::DWARF64; } 102 103 uint32_t sizeofTotalLength() const { return isDWARF64() ? 12 : 4; } 104 105 uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; } 106 107 bool totalLengthIsValid() const; 108 109 /// Length of the prologue in bytes. 110 uint32_t getLength() const { 111 return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) + 112 sizeofPrologueLength(); 113 } 114 115 /// Length of the line table data in bytes (not including the prologue). 116 uint32_t getStatementTableLength() const { 117 return TotalLength + sizeofTotalLength() - getLength(); 118 } 119 120 int32_t getMaxLineIncrementForSpecialOpcode() const { 121 return LineBase + (int8_t)LineRange - 1; 122 } 123 124 /// Get DWARF-version aware access to the file name entry at the provided 125 /// index. 126 const llvm::DWARFDebugLine::FileNameEntry & 127 getFileNameEntry(uint64_t Index) const; 128 129 bool hasFileAtIndex(uint64_t FileIndex) const; 130 131 bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, 132 DILineInfoSpecifier::FileLineInfoKind Kind, 133 std::string &Result) const; 134 135 void clear(); 136 void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const; 137 Error parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, 138 const DWARFContext &Ctx, const DWARFUnit *U = nullptr); 139 }; 140 141 /// Standard .debug_line state machine structure. 142 struct Row { 143 explicit Row(bool DefaultIsStmt = false); 144 145 /// Called after a row is appended to the matrix. 146 void postAppend(); 147 void reset(bool DefaultIsStmt); 148 void dump(raw_ostream &OS) const; 149 150 static void dumpTableHeader(raw_ostream &OS); 151 152 static bool orderByAddress(const Row &LHS, const Row &RHS) { 153 return std::tie(LHS.Address.SectionIndex, LHS.Address.Address) < 154 std::tie(RHS.Address.SectionIndex, RHS.Address.Address); 155 } 156 157 /// The program-counter value corresponding to a machine instruction 158 /// generated by the compiler and section index pointing to the section 159 /// containg this PC. If relocation information is present then section 160 /// index is the index of the section which contains above address. 161 /// Otherwise this is object::SectionedAddress::Undef value. 162 object::SectionedAddress Address; 163 /// An unsigned integer indicating a source line number. Lines are numbered 164 /// beginning at 1. The compiler may emit the value 0 in cases where an 165 /// instruction cannot be attributed to any source line. 166 uint32_t Line; 167 /// An unsigned integer indicating a column number within a source line. 168 /// Columns are numbered beginning at 1. The value 0 is reserved to indicate 169 /// that a statement begins at the 'left edge' of the line. 170 uint16_t Column; 171 /// An unsigned integer indicating the identity of the source file 172 /// corresponding to a machine instruction. 173 uint16_t File; 174 /// An unsigned integer representing the DWARF path discriminator value 175 /// for this location. 176 uint32_t Discriminator; 177 /// An unsigned integer whose value encodes the applicable instruction set 178 /// architecture for the current instruction. 179 uint8_t Isa; 180 /// A boolean indicating that the current instruction is the beginning of a 181 /// statement. 182 uint8_t IsStmt : 1, 183 /// A boolean indicating that the current instruction is the 184 /// beginning of a basic block. 185 BasicBlock : 1, 186 /// A boolean indicating that the current address is that of the 187 /// first byte after the end of a sequence of target machine 188 /// instructions. 189 EndSequence : 1, 190 /// A boolean indicating that the current address is one (of possibly 191 /// many) where execution should be suspended for an entry breakpoint 192 /// of a function. 193 PrologueEnd : 1, 194 /// A boolean indicating that the current address is one (of possibly 195 /// many) where execution should be suspended for an exit breakpoint 196 /// of a function. 197 EpilogueBegin : 1; 198 }; 199 200 /// Represents a series of contiguous machine instructions. Line table for 201 /// each compilation unit may consist of multiple sequences, which are not 202 /// guaranteed to be in the order of ascending instruction address. 203 struct Sequence { 204 Sequence(); 205 206 /// Sequence describes instructions at address range [LowPC, HighPC) 207 /// and is described by line table rows [FirstRowIndex, LastRowIndex). 208 uint64_t LowPC; 209 uint64_t HighPC; 210 /// If relocation information is present then this is the index of the 211 /// section which contains above addresses. Otherwise this is 212 /// object::SectionedAddress::Undef value. 213 uint64_t SectionIndex; 214 unsigned FirstRowIndex; 215 unsigned LastRowIndex; 216 bool Empty; 217 218 void reset(); 219 220 static bool orderByHighPC(const Sequence &LHS, const Sequence &RHS) { 221 return std::tie(LHS.SectionIndex, LHS.HighPC) < 222 std::tie(RHS.SectionIndex, RHS.HighPC); 223 } 224 225 bool isValid() const { 226 return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex); 227 } 228 229 bool containsPC(object::SectionedAddress PC) const { 230 return SectionIndex == PC.SectionIndex && 231 (LowPC <= PC.Address && PC.Address < HighPC); 232 } 233 }; 234 235 struct LineTable { 236 LineTable(); 237 238 /// Represents an invalid row 239 const uint32_t UnknownRowIndex = UINT32_MAX; 240 241 void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } 242 243 void appendSequence(const DWARFDebugLine::Sequence &S) { 244 Sequences.push_back(S); 245 } 246 247 /// Returns the index of the row with file/line info for a given address, 248 /// or UnknownRowIndex if there is no such row. 249 uint32_t lookupAddress(object::SectionedAddress Address) const; 250 251 bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, 252 std::vector<uint32_t> &Result) const; 253 254 bool hasFileAtIndex(uint64_t FileIndex) const { 255 return Prologue.hasFileAtIndex(FileIndex); 256 } 257 258 /// Extracts filename by its index in filename table in prologue. 259 /// In Dwarf 4, the files are 1-indexed and the current compilation file 260 /// name is not represented in the list. In DWARF v5, the files are 261 /// 0-indexed and the primary source file has the index 0. 262 /// Returns true on success. 263 bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, 264 DILineInfoSpecifier::FileLineInfoKind Kind, 265 std::string &Result) const { 266 return Prologue.getFileNameByIndex(FileIndex, CompDir, Kind, Result); 267 } 268 269 /// Fills the Result argument with the file and line information 270 /// corresponding to Address. Returns true on success. 271 bool getFileLineInfoForAddress(object::SectionedAddress Address, 272 const char *CompDir, 273 DILineInfoSpecifier::FileLineInfoKind Kind, 274 DILineInfo &Result) const; 275 276 void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const; 277 void clear(); 278 279 /// Parse prologue and all rows. 280 Error parse( 281 DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, 282 const DWARFContext &Ctx, const DWARFUnit *U, 283 std::function<void(Error)> RecoverableErrorCallback, 284 raw_ostream *OS = nullptr); 285 286 using RowVector = std::vector<Row>; 287 using RowIter = RowVector::const_iterator; 288 using SequenceVector = std::vector<Sequence>; 289 using SequenceIter = SequenceVector::const_iterator; 290 291 struct Prologue Prologue; 292 RowVector Rows; 293 SequenceVector Sequences; 294 295 private: 296 uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq, 297 object::SectionedAddress Address) const; 298 Optional<StringRef> 299 getSourceByIndex(uint64_t FileIndex, 300 DILineInfoSpecifier::FileLineInfoKind Kind) const; 301 302 uint32_t lookupAddressImpl(object::SectionedAddress Address) const; 303 304 bool lookupAddressRangeImpl(object::SectionedAddress Address, uint64_t Size, 305 std::vector<uint32_t> &Result) const; 306 }; 307 308 const LineTable *getLineTable(uint32_t Offset) const; 309 Expected<const LineTable *> getOrParseLineTable( 310 DWARFDataExtractor &DebugLineData, uint32_t Offset, 311 const DWARFContext &Ctx, const DWARFUnit *U, 312 std::function<void(Error)> RecoverableErrorCallback); 313 314 /// Helper to allow for parsing of an entire .debug_line section in sequence. 315 class SectionParser { 316 public: 317 using cu_range = DWARFUnitVector::iterator_range; 318 using tu_range = DWARFUnitVector::iterator_range; 319 using LineToUnitMap = std::map<uint64_t, DWARFUnit *>; 320 321 SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs, 322 tu_range TUs); 323 324 /// Get the next line table from the section. Report any issues via the 325 /// callbacks. 326 /// 327 /// \param RecoverableErrorCallback - any issues that don't prevent further 328 /// parsing of the table will be reported through this callback. 329 /// \param UnrecoverableErrorCallback - any issues that prevent further 330 /// parsing of the table will be reported through this callback. 331 /// \param OS - if not null, the parser will print information about the 332 /// table as it parses it. 333 LineTable 334 parseNext( 335 function_ref<void(Error)> RecoverableErrorCallback, 336 function_ref<void(Error)> UnrecoverableErrorCallback, 337 raw_ostream *OS = nullptr); 338 339 /// Skip the current line table and go to the following line table (if 340 /// present) immediately. 341 /// 342 /// \param ErrorCallback - report any prologue parsing issues via this 343 /// callback. 344 void skip(function_ref<void(Error)> ErrorCallback); 345 346 /// Indicates if the parser has parsed as much as possible. 347 /// 348 /// \note Certain problems with the line table structure might mean that 349 /// parsing stops before the end of the section is reached. 350 bool done() const { return Done; } 351 352 /// Get the offset the parser has reached. 353 uint32_t getOffset() const { return Offset; } 354 355 private: 356 DWARFUnit *prepareToParse(uint32_t Offset); 357 void moveToNextTable(uint32_t OldOffset, const Prologue &P); 358 359 LineToUnitMap LineToUnit; 360 361 DWARFDataExtractor &DebugLineData; 362 const DWARFContext &Context; 363 uint32_t Offset = 0; 364 bool Done = false; 365 }; 366 367 private: 368 struct ParsingState { 369 ParsingState(struct LineTable *LT); 370 371 void resetRowAndSequence(); 372 void appendRowToMatrix(); 373 374 /// Line table we're currently parsing. 375 struct LineTable *LineTable; 376 struct Row Row; 377 struct Sequence Sequence; 378 }; 379 380 using LineTableMapTy = std::map<uint32_t, LineTable>; 381 using LineTableIter = LineTableMapTy::iterator; 382 using LineTableConstIter = LineTableMapTy::const_iterator; 383 384 LineTableMapTy LineTableMap; 385 }; 386 387 } // end namespace llvm 388 389 #endif // LLVM_DEBUGINFO_DWARFDEBUGLINE_H 390