37struct ContentDescriptor {
47 return Version >= 2 && Version <= 6;
52 switch (ContentType) {
53 case dwarf::DW_LNCT_timestamp:
56 case dwarf::DW_LNCT_size:
59 case dwarf::DW_LNCT_MD5:
62 case dwarf::DW_LNCT_LLVM_source:
76 assert(DwarfVersion != 0 &&
77 "line table prologue has no dwarf version information");
78 if (DwarfVersion >= 5)
80 return FileIndex != 0 && FileIndex <=
FileNames.size();
83std::optional<uint64_t>
88 assert(DwarfVersion != 0 &&
89 "line table prologue has no dwarf version information");
91 if (DwarfVersion >= 5)
99 assert(DwarfVersion != 0 &&
100 "line table prologue has no dwarf version information");
102 if (DwarfVersion >= 5)
124 OS <<
"Line table prologue:\n"
125 <<
formatv(
" total_length: 0x{0:x-}\n",
135 " prologue_length: 0x{0:x-}\n",
146 OS <<
formatv(
"standard_opcode_lengths[{0}] = {1}\n",
154 OS <<
formatv(
"include_directories[{0,3}] = ",
I + DirBase);
165 OS <<
formatv(
"file_names[{0,3}]:\n",
I + FileBase);
167 FileEntry.
Name.
dump(OS, DumpOptions);
168 OS <<
'\n' <<
formatv(
" dir_index: {0}\n", FileEntry.
DirIdx);
179 else if ((*Source)[0]) {
194 std::vector<DWARFFormValue> &IncludeDirectories,
195 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
202 "include directories table was not null "
203 "terminated before the end of the prologue");
209 IncludeDirectories.push_back(Dir);
218 if (!Err && Name.empty())
232 "file names table was not null terminated before "
233 "the end of the prologue");
235 FileNames.push_back(FileEntry);
244static llvm::Expected<ContentDescriptors>
248 ContentDescriptors Descriptors;
249 int FormatCount = DebugLineData.
getU8(OffsetPtr, &Err);
250 bool HasPath =
false;
251 for (
int I = 0;
I != FormatCount && !Err; ++
I) {
252 ContentDescriptor Descriptor;
256 if (Descriptor.Type == dwarf::DW_LNCT_path)
260 Descriptors.push_back(Descriptor);
265 "failed to parse entry content descriptors: %s",
270 "failed to parse entry content descriptions"
271 " because no path was found");
280 std::vector<DWARFFormValue> &IncludeDirectories,
281 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
291 for (
auto Descriptor : *DirDescriptors) {
293 switch (Descriptor.Type) {
295 if (!
Value.extractValue(DebugLineData, OffsetPtr,
FormParams, &Ctx, U))
297 "failed to parse directory entry because "
298 "extracting the form value failed");
299 IncludeDirectories.push_back(
Value);
304 "failed to parse directory entry because "
305 "skipping the form value failed");
313 if (!FileDescriptors)
320 for (
auto Descriptor : *FileDescriptors) {
322 if (!
Value.extractValue(DebugLineData, OffsetPtr,
FormParams, &Ctx, U))
324 "failed to parse file entry because "
325 "extracting the form value failed");
326 switch (Descriptor.Type) {
330 case DW_LNCT_LLVM_source:
333 case DW_LNCT_directory_index:
336 case DW_LNCT_timestamp:
343 if (!
Value.getAsBlock() ||
Value.getAsBlock()->size() != 16)
346 "failed to parse file entry because the MD5 hash is invalid");
354 FileNames.push_back(FileEntry);
371 const uint64_t PrologueOffset = *OffsetPtr;
385 *OffsetPtr = Cursor.tell();
388 "parsing line table prologue at offset 0x%8.8" PRIx64
389 ": unsupported version %" PRIu16,
398 if (DataAddrSize == 0) {
399 if (PrologueAddrSize != 4 && PrologueAddrSize != 8) {
402 "parsing line table prologue at offset 0x%8.8" PRIx64
403 ": invalid address size %" PRIu8,
404 PrologueOffset, PrologueAddrSize));
406 }
else if (DataAddrSize != PrologueAddrSize) {
409 "parsing line table prologue at offset 0x%8.8" PRIx64
": address "
410 "size %" PRIu8
" doesn't match architecture address size %" PRIu8,
411 PrologueOffset, PrologueAddrSize, DataAddrSize));
435 "parsing line table prologue at offset 0x%8.8" PRIx64
436 " found opcode base of 0. Assuming no standard opcodes",
446 *OffsetPtr = Cursor.tell();
453 "parsing line table prologue at offset 0x%8.8" PRIx64
": %s",
454 PrologueOffset,
toString(Cursor.takeError()).c_str());
466 "parsing line table prologue at 0x%8.8" PRIx64
467 " found an invalid directory or file table description at"
469 PrologueOffset, *OffsetPtr),
474 assert(*OffsetPtr <= EndPrologueOffset);
475 if (*OffsetPtr != EndPrologueOffset) {
478 "unknown data in line table prologue at offset 0x%8.8" PRIx64
479 ": parsing ended (at offset 0x%8.8" PRIx64
480 ") before reaching the prologue end at offset 0x%8.8" PRIx64,
481 PrologueOffset, *OffsetPtr, EndPrologueOffset));
513 <<
"Address Line Column File ISA Discriminator OpIndex "
516 <<
"------------------ ------ ------ ------ --- ------------- ------- "
566DWARFDebugLine::ParsingState::ParsingState(
571void DWARFDebugLine::ParsingState::resetRowAndSequence(
uint64_t Offset) {
572 Row.reset(LineTable->Prologue.DefaultIsStmt);
574 Sequence.StmtSeqOffset =
Offset;
577void DWARFDebugLine::ParsingState::appendRowToMatrix() {
578 unsigned RowNumber = LineTable->Rows.size();
579 if (Sequence.Empty) {
581 Sequence.Empty =
false;
582 Sequence.LowPC = Row.Address.Address;
583 Sequence.FirstRowIndex = RowNumber;
598const DWARFDebugLine::LineTable *
600 LineTableConstIter Pos = LineTableMap.find(
Offset);
601 if (Pos != LineTableMap.end())
611 "offset 0x%8.8" PRIx64
612 " is not a valid debug line section offset",
615 std::pair<LineTableIter, bool> Pos =
620 LT->parse(DebugLineData, &
Offset, Ctx, U, RecoverableErrorHandler))
621 return std::move(Err);
628 LineTableMap.erase(
Offset);
633 if (Opcode < OpcodeBase)
638DWARFDebugLine::ParsingState::AddrOpIndexDelta
639DWARFDebugLine::ParsingState::advanceAddrOpIndex(uint64_t OperationAdvance,
641 uint64_t OpcodeOffset) {
650 "line table program at offset 0x%8.8" PRIx64
651 " contains a %s opcode at offset 0x%8.8" PRIx64
652 ", but the prologue maximum_operations_per_instruction value is 0"
653 ", which is invalid. Assuming a value of 1 instead",
654 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
663 "line table program at offset 0x%8.8" PRIx64
664 " contains a %s opcode at offset 0x%8.8" PRIx64
665 ", but the prologue maximum_operations_per_instruction value is %" PRId8
666 ", which is experimentally supported, so line number information "
668 LineTableOffset, OpcodeName.
data(), OpcodeOffset,
673 "line table program at offset 0x%8.8" PRIx64
674 " contains a %s opcode at offset 0x%8.8" PRIx64
675 ", but the prologue minimum_instruction_length value "
676 "is 0, which prevents any address advancing",
677 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
678 ReportAdvanceAddrProblem =
false;
691 uint8_t MaxOpsPerInst =
694 uint64_t AddrOffset = ((
Row.
OpIndex + OperationAdvance) / MaxOpsPerInst) *
700 int16_t OpIndexDelta =
static_cast<int16_t
>(
Row.
OpIndex) - PrevOpIndex;
702 return {AddrOffset, OpIndexDelta};
705DWARFDebugLine::ParsingState::OpcodeAdvanceResults
706DWARFDebugLine::ParsingState::advanceForOpcode(uint8_t Opcode,
707 uint64_t OpcodeOffset) {
708 assert(Opcode == DW_LNS_const_add_pc ||
711 StringRef OpcodeName =
715 "line table program at offset 0x%8.8" PRIx64
716 " contains a %s opcode at offset 0x%8.8" PRIx64
717 ", but the prologue line_range value is 0. The "
718 "address and line will not be adjusted",
719 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
720 ReportBadLineRange =
false;
723 uint8_t OpcodeValue = Opcode;
724 if (Opcode == DW_LNS_const_add_pc)
727 uint64_t OperationAdvance =
731 AddrOpIndexDelta Advance =
732 advanceAddrOpIndex(OperationAdvance, Opcode, OpcodeOffset);
733 return {Advance.AddrOffset, Advance.OpIndexDelta, AdjustedOpcode};
736DWARFDebugLine::ParsingState::SpecialOpcodeDelta
737DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
738 uint64_t OpcodeOffset) {
770 DWARFDebugLine::ParsingState::OpcodeAdvanceResults AddrAdvanceResult =
771 advanceForOpcode(Opcode, OpcodeOffset);
772 int32_t LineOffset = 0;
778 return {AddrAdvanceResult.
AddrDelta, LineOffset,
798 assert((OS || !
Verbose) &&
"cannot have verbose output without stream");
799 const uint64_t DebugLineOffset = *OffsetPtr;
804 Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
823 assert(DebugLineData.
size() > DebugLineOffset &&
824 "prologue parsing should handle invalid offset");
825 uint64_t BytesRemaining = DebugLineData.
size() - DebugLineOffset;
826 RecoverableErrorHandler(
828 "line table program with offset 0x%8.8" PRIx64
829 " has length 0x%8.8" PRIx64
" but only 0x%8.8" PRIx64
830 " bytes are available",
831 DebugLineOffset, ProgramLength, BytesRemaining));
833 ProgramLength = BytesRemaining;
838 const uint64_t EndOffset = DebugLineOffset + ProgramLength;
848 ParsingState State(
this, DebugLineOffset, RecoverableErrorHandler);
850 *OffsetPtr = DebugLineOffset +
Prologue.getLength();
851 if (OS && *OffsetPtr < EndOffset) {
857 State.resetRowAndSequence(*OffsetPtr);
859 bool TombstonedAddress =
false;
861 if (!TombstonedAddress) {
868 State.appendRowToMatrix();
871 while (*OffsetPtr < EndOffset) {
875 *OS <<
formatv(
"{0:x8}: ", *OffsetPtr);
879 size_t RowCount =
Rows.size();
882 *OS <<
formatv(
"{0:x-2} ", Opcode);
893 *OS <<
"Badly formed extended line op (length 0)\n";
897 RecoverableErrorHandler(Cursor.takeError());
899 *OffsetPtr = Cursor.tell();
906 uint64_t OperandOffset = Cursor.tell();
910 case DW_LNE_end_sequence:
918 State.Row.EndSequence =
true;
925 State.resetRowAndSequence(Cursor.tell());
928 case DW_LNE_set_address:
941 uint64_t OpcodeAddressSize = Len - 1;
942 if (ExtractorAddressSize != OpcodeAddressSize &&
943 ExtractorAddressSize != 0)
946 "mismatching address size at offset 0x%8.8" PRIx64
947 " expected 0x%2.2" PRIx8
" found 0x%2.2" PRIx64,
948 ExtOffset, ExtractorAddressSize, Len - 1));
953 if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
954 OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
957 "address size 0x%2.2" PRIx64
958 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
960 OpcodeAddressSize, ExtOffset));
961 TableData.
skip(Cursor, OpcodeAddressSize);
965 Cursor, &State.Row.Address.SectionIndex);
966 State.Row.OpIndex = 0;
970 TombstonedAddress = State.Row.Address.Address == Tombstone;
973 if (ExtractorAddressSize != 0)
980 State.Row.Address.Address);
986 case DW_LNE_define_file:
1009 const char *Name = TableData.
getCStr(Cursor);
1015 Prologue.FileNames.push_back(FileEntry);
1017 *OS <<
" (" << Name <<
", dir=" << FileEntry.
DirIdx
1019 <<
", length=" << FileEntry.
Length <<
")";
1023 case DW_LNE_set_discriminator:
1024 State.Row.Discriminator = TableData.
getULEB128(Cursor);
1026 *OS <<
" (" << State.Row.Discriminator <<
")";
1031 *OS <<
formatv(
"Unrecognized extended op {0:x2}", SubOpcode)
1032 <<
formatv(
" length {0:x-}", Len);
1035 TableData.
skip(Cursor, Len - 1);
1043 if (Cursor && Cursor.tell() != End)
1046 "unexpected line op length at offset 0x%8.8" PRIx64
1047 " expected 0x%2.2" PRIx64
" found 0x%2.2" PRIx64,
1048 ExtOffset, Len, Cursor.tell() - ExtOffset));
1053 *OS <<
" (<parsing error>";
1055 *OS <<
formatv(
" {0:x-2}", Byte);
1056 Byte = TableData.
getU8(ByteCursor);
1057 }
while (ByteCursor);
1067 }
else if (Opcode <
Prologue.OpcodeBase) {
1078 case DW_LNS_advance_pc:
1082 if (std::optional<uint64_t> Operand =
1085 State.advanceAddrOpIndex(*Operand, Opcode, OpcodeOffset);
1092 case DW_LNS_advance_line:
1096 int64_t LineDelta = TableData.
getSLEB128(Cursor);
1098 State.Row.Line += LineDelta;
1100 *OS <<
" (" << State.Row.Line <<
")";
1105 case DW_LNS_set_file:
1108 if (std::optional<uint16_t> File =
1110 State.Row.File = *File;
1112 *OS <<
" (" << State.Row.File <<
")";
1116 case DW_LNS_set_column:
1119 if (std::optional<uint16_t> Column =
1121 State.Row.Column = *Column;
1123 *OS <<
" (" << State.Row.Column <<
")";
1127 case DW_LNS_negate_stmt:
1130 State.Row.IsStmt = !State.Row.IsStmt;
1133 case DW_LNS_set_basic_block:
1136 State.Row.BasicBlock =
true;
1139 case DW_LNS_const_add_pc:
1153 State.advanceForOpcode(Opcode, OpcodeOffset);
1155 *OS <<
formatv(
" (addr += {0:x16}, op-index += {1})",
1160 case DW_LNS_fixed_advance_pc:
1174 State.Row.Address.Address += PCOffset;
1175 State.Row.OpIndex = 0;
1177 *OS <<
formatv(
" (addr += {0:x4}, op-index = 0)", PCOffset);
1182 case DW_LNS_set_prologue_end:
1185 State.Row.PrologueEnd =
true;
1188 case DW_LNS_set_epilogue_begin:
1191 State.Row.EpilogueBegin =
true;
1194 case DW_LNS_set_isa:
1197 if (std::optional<uint8_t> Isa =
1199 State.Row.Isa = *Isa;
1201 *OS <<
" (" << (
uint64_t)State.Row.Isa <<
")";
1212 *OS <<
"Unrecognized standard opcode";
1214 std::vector<uint64_t> Operands;
1216 if (std::optional<uint64_t>
Value =
1218 Operands.push_back(*
Value);
1222 if (
Verbose && !Operands.empty()) {
1223 *OS <<
" (operands: ";
1233 *OffsetPtr = Cursor.tell();
1237 State.handleSpecialOpcode(Opcode, OpcodeOffset);
1240 *OS <<
"address += " << Delta.
Address <<
", line += " << Delta.
Line
1241 <<
", op-index += " << Delta.
OpIndex;
1243 *OffsetPtr = Cursor.tell();
1255 if (!Cursor && Opcode != 0) {
1258 return Cursor.takeError();
1262 RecoverableErrorHandler(Cursor.takeError());
1265 if (!State.Sequence.Empty)
1268 "last sequence in debug line table at offset 0x%8.8" PRIx64
1269 " is not terminated",
1292uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1296 return UnknownRowIndex;
1312 RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1,
Row,
1316 return RowPos - Rows.begin();
1321 bool *IsApproximateLine)
const {
1332 return lookupAddressImpl(
Address, IsApproximateLine);
1337 bool *IsApproximateLine)
const {
1338 assert((!IsApproximateLine || !*IsApproximateLine) &&
1339 "Make sure IsApproximateLine is appropriately "
1340 "initialized, if provided");
1347 if (It == Sequences.end() || It->SectionIndex !=
Address.SectionIndex)
1348 return UnknownRowIndex;
1351 if (RowIndex == UnknownRowIndex || !IsApproximateLine)
1355 uint32_t ApproxRowIndex = RowIndex;
1357 for (; ApproxRowIndex >= It->FirstRowIndex; --ApproxRowIndex) {
1358 if (Rows[ApproxRowIndex].Line)
1359 return ApproxRowIndex;
1360 *IsApproximateLine =
true;
1363 if (ApproxRowIndex < It->FirstRowIndex)
1364 *IsApproximateLine =
false;
1371 std::vector<uint32_t> &Result,
1372 std::optional<uint64_t> StmtSequenceOffset)
const {
1375 if (lookupAddressRangeImpl(
Address,
Size, Result, StmtSequenceOffset))
1383 return lookupAddressRangeImpl(
Address,
Size, Result, StmtSequenceOffset);
1386bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1388 std::vector<uint32_t> &Result,
1389 std::optional<uint64_t> StmtSequenceOffset)
const {
1390 if (Sequences.empty())
1397 SequenceIter LastSeq = Sequences.end();
1398 SequenceIter SeqPos;
1400 if (StmtSequenceOffset) {
1403 SeqPos = std::find_if(Sequences.begin(), LastSeq,
1405 return S.StmtSeqOffset == *StmtSequenceOffset;
1409 if (SeqPos == LastSeq)
1414 LastSeq = SeqPos + 1;
1417 SeqPos = std::upper_bound(Sequences.begin(), LastSeq, Sequence,
1419 if (SeqPos == LastSeq)
1424 if (!SeqPos->containsPC(Address))
1427 SequenceIter StartPos = SeqPos;
1430 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
1435 if (SeqPos == StartPos)
1436 FirstRowIndex = findRowInSeq(CurSeq, Address);
1440 findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
1441 if (LastRowIndex == UnknownRowIndex)
1444 assert(FirstRowIndex != UnknownRowIndex);
1445 assert(LastRowIndex != UnknownRowIndex);
1447 for (uint32_t
I = FirstRowIndex;
I <= LastRowIndex; ++
I) {
1457std::optional<StringRef>
1458DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
1459 FileLineInfoKind Kind)
const {
1461 return std::nullopt;
1464 return StringRef(*
E);
1465 return std::nullopt;
1479 if (Kind == FileLineInfoKind::None || !
hasFileAtIndex(FileIndex))
1486 if (Kind == FileLineInfoKind::RawValue ||
1488 Result = std::string(FileName);
1491 if (Kind == FileLineInfoKind::BaseNameOnly) {
1502 if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1514 if (Kind == FileLineInfoKind::AbsoluteFilePath &&
1519 assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1520 Kind == FileLineInfoKind::RelativeFilePath) &&
1521 "invalid FileLineInfo Kind");
1525 Result = std::string(FilePath);
1531 FileLineInfoKind Kind,
DILineInfo &Result)
const {
1535 if (RowIndex == -1U)
1538 const auto &
Row =
Rows[RowIndex];
1544 Result.Source = getSourceByIndex(
Row.
File, Kind);
1551 if (Entry.DirIdx <
Prologue.IncludeDirectories.size()) {
1558 if (0 < Entry.DirIdx && Entry.DirIdx <=
Prologue.IncludeDirectories.size()) {
1573 for (
const auto &U : Units)
1574 if (
auto CUDIE = U->getUnitDIE())
1576 LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
1583 : DebugLineData(
Data), Context(
C) {
1585 if (!DebugLineData.isValidOffset(Offset))
1597 assert(DebugLineData.isValidOffset(Offset) &&
1598 "parsing should have terminated");
1602 if (
Error Err = LT.parse(DebugLineData, &Offset, Context, U,
1603 RecoverableErrorHandler, OS,
Verbose))
1604 UnrecoverableErrorHandler(std::move(Err));
1605 moveToNextTable(OldOffset, LT.Prologue);
1612 assert(DebugLineData.isValidOffset(Offset) &&
1613 "parsing should have terminated");
1617 if (
Error Err = LT.Prologue.parse(DebugLineData, &Offset,
1618 RecoverableErrorHandler, Context, U))
1619 UnrecoverableErrorHandler(std::move(Err));
1620 moveToNextTable(OldOffset, LT.Prologue);
1625 auto It = LineToUnit.find(
Offset);
1626 if (It != LineToUnit.end())
1632bool DWARFDebugLine::SectionParser::hasValidVersion(
uint64_t Offset) {
1647void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
1652 if (!
P.totalLengthIsValid()) {
1657 Offset = OldOffset +
P.TotalLength +
P.sizeofTotalLength();
1665 if (hasValidVersion(
Offset))
1671 for (
unsigned Align : {4, 8}) {
1680 if (hasValidVersion(AlignedOffset)) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const dwarf::FormParams &FormParams, const DWARFContext &Ctx, const DWARFUnit *U, DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector< DWARFFormValue > &IncludeDirectories, std::vector< DWARFDebugLine::FileNameEntry > &FileNames)
static Error parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector< DWARFFormValue > &IncludeDirectories, std::vector< DWARFDebugLine::FileNameEntry > &FileNames)
static llvm::Expected< ContentDescriptors > parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, DWARFDebugLine::ContentTypeTracker *ContentTypes)
static DWARFDebugLine::SectionParser::LineToUnitMap buildLineToUnitMap(DWARFUnitVector::iterator_range Units)
static bool versionIsSupported(uint16_t Version)
static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase)
static std::optional< T > parseULEB128(DWARFDataExtractor &Data, DataExtractor::Cursor &Cursor)
Parse a ULEB128 using the specified Cursor.
This file contains constants used for implementing Dwarf debug support.
static fatal_error_handler_t ErrorHandler
This file defines the SmallString class.
This file defines the SmallVector class.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
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.
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.
LLVM_ABI SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, DWARFUnitVector::iterator_range Units)
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
llvm::iterator_range< UnitVector::iterator > iterator_range
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
A helper class to return the specified delimiter string after the first invocation of operator String...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
LLVM_ABI StringRef LNExtendedString(unsigned Encoding)
LLVM_ABI StringRef FormatString(DwarfFormat Format)
LLVM_ABI StringRef LNStandardString(unsigned Standard)
@ C
The default llvm calling convention, compatible with C.
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
Calculates the starting offsets for various sections within the .debug_names section.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
LineNumberOps
Line Number Standard Opcode Encodings.
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
uint64_t computeTombstoneAddress(uint8_t AddressByteSize)
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
auto uninitialized_copy(R &&Src, IterTy Dst)
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Error joinErrors(Error E1, Error E2)
Concatenate errors.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void consumeError(Error Err)
Consume a Error without doing anything.
Container for dump options that control which debug information will be dumped.
A format-neutral container for source line information.
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.
LLVM_ABI Error parse(DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const DWARFContext &Ctx, const DWARFUnit *U, function_ref< void(Error)> RecoverableErrorHandler, raw_ostream *OS=nullptr, bool Verbose=false)
Parse prologue and all rows.
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
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.
uint16_t getVersion() const
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
LLVM_ABI Error parse(DWARFDataExtractor Data, uint64_t *OffsetPtr, function_ref< void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx, const DWARFUnit *U=nullptr)
uint8_t LineRange
This parameter affects the meaning of the special opcodes. See below.
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
uint8_t getAddressSize() 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)
LLVM_ABI Row(bool DefaultIsStmt=false)
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...
LLVM_ABI SmallString< 32 > digest() const
static const uint64_t UndefSection