36struct ContentDescriptor {
46 return Version >= 2 && Version <= 6;
51 switch (ContentType) {
52 case dwarf::DW_LNCT_timestamp:
55 case dwarf::DW_LNCT_size:
58 case dwarf::DW_LNCT_MD5:
61 case dwarf::DW_LNCT_LLVM_source:
75 assert(DwarfVersion != 0 &&
76 "line table prologue has no dwarf version information");
77 if (DwarfVersion >= 5)
79 return FileIndex != 0 && FileIndex <=
FileNames.size();
82std::optional<uint64_t>
87 assert(DwarfVersion != 0 &&
88 "line table prologue has no dwarf version information");
90 if (DwarfVersion >= 5)
98 assert(DwarfVersion != 0 &&
99 "line table prologue has no dwarf version information");
101 if (DwarfVersion >= 5)
123 OS <<
"Line table prologue:\n"
124 <<
formatv(
" total_length: 0x{0:x-}\n",
134 " prologue_length: 0x{0:x-}\n",
145 OS <<
formatv(
"standard_opcode_lengths[{0}] = {1}\n",
153 OS <<
formatv(
"include_directories[{0,3}] = ",
I + DirBase);
164 OS <<
formatv(
"file_names[{0,3}]:\n",
I + FileBase);
166 FileEntry.
Name.
dump(OS, DumpOptions);
167 OS <<
'\n' <<
formatv(
" dir_index: {0}\n", FileEntry.
DirIdx);
178 else if ((*Source)[0]) {
193 std::vector<DWARFFormValue> &IncludeDirectories,
194 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
201 "include directories table was not null "
202 "terminated before the end of the prologue");
208 IncludeDirectories.push_back(Dir);
217 if (!Err && Name.empty())
231 "file names table was not null terminated before "
232 "the end of the prologue");
234 FileNames.push_back(FileEntry);
243static llvm::Expected<ContentDescriptors>
247 ContentDescriptors Descriptors;
248 int FormatCount = DebugLineData.
getU8(OffsetPtr, &Err);
249 bool HasPath =
false;
250 for (
int I = 0;
I != FormatCount && !Err; ++
I) {
251 ContentDescriptor Descriptor;
255 if (Descriptor.Type == dwarf::DW_LNCT_path)
259 Descriptors.push_back(Descriptor);
264 "failed to parse entry content descriptors: %s",
269 "failed to parse entry content descriptions"
270 " because no path was found");
279 std::vector<DWARFFormValue> &IncludeDirectories,
280 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
290 for (
auto Descriptor : *DirDescriptors) {
292 switch (Descriptor.Type) {
294 if (!
Value.extractValue(DebugLineData, OffsetPtr,
FormParams, &Ctx, U))
296 "failed to parse directory entry because "
297 "extracting the form value failed");
298 IncludeDirectories.push_back(
Value);
303 "failed to parse directory entry because "
304 "skipping the form value failed");
312 if (!FileDescriptors)
319 for (
auto Descriptor : *FileDescriptors) {
321 if (!
Value.extractValue(DebugLineData, OffsetPtr,
FormParams, &Ctx, U))
323 "failed to parse file entry because "
324 "extracting the form value failed");
325 switch (Descriptor.Type) {
329 case DW_LNCT_LLVM_source:
332 case DW_LNCT_directory_index:
335 case DW_LNCT_timestamp:
342 if (!
Value.getAsBlock() ||
Value.getAsBlock()->size() != 16)
345 "failed to parse file entry because the MD5 hash is invalid");
353 FileNames.push_back(FileEntry);
370 const uint64_t PrologueOffset = *OffsetPtr;
384 *OffsetPtr = Cursor.tell();
387 "parsing line table prologue at offset 0x%8.8" PRIx64
388 ": unsupported version %" PRIu16,
397 if (DataAddrSize == 0) {
398 if (PrologueAddrSize != 4 && PrologueAddrSize != 8) {
401 "parsing line table prologue at offset 0x%8.8" PRIx64
402 ": invalid address size %" PRIu8,
403 PrologueOffset, PrologueAddrSize));
405 }
else if (DataAddrSize != PrologueAddrSize) {
408 "parsing line table prologue at offset 0x%8.8" PRIx64
": address "
409 "size %" PRIu8
" doesn't match architecture address size %" PRIu8,
410 PrologueOffset, PrologueAddrSize, DataAddrSize));
418 const uint64_t EndPrologueOffset =
PrologueLength + Cursor.tell();
434 "parsing line table prologue at offset 0x%8.8" PRIx64
435 " found opcode base of 0. Assuming no standard opcodes",
445 *OffsetPtr = Cursor.tell();
452 "parsing line table prologue at offset 0x%8.8" PRIx64
": %s",
453 PrologueOffset,
toString(Cursor.takeError()).c_str());
465 "parsing line table prologue at 0x%8.8" PRIx64
466 " found an invalid directory or file table description at"
468 PrologueOffset, *OffsetPtr),
473 assert(*OffsetPtr <= EndPrologueOffset);
474 if (*OffsetPtr != EndPrologueOffset) {
477 "unknown data in line table prologue at offset 0x%8.8" PRIx64
478 ": parsing ended (at offset 0x%8.8" PRIx64
479 ") before reaching the prologue end at offset 0x%8.8" PRIx64,
480 PrologueOffset, *OffsetPtr, EndPrologueOffset));
512 <<
"Address Line Column File ISA Discriminator OpIndex "
515 <<
"------------------ ------ ------ ------ --- ------------- ------- "
565DWARFDebugLine::ParsingState::ParsingState(
566 struct LineTable *LT, uint64_t TableOffset,
570void DWARFDebugLine::ParsingState::resetRowAndSequence(uint64_t
Offset) {
571 Row.reset(LineTable->Prologue.DefaultIsStmt);
573 Sequence.StmtSeqOffset =
Offset;
576void DWARFDebugLine::ParsingState::appendRowToMatrix() {
577 unsigned RowNumber = LineTable->Rows.size();
578 if (Sequence.Empty) {
580 Sequence.Empty =
false;
581 Sequence.LowPC = Row.Address.Address;
582 Sequence.FirstRowIndex = RowNumber;
597const DWARFDebugLine::LineTable *
599 LineTableConstIter Pos = LineTableMap.find(
Offset);
600 if (Pos != LineTableMap.end())
610 "offset 0x%8.8" PRIx64
611 " is not a valid debug line section offset",
614 std::pair<LineTableIter, bool> Pos =
619 LT->parse(DebugLineData, &
Offset, Ctx, U, RecoverableErrorHandler))
620 return std::move(Err);
627 LineTableMap.erase(
Offset);
632 if (Opcode < OpcodeBase)
637DWARFDebugLine::ParsingState::AddrOpIndexDelta
638DWARFDebugLine::ParsingState::advanceAddrOpIndex(
uint64_t OperationAdvance,
649 "line table program at offset 0x%8.8" PRIx64
650 " contains a %s opcode at offset 0x%8.8" PRIx64
651 ", but the prologue maximum_operations_per_instruction value is 0"
652 ", which is invalid. Assuming a value of 1 instead",
653 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
662 "line table program at offset 0x%8.8" PRIx64
663 " contains a %s opcode at offset 0x%8.8" PRIx64
664 ", but the prologue maximum_operations_per_instruction value is %" PRId8
665 ", which is experimentally supported, so line number information "
667 LineTableOffset, OpcodeName.
data(), OpcodeOffset,
672 "line table program at offset 0x%8.8" PRIx64
673 " contains a %s opcode at offset 0x%8.8" PRIx64
674 ", but the prologue minimum_instruction_length value "
675 "is 0, which prevents any address advancing",
676 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
677 ReportAdvanceAddrProblem =
false;
690 uint8_t MaxOpsPerInst =
699 int16_t OpIndexDelta =
static_cast<int16_t
>(
Row.
OpIndex) - PrevOpIndex;
701 return {AddrOffset, OpIndexDelta};
704DWARFDebugLine::ParsingState::OpcodeAdvanceResults
705DWARFDebugLine::ParsingState::advanceForOpcode(uint8_t Opcode,
707 assert(Opcode == DW_LNS_const_add_pc ||
710 StringRef OpcodeName =
714 "line table program at offset 0x%8.8" PRIx64
715 " contains a %s opcode at offset 0x%8.8" PRIx64
716 ", but the prologue line_range value is 0. The "
717 "address and line will not be adjusted",
718 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
719 ReportBadLineRange =
false;
722 uint8_t OpcodeValue = Opcode;
723 if (Opcode == DW_LNS_const_add_pc)
730 AddrOpIndexDelta Advance =
731 advanceAddrOpIndex(OperationAdvance, Opcode, OpcodeOffset);
732 return {Advance.AddrOffset, Advance.OpIndexDelta, AdjustedOpcode};
735DWARFDebugLine::ParsingState::SpecialOpcodeDelta
736DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
769 DWARFDebugLine::ParsingState::OpcodeAdvanceResults AddrAdvanceResult =
770 advanceForOpcode(Opcode, OpcodeOffset);
771 int32_t LineOffset = 0;
777 return {AddrAdvanceResult.
AddrDelta, LineOffset,
797 assert((OS || !
Verbose) &&
"cannot have verbose output without stream");
798 const uint64_t DebugLineOffset = *OffsetPtr;
803 Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
819 uint64_t ProgramLength =
Prologue.TotalLength +
Prologue.sizeofTotalLength();
822 assert(DebugLineData.
size() > DebugLineOffset &&
823 "prologue parsing should handle invalid offset");
824 uint64_t BytesRemaining = DebugLineData.
size() - DebugLineOffset;
825 RecoverableErrorHandler(
827 "line table program with offset 0x%8.8" PRIx64
828 " has length 0x%8.8" PRIx64
" but only 0x%8.8" PRIx64
829 " bytes are available",
830 DebugLineOffset, ProgramLength, BytesRemaining));
832 ProgramLength = BytesRemaining;
837 const uint64_t EndOffset = DebugLineOffset + ProgramLength;
847 ParsingState State(
this, DebugLineOffset, RecoverableErrorHandler);
849 *OffsetPtr = DebugLineOffset +
Prologue.getLength();
850 if (OS && *OffsetPtr < EndOffset) {
856 State.resetRowAndSequence(*OffsetPtr);
858 bool TombstonedAddress =
false;
860 if (!TombstonedAddress) {
867 State.appendRowToMatrix();
870 while (*OffsetPtr < EndOffset) {
874 *OS <<
formatv(
"{0:x8}: ", *OffsetPtr);
876 uint64_t OpcodeOffset = *OffsetPtr;
878 size_t RowCount =
Rows.size();
881 *OS <<
formatv(
"{0:x-2} ", Opcode);
887 uint64_t ExtOffset = Cursor.tell();
892 *OS <<
"Badly formed extended line op (length 0)\n";
896 RecoverableErrorHandler(Cursor.takeError());
898 *OffsetPtr = Cursor.tell();
905 uint64_t OperandOffset = Cursor.tell();
909 case DW_LNE_end_sequence:
917 State.Row.EndSequence =
true;
924 State.resetRowAndSequence(Cursor.tell());
927 case DW_LNE_set_address:
940 uint64_t OpcodeAddressSize = Len - 1;
941 if (ExtractorAddressSize != OpcodeAddressSize &&
942 ExtractorAddressSize != 0)
945 "mismatching address size at offset 0x%8.8" PRIx64
946 " expected 0x%2.2" PRIx8
" found 0x%2.2" PRIx64,
947 ExtOffset, ExtractorAddressSize, Len - 1));
952 if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
953 OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
956 "address size 0x%2.2" PRIx64
957 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
959 OpcodeAddressSize, ExtOffset));
960 TableData.
skip(Cursor, OpcodeAddressSize);
964 Cursor, &State.Row.Address.SectionIndex);
965 State.Row.OpIndex = 0;
969 TombstonedAddress = State.Row.Address.Address == Tombstone;
972 if (ExtractorAddressSize != 0)
979 State.Row.Address.Address);
985 case DW_LNE_define_file:
1008 const char *Name = TableData.
getCStr(Cursor);
1014 Prologue.FileNames.push_back(FileEntry);
1016 *OS <<
" (" << Name <<
", dir=" << FileEntry.
DirIdx
1018 <<
", length=" << FileEntry.
Length <<
")";
1022 case DW_LNE_set_discriminator:
1023 State.Row.Discriminator = TableData.
getULEB128(Cursor);
1025 *OS <<
" (" << State.Row.Discriminator <<
")";
1030 *OS <<
formatv(
"Unrecognized extended op {0:x2}", SubOpcode)
1031 <<
formatv(
" length {0:x-}", Len);
1034 TableData.
skip(Cursor, Len - 1);
1041 uint64_t End = ExtOffset + Len;
1042 if (Cursor && Cursor.tell() != End)
1045 "unexpected line op length at offset 0x%8.8" PRIx64
1046 " expected 0x%2.2" PRIx64
" found 0x%2.2" PRIx64,
1047 ExtOffset, Len, Cursor.tell() - ExtOffset));
1052 *OS <<
" (<parsing error>";
1054 *OS <<
formatv(
" {0:x-2}", Byte);
1055 Byte = TableData.
getU8(ByteCursor);
1056 }
while (ByteCursor);
1066 }
else if (Opcode <
Prologue.OpcodeBase) {
1077 case DW_LNS_advance_pc:
1081 if (std::optional<uint64_t> Operand =
1084 State.advanceAddrOpIndex(*Operand, Opcode, OpcodeOffset);
1091 case DW_LNS_advance_line:
1095 int64_t LineDelta = TableData.
getSLEB128(Cursor);
1097 State.Row.Line += LineDelta;
1099 *OS <<
" (" << State.Row.Line <<
")";
1104 case DW_LNS_set_file:
1107 if (std::optional<uint16_t> File =
1109 State.Row.File = *File;
1111 *OS <<
" (" << State.Row.File <<
")";
1115 case DW_LNS_set_column:
1118 if (std::optional<uint16_t> Column =
1120 State.Row.Column = *Column;
1122 *OS <<
" (" << State.Row.Column <<
")";
1126 case DW_LNS_negate_stmt:
1129 State.Row.IsStmt = !State.Row.IsStmt;
1132 case DW_LNS_set_basic_block:
1135 State.Row.BasicBlock =
true;
1138 case DW_LNS_const_add_pc:
1152 State.advanceForOpcode(Opcode, OpcodeOffset);
1154 *OS <<
formatv(
" (addr += {0:x16}, op-index += {1})",
1159 case DW_LNS_fixed_advance_pc:
1173 State.Row.Address.Address += PCOffset;
1174 State.Row.OpIndex = 0;
1176 *OS <<
formatv(
" (addr += {0:x4}, op-index = 0)", PCOffset);
1181 case DW_LNS_set_prologue_end:
1184 State.Row.PrologueEnd =
true;
1187 case DW_LNS_set_epilogue_begin:
1190 State.Row.EpilogueBegin =
true;
1193 case DW_LNS_set_isa:
1196 if (std::optional<uint8_t> Isa =
1198 State.Row.Isa = *Isa;
1200 *OS <<
" (" << (uint64_t)State.Row.Isa <<
")";
1211 *OS <<
"Unrecognized standard opcode";
1215 if (std::optional<uint64_t>
Value =
1222 *OS <<
" (operands: ";
1232 *OffsetPtr = Cursor.tell();
1236 State.handleSpecialOpcode(Opcode, OpcodeOffset);
1239 *OS <<
"address += " << Delta.
Address <<
", line += " << Delta.
Line
1240 <<
", op-index += " << Delta.
OpIndex;
1242 *OffsetPtr = Cursor.tell();
1254 if (!Cursor && Opcode != 0) {
1257 return Cursor.takeError();
1261 RecoverableErrorHandler(Cursor.takeError());
1264 if (!State.Sequence.Empty)
1267 "last sequence in debug line table at offset 0x%8.8" PRIx64
1268 " is not terminated",
1271 Rows.shrink_to_fit();
1294uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1298 return UnknownRowIndex;
1314 RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1,
Row,
1318 return RowPos - Rows.begin();
1323 bool *IsApproximateLine)
const {
1334 return lookupAddressImpl(
Address, IsApproximateLine);
1339 bool *IsApproximateLine)
const {
1340 assert((!IsApproximateLine || !*IsApproximateLine) &&
1341 "Make sure IsApproximateLine is appropriately "
1342 "initialized, if provided");
1349 if (It == Sequences.end() || It->SectionIndex !=
Address.SectionIndex)
1350 return UnknownRowIndex;
1353 if (RowIndex == UnknownRowIndex || !IsApproximateLine)
1357 uint32_t ApproxRowIndex = RowIndex;
1359 for (; ApproxRowIndex >= It->FirstRowIndex; --ApproxRowIndex) {
1360 if (Rows[ApproxRowIndex].Line)
1361 return ApproxRowIndex;
1362 *IsApproximateLine =
true;
1365 if (ApproxRowIndex < It->FirstRowIndex)
1366 *IsApproximateLine =
false;
1373 std::vector<uint32_t> &Result,
1374 std::optional<uint64_t> StmtSequenceOffset)
const {
1377 if (lookupAddressRangeImpl(
Address,
Size, Result, StmtSequenceOffset))
1385 return lookupAddressRangeImpl(
Address,
Size, Result, StmtSequenceOffset);
1388bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1390 std::vector<uint32_t> &Result,
1391 std::optional<uint64_t> StmtSequenceOffset)
const {
1392 if (Sequences.empty())
1399 SequenceIter LastSeq = Sequences.end();
1400 SequenceIter SeqPos;
1402 if (StmtSequenceOffset) {
1405 SeqPos = std::find_if(Sequences.begin(), LastSeq,
1407 return S.StmtSeqOffset == *StmtSequenceOffset;
1411 if (SeqPos == LastSeq)
1416 LastSeq = SeqPos + 1;
1419 SeqPos = std::upper_bound(Sequences.begin(), LastSeq, Sequence,
1421 if (SeqPos == LastSeq)
1426 if (!SeqPos->containsPC(Address))
1429 SequenceIter StartPos = SeqPos;
1432 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
1437 if (SeqPos == StartPos)
1438 FirstRowIndex = findRowInSeq(CurSeq, Address);
1442 findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
1443 if (LastRowIndex == UnknownRowIndex)
1446 assert(FirstRowIndex != UnknownRowIndex);
1447 assert(LastRowIndex != UnknownRowIndex);
1449 for (uint32_t
I = FirstRowIndex;
I <= LastRowIndex; ++
I) {
1459std::optional<StringRef>
1460DWARFDebugLine::LineTable::getSourceByIndex(
uint64_t FileIndex,
1461 FileLineInfoKind Kind)
const {
1463 return std::nullopt;
1466 return StringRef(*
E);
1467 return std::nullopt;
1479 uint64_t FileIndex,
StringRef CompDir, FileLineInfoKind Kind,
1481 if (Kind == FileLineInfoKind::None || !
hasFileAtIndex(FileIndex))
1488 if (Kind == FileLineInfoKind::RawValue ||
1490 Result = std::string(FileName);
1493 if (Kind == FileLineInfoKind::BaseNameOnly) {
1504 if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1516 if (Kind == FileLineInfoKind::AbsoluteFilePath &&
1521 assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1522 Kind == FileLineInfoKind::RelativeFilePath) &&
1523 "invalid FileLineInfo Kind");
1527 Result = std::string(FilePath);
1533 FileLineInfoKind Kind,
DILineInfo &Result)
const {
1537 if (RowIndex == -1U)
1540 const auto &
Row =
Rows[RowIndex];
1546 Result.Source = getSourceByIndex(
Row.
File, Kind);
1553 if (Entry.DirIdx <
Prologue.IncludeDirectories.size()) {
1560 if (0 < Entry.DirIdx && Entry.DirIdx <=
Prologue.IncludeDirectories.size()) {
1575 for (
const auto &U : Units)
1576 if (
auto CUDIE = U->getUnitDIE())
1578 LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
1585 : DebugLineData(
Data), Context(
C) {
1587 if (!DebugLineData.isValidOffset(Offset))
1599 assert(DebugLineData.isValidOffset(Offset) &&
1600 "parsing should have terminated");
1602 uint64_t OldOffset = Offset;
1604 if (
Error Err = LT.parse(DebugLineData, &Offset, Context, U,
1605 RecoverableErrorHandler, OS,
Verbose))
1606 UnrecoverableErrorHandler(std::move(Err));
1607 moveToNextTable(OldOffset, LT.Prologue);
1614 assert(DebugLineData.isValidOffset(Offset) &&
1615 "parsing should have terminated");
1617 uint64_t OldOffset = Offset;
1619 if (
Error Err = LT.Prologue.parse(DebugLineData, &Offset,
1620 RecoverableErrorHandler, Context, U))
1621 UnrecoverableErrorHandler(std::move(Err));
1622 moveToNextTable(OldOffset, LT.Prologue);
1625DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t
Offset) {
1627 auto It = LineToUnit.find(
Offset);
1628 if (It != LineToUnit.end())
1634bool DWARFDebugLine::SectionParser::hasValidVersion(uint64_t
Offset) {
1638 uint16_t
Version = HeaderData.getU16(Cursor);
1649void DWARFDebugLine::SectionParser::moveToNextTable(
uint64_t OldOffset,
1654 if (!
P.totalLengthIsValid()) {
1659 Offset = OldOffset +
P.TotalLength +
P.sizeofTotalLength();
1667 if (hasValidVersion(
Offset))
1673 for (
unsigned Align : {4, 8}) {
1682 if (hasValidVersion(AlignedOffset)) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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)
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.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
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.
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