LLVM 22.0.0git
DWARFDebugLine.h
Go to the documentation of this file.
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_DWARF_DWARFDEBUGLINE_H
10#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLINE_H
11
12#include "llvm/ADT/StringRef.h"
18#include "llvm/Support/MD5.h"
19#include "llvm/Support/Path.h"
20#include <cstdint>
21#include <map>
22#include <string>
23#include <vector>
24
25namespace llvm {
26
27class raw_ostream;
28
30public:
32 FileNameEntry() = default;
33
40 };
41
42 /// Tracks which optional content types are present in a DWARF file name
43 /// entry format.
45 ContentTypeTracker() = default;
46
47 /// Whether filename entries provide a modification timestamp.
48 bool HasModTime = false;
49 /// Whether filename entries provide a file size.
50 bool HasLength = false;
51 /// For v5, whether filename entries provide an MD5 checksum.
52 bool HasMD5 = false;
53 /// For v5, whether filename entries provide source text.
54 bool HasSource = false;
55
56 /// Update tracked content types with \p ContentType.
58 };
59
60 struct Prologue {
62
63 /// The size in bytes of the statement information for this compilation unit
64 /// (not including the total_length field itself).
66 /// Version, address size (starting in v5), and DWARF32/64 format; these
67 /// parameters affect interpretation of forms (used in the directory and
68 /// file tables starting with v5).
70 /// The number of bytes following the prologue_length field to the beginning
71 /// of the first byte of the statement program itself.
73 /// In v5, size in bytes of a segment selector.
75 /// The size in bytes of the smallest target machine instruction. Statement
76 /// program opcodes that alter the address register first multiply their
77 /// operands by this value.
79 /// The maximum number of individual operations that may be encoded in an
80 /// instruction.
82 /// The initial value of theis_stmtregister.
84 /// This parameter affects the meaning of the special opcodes. See below.
85 int8_t LineBase;
86 /// This parameter affects the meaning of the special opcodes. See below.
88 /// The number assigned to the first special opcode.
90 /// This tracks which optional file format content types are present.
92 std::vector<uint8_t> StandardOpcodeLengths;
93 std::vector<DWARFFormValue> IncludeDirectories;
94 std::vector<FileNameEntry> FileNames;
95
96 const dwarf::FormParams getFormParams() const { return FormParams; }
99 bool isDWARF64() const { return FormParams.Format == dwarf::DWARF64; }
100
101 uint32_t sizeofTotalLength() const { return isDWARF64() ? 12 : 4; }
102
103 uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; }
104
105 LLVM_ABI bool totalLengthIsValid() const;
106
107 /// Length of the prologue in bytes.
109
110 /// Get DWARF-version aware access to the file name entry at the provided
111 /// index.
114
115 LLVM_ABI bool hasFileAtIndex(uint64_t FileIndex) const;
116
117 LLVM_ABI std::optional<uint64_t> getLastValidFileIndex() const;
118
119 LLVM_ABI bool
120 getFileNameByIndex(uint64_t FileIndex, StringRef CompDir,
122 std::string &Result,
124
125 LLVM_ABI void clear();
126 LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
128 function_ref<void(Error)> RecoverableErrorHandler,
129 const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
130 };
131
132 /// Standard .debug_line state machine structure.
133 struct Row {
134 LLVM_ABI explicit Row(bool DefaultIsStmt = false);
135
136 /// Called after a row is appended to the matrix.
137 LLVM_ABI void postAppend();
138 LLVM_ABI void reset(bool DefaultIsStmt);
139 LLVM_ABI void dump(raw_ostream &OS) const;
140
141 LLVM_ABI static void dumpTableHeader(raw_ostream &OS, unsigned Indent);
142
143 static bool orderByAddress(const Row &LHS, const Row &RHS) {
144 return std::tie(LHS.Address.SectionIndex, LHS.Address.Address) <
145 std::tie(RHS.Address.SectionIndex, RHS.Address.Address);
146 }
147
148 /// The program-counter value corresponding to a machine instruction
149 /// generated by the compiler and section index pointing to the section
150 /// containg this PC. If relocation information is present then section
151 /// index is the index of the section which contains above address.
152 /// Otherwise this is object::SectionedAddress::Undef value.
154 /// An unsigned integer indicating a source line number. Lines are numbered
155 /// beginning at 1. The compiler may emit the value 0 in cases where an
156 /// instruction cannot be attributed to any source line.
158 /// An unsigned integer indicating a column number within a source line.
159 /// Columns are numbered beginning at 1. The value 0 is reserved to indicate
160 /// that a statement begins at the 'left edge' of the line.
162 /// An unsigned integer indicating the identity of the source file
163 /// corresponding to a machine instruction.
165 /// An unsigned integer representing the DWARF path discriminator value
166 /// for this location.
168 /// An unsigned integer whose value encodes the applicable instruction set
169 /// architecture for the current instruction.
171 /// An unsigned integer representing the index of an operation within a
172 /// VLIW instruction. The index of the first operation is 0.
173 /// For non-VLIW architectures, this register will always be 0.
175 /// A boolean indicating that the current instruction is the beginning of a
176 /// statement.
178 /// A boolean indicating that the current instruction is the
179 /// beginning of a basic block.
181 /// A boolean indicating that the current address is that of the
182 /// first byte after the end of a sequence of target machine
183 /// instructions.
185 /// A boolean indicating that the current address is one (of possibly
186 /// many) where execution should be suspended for an entry breakpoint
187 /// of a function.
189 /// A boolean indicating that the current address is one (of possibly
190 /// many) where execution should be suspended for an exit breakpoint
191 /// of a function.
193 };
194
195 /// Represents a series of contiguous machine instructions. Line table for
196 /// each compilation unit may consist of multiple sequences, which are not
197 /// guaranteed to be in the order of ascending instruction address.
198 struct Sequence {
200
201 /// Sequence describes instructions at address range [LowPC, HighPC)
202 /// and is described by line table rows [FirstRowIndex, LastRowIndex).
205 /// If relocation information is present then this is the index of the
206 /// section which contains above addresses. Otherwise this is
207 /// object::SectionedAddress::Undef value.
210 unsigned LastRowIndex;
211 bool Empty;
212
213 /// The offset into the line table where this sequence begins
215
216 LLVM_ABI void reset();
217
218 static bool orderByHighPC(const Sequence &LHS, const Sequence &RHS) {
219 return std::tie(LHS.SectionIndex, LHS.HighPC) <
220 std::tie(RHS.SectionIndex, RHS.HighPC);
221 }
222
223 bool isValid() const {
224 return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
225 }
226
228 return SectionIndex == PC.SectionIndex &&
229 (LowPC <= PC.Address && PC.Address < HighPC);
230 }
231 };
232
233 struct LineTable {
235
236 /// Represents an invalid row
237 const uint32_t UnknownRowIndex = UINT32_MAX;
238
239 void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); }
240
242 Sequences.push_back(S);
243 }
244
245 /// Returns the index of the row with file/line info for a given address,
246 /// or UnknownRowIndex if there is no such row.
248 bool *IsApproximateLine = nullptr) const;
249
250 /// Fills the Result argument with the indices of the rows that correspond
251 /// to the address range specified by \p Address and \p Size.
252 ///
253 /// \param Address - The starting address of the range.
254 /// \param Size - The size of the address range.
255 /// \param Result - The vector to fill with row indices.
256 /// \param StmtSequenceOffset - if provided, only rows from the sequence
257 /// starting at the matching offset will be added to the result.
258 ///
259 /// Returns true if any rows were found.
262 std::vector<uint32_t> &Result,
263 std::optional<uint64_t> StmtSequenceOffset = std::nullopt) const;
264
265 bool hasFileAtIndex(uint64_t FileIndex) const {
266 return Prologue.hasFileAtIndex(FileIndex);
267 }
268
269 std::optional<uint64_t> getLastValidFileIndex() const {
271 }
272
273 /// Extracts filename by its index in filename table in prologue.
274 /// In Dwarf 4, the files are 1-indexed and the current compilation file
275 /// name is not represented in the list. In DWARF v5, the files are
276 /// 0-indexed and the primary source file has the index 0.
277 /// Returns true on success.
278 bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir,
280 std::string &Result) const {
281 return Prologue.getFileNameByIndex(FileIndex, CompDir, Kind, Result);
282 }
283
284 /// Fills the Result argument with the file and line information
285 /// corresponding to Address. Returns true on success.
287 object::SectionedAddress Address, bool Approximate, const char *CompDir,
289
290 /// Extracts directory name by its Entry in include directories table
291 /// in prologue. Returns true on success.
293 std::string &Directory) const;
294
295 LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
296 LLVM_ABI void clear();
297
298 /// Parse prologue and all rows.
299 LLVM_ABI Error parse(DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
300 const DWARFContext &Ctx, const DWARFUnit *U,
301 function_ref<void(Error)> RecoverableErrorHandler,
302 raw_ostream *OS = nullptr, bool Verbose = false);
303
304 using RowVector = std::vector<Row>;
305 using RowIter = RowVector::const_iterator;
306 using SequenceVector = std::vector<Sequence>;
307 using SequenceIter = SequenceVector::const_iterator;
308
312
313 private:
314 uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
316 std::optional<StringRef>
317 getSourceByIndex(uint64_t FileIndex,
319
320 uint32_t lookupAddressImpl(object::SectionedAddress Address,
321 bool *IsApproximateLine = nullptr) const;
322
323 /// Fills the Result argument with the indices of the rows that correspond
324 /// to the address range specified by \p Address and \p Size.
325 ///
326 /// \param Address - The starting address of the range.
327 /// \param Size - The size of the address range.
328 /// \param Result - The vector to fill with row indices.
329 /// \param StmtSequenceOffset - if provided, only rows from the sequence
330 /// starting at the matching offset will be added to the result.
331 ///
332 /// Returns true if any rows were found.
333 bool
334 lookupAddressRangeImpl(object::SectionedAddress Address, uint64_t Size,
335 std::vector<uint32_t> &Result,
336 std::optional<uint64_t> StmtSequenceOffset) const;
337 };
338
342 const DWARFContext &Ctx, const DWARFUnit *U,
343 function_ref<void(Error)> RecoverableErrorHandler);
345
346 /// Helper to allow for parsing of an entire .debug_line section in sequence.
348 public:
349 using LineToUnitMap = std::map<uint64_t, DWARFUnit *>;
350
353
354 /// Get the next line table from the section. Report any issues via the
355 /// handlers.
356 ///
357 /// \param RecoverableErrorHandler - any issues that don't prevent further
358 /// parsing of the table will be reported through this handler.
359 /// \param UnrecoverableErrorHandler - any issues that prevent further
360 /// parsing of the table will be reported through this handler.
361 /// \param OS - if not null, the parser will print information about the
362 /// table as it parses it.
363 /// \param Verbose - if true, the parser will print verbose information when
364 /// printing to the output.
366 parseNext(function_ref<void(Error)> RecoverableErrorHandler,
367 function_ref<void(Error)> UnrecoverableErrorHandler,
368 raw_ostream *OS = nullptr, bool Verbose = false);
369
370 /// Skip the current line table and go to the following line table (if
371 /// present) immediately.
372 ///
373 /// \param RecoverableErrorHandler - report any recoverable prologue
374 /// parsing issues via this handler.
375 /// \param UnrecoverableErrorHandler - report any unrecoverable prologue
376 /// parsing issues via this handler.
377 LLVM_ABI void skip(function_ref<void(Error)> RecoverableErrorHandler,
378 function_ref<void(Error)> UnrecoverableErrorHandler);
379
380 /// Indicates if the parser has parsed as much as possible.
381 ///
382 /// \note Certain problems with the line table structure might mean that
383 /// parsing stops before the end of the section is reached.
384 bool done() const { return Done; }
385
386 /// Get the offset the parser has reached.
387 uint64_t getOffset() const { return Offset; }
388
389 private:
390 DWARFUnit *prepareToParse(uint64_t Offset);
391 void moveToNextTable(uint64_t OldOffset, const Prologue &P);
392 bool hasValidVersion(uint64_t Offset);
393
394 LineToUnitMap LineToUnit;
395
396 DWARFDataExtractor &DebugLineData;
397 const DWARFContext &Context;
398 uint64_t Offset = 0;
399 bool Done = false;
400 };
401
402private:
403 struct ParsingState {
404 LLVM_ABI ParsingState(struct LineTable *LT, uint64_t TableOffset,
405 function_ref<void(Error)> ErrorHandler);
406
407 LLVM_ABI void resetRowAndSequence(uint64_t Offset);
408 LLVM_ABI void appendRowToMatrix();
409
413 };
414
415 /// Advance the address and op-index by the \p OperationAdvance value.
416 /// \returns the amount advanced by.
417 LLVM_ABI AddrOpIndexDelta advanceAddrOpIndex(uint64_t OperationAdvance,
418 uint8_t Opcode,
419 uint64_t OpcodeOffset);
420
425 };
426
427 /// Advance the address and op-index as required by the specified \p Opcode.
428 /// \returns the amount advanced by and the calculated adjusted opcode.
429 LLVM_ABI OpcodeAdvanceResults advanceForOpcode(uint8_t Opcode,
430 uint64_t OpcodeOffset);
431
434 int32_t Line;
435 int16_t OpIndex;
436 };
437
438 /// Advance the line, address and op-index as required by the specified
439 /// special \p Opcode. \returns the address, op-index and line delta.
440 LLVM_ABI SpecialOpcodeDelta handleSpecialOpcode(uint8_t Opcode,
441 uint64_t OpcodeOffset);
442
443 /// Line table we're currently parsing.
444 struct LineTable *LineTable;
445 struct Row Row;
446 struct Sequence Sequence;
447
448 private:
449 uint64_t LineTableOffset;
450
451 bool ReportAdvanceAddrProblem = true;
452 bool ReportBadLineRange = true;
454 };
455
456 using LineTableMapTy = std::map<uint64_t, LineTable>;
457 using LineTableIter = LineTableMapTy::iterator;
458 using LineTableConstIter = LineTableMapTy::const_iterator;
459
460 LineTableMapTy LineTableMap;
461};
462
463} // end namespace llvm
464
465#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLINE_H
#define LLVM_ABI
Definition: Compiler.h:213
This file contains constants used for implementing Dwarf debug support.
uint32_t Index
uint64_t Size
static fatal_error_handler_t ErrorHandler
#define P(N)
raw_pwrite_stream & OS
Value * RHS
Value * LHS
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:49
A DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
Helper to allow for parsing of an entire .debug_line section in sequence.
LLVM_ABI void skip(function_ref< void(Error)> RecoverableErrorHandler, function_ref< void(Error)> UnrecoverableErrorHandler)
Skip the current line table and go to the following line table (if present) immediately.
uint64_t getOffset() const
Get the offset the parser has reached.
std::map< uint64_t, DWARFUnit * > LineToUnitMap
LLVM_ABI LineTable parseNext(function_ref< void(Error)> RecoverableErrorHandler, function_ref< void(Error)> UnrecoverableErrorHandler, raw_ostream *OS=nullptr, bool Verbose=false)
Get the next line table from the section.
bool done() const
Indicates if the parser has parsed as much as possible.
LLVM_ABI void clearLineTable(uint64_t Offset)
LLVM_ABI Expected< const LineTable * > getOrParseLineTable(DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx, const DWARFUnit *U, function_ref< void(Error)> RecoverableErrorHandler)
LLVM_ABI const LineTable * getLineTable(uint64_t Offset) const
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
Tagged union holding either a T or a Error.
Definition: Error.h:485
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
#define UINT64_MAX
Definition: DataTypes.h:77
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
LineNumberEntryFormat
Definition: Dwarf.h:794
@ DWARF64
Definition: Dwarf.h:92
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:196
A format-neutral container for source line information.
Definition: DIContext.h:32
Tracks which optional content types are present in a DWARF file name entry format.
bool HasLength
Whether filename entries provide a file size.
bool HasSource
For v5, whether filename entries provide source text.
bool HasModTime
Whether filename entries provide a modification timestamp.
bool HasMD5
For v5, whether filename entries provide an MD5 checksum.
LLVM_ABI void trackContentType(dwarf::LineNumberEntryFormat ContentType)
Update tracked content types with ContentType.
LLVM_ABI uint32_t lookupAddress(object::SectionedAddress Address, bool *IsApproximateLine=nullptr) const
Returns the index of the row with file/line info for a given address, or UnknownRowIndex if there is ...
LLVM_ABI bool getDirectoryForEntry(const FileNameEntry &Entry, std::string &Directory) const
Extracts directory name by its Entry in include directories table in prologue.
const uint32_t UnknownRowIndex
Represents an invalid row.
LLVM_ABI bool getFileLineInfoForAddress(object::SectionedAddress Address, bool Approximate, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
std::optional< uint64_t > getLastValidFileIndex() const
bool hasFileAtIndex(uint64_t FileIndex) const
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
RowVector::const_iterator RowIter
SequenceVector::const_iterator SequenceIter
std::vector< Sequence > SequenceVector
void appendSequence(const DWARFDebugLine::Sequence &S)
LLVM_ABI bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result, std::optional< uint64_t > StmtSequenceOffset=std::nullopt) const
Fills the Result argument with the indices of the rows that correspond to the address range specified...
void appendRow(const DWARFDebugLine::Row &R)
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
uint8_t MaxOpsPerInst
The maximum number of individual operations that may be encoded in an instruction.
uint8_t MinInstLength
The size in bytes of the smallest target machine instruction.
LLVM_ABI bool hasFileAtIndex(uint64_t FileIndex) const
uint64_t PrologueLength
The number of bytes following the prologue_length field to the beginning of the first byte of the sta...
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
uint32_t sizeofTotalLength() const
uint8_t SegSelectorSize
In v5, size in bytes of a segment selector.
int8_t LineBase
This parameter affects the meaning of the special opcodes. See below.
LLVM_ABI std::optional< uint64_t > getLastValidFileIndex() const
uint32_t sizeofPrologueLength() const
uint8_t LineRange
This parameter affects the meaning of the special opcodes. See below.
const dwarf::FormParams getFormParams() const
std::vector< DWARFFormValue > IncludeDirectories
uint8_t OpcodeBase
The number assigned to the first special opcode.
std::vector< uint8_t > StandardOpcodeLengths
LLVM_ABI bool totalLengthIsValid() const
LLVM_ABI const llvm::DWARFDebugLine::FileNameEntry & getFileNameEntry(uint64_t Index) const
Get DWARF-version aware access to the file name entry at the provided index.
LLVM_ABI bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result, sys::path::Style Style=sys::path::Style::native) const
uint8_t DefaultIsStmt
The initial value of theis_stmtregister.
uint64_t TotalLength
The size in bytes of the statement information for this compilation unit (not including the total_len...
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
LLVM_ABI uint64_t getLength() const
Length of the prologue in bytes.
ContentTypeTracker ContentTypes
This tracks which optional file format content types are present.
std::vector< FileNameEntry > FileNames
Standard .debug_line state machine structure.
uint8_t BasicBlock
A boolean indicating that the current instruction is the beginning of a basic block.
static bool orderByAddress(const Row &LHS, const Row &RHS)
uint32_t Line
An unsigned integer indicating a source line number.
uint16_t File
An unsigned integer indicating the identity of the source file corresponding to a machine instruction...
uint32_t Discriminator
An unsigned integer representing the DWARF path discriminator value for this location.
uint8_t EpilogueBegin
A boolean indicating that the current address is one (of possibly many) where execution should be sus...
object::SectionedAddress Address
The program-counter value corresponding to a machine instruction generated by the compiler and sectio...
LLVM_ABI void postAppend()
Called after a row is appended to the matrix.
uint8_t PrologueEnd
A boolean indicating that the current address is one (of possibly many) where execution should be sus...
uint16_t Column
An unsigned integer indicating a column number within a source line.
uint8_t EndSequence
A boolean indicating that the current address is that of the first byte after the end of a sequence o...
static LLVM_ABI void dumpTableHeader(raw_ostream &OS, unsigned Indent)
uint8_t IsStmt
A boolean indicating that the current instruction is the beginning of a statement.
LLVM_ABI void reset(bool DefaultIsStmt)
uint8_t Isa
An unsigned integer whose value encodes the applicable instruction set architecture for the current i...
LLVM_ABI void dump(raw_ostream &OS) const
uint8_t OpIndex
An unsigned integer representing the index of an operation within a VLIW instruction.
Represents a series of contiguous machine instructions.
uint64_t LowPC
Sequence describes instructions at address range [LowPC, HighPC) and is described by line table rows ...
static bool orderByHighPC(const Sequence &LHS, const Sequence &RHS)
bool containsPC(object::SectionedAddress PC) const
uint64_t StmtSeqOffset
The offset into the line table where this sequence begins.
uint64_t SectionIndex
If relocation information is present then this is the index of the section which contains above addre...
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:1093
DwarfFormat Format
Definition: Dwarf.h:1096
Definition: regcomp.c:186