35struct ContentDescriptor {
45 return Version >= 2 && Version <= 5;
50 switch (ContentType) {
51 case dwarf::DW_LNCT_timestamp:
54 case dwarf::DW_LNCT_size:
57 case dwarf::DW_LNCT_MD5:
60 case dwarf::DW_LNCT_LLVM_source:
73 uint16_t DwarfVersion = getVersion();
74 assert(DwarfVersion != 0 &&
75 "line table prologue has no dwarf version information");
76 if (DwarfVersion >= 5)
77 return FileIndex < FileNames.size();
78 return FileIndex != 0 && FileIndex <= FileNames.size();
81std::optional<uint64_t>
83 if (FileNames.empty())
85 uint16_t DwarfVersion = getVersion();
86 assert(DwarfVersion != 0 &&
87 "line table prologue has no dwarf version information");
89 if (DwarfVersion >= 5)
90 return FileNames.size() - 1;
91 return FileNames.size();
96 uint16_t DwarfVersion = getVersion();
97 assert(DwarfVersion != 0 &&
98 "line table prologue has no dwarf version information");
100 if (DwarfVersion >= 5)
101 return FileNames[
Index];
102 return FileNames[
Index - 1];
106 TotalLength = PrologueLength = 0;
108 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
112 StandardOpcodeLengths.clear();
113 IncludeDirectories.clear();
119 if (!totalLengthIsValid())
122 OS <<
"Line table prologue:\n"
123 <<
format(
" total_length: 0x%0*" PRIx64
"\n", OffsetDumpWidth,
126 <<
format(
" version: %u\n", getVersion());
129 if (getVersion() >= 5)
130 OS <<
format(
" address_size: %u\n", getAddressSize())
131 <<
format(
" seg_select_size: %u\n", SegSelectorSize);
132 OS <<
format(
" prologue_length: 0x%0*" PRIx64
"\n", OffsetDumpWidth,
134 <<
format(
" min_inst_length: %u\n", MinInstLength)
135 <<
format(getVersion() >= 4 ?
"max_ops_per_inst: %u\n" :
"", MaxOpsPerInst)
136 <<
format(
" default_is_stmt: %u\n", DefaultIsStmt)
137 <<
format(
" line_base: %i\n", LineBase)
138 <<
format(
" line_range: %u\n", LineRange)
139 <<
format(
" opcode_base: %u\n", OpcodeBase);
141 for (
uint32_t I = 0;
I != StandardOpcodeLengths.size(); ++
I)
142 OS <<
formatv(
"standard_opcode_lengths[{0}] = {1}\n",
144 StandardOpcodeLengths[
I]);
146 if (!IncludeDirectories.empty()) {
148 uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
149 for (
uint32_t I = 0;
I != IncludeDirectories.size(); ++
I) {
150 OS <<
format(
"include_directories[%3u] = ",
I + DirBase);
151 IncludeDirectories[
I].dump(
OS, DumpOptions);
156 if (!FileNames.empty()) {
158 uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
161 OS <<
format(
"file_names[%3u]:\n",
I + FileBase);
165 <<
format(
" dir_index: %" PRIu64
"\n", FileEntry.
DirIdx);
166 if (ContentTypes.HasMD5)
168 if (ContentTypes.HasModTime)
170 if (ContentTypes.HasLength)
172 if (ContentTypes.HasSource) {
186 std::vector<DWARFFormValue> &IncludeDirectories,
187 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
194 "include directories table was not null "
195 "terminated before the end of the prologue");
201 IncludeDirectories.push_back(Dir);
210 if (!Err &&
Name.empty())
224 "file names table was not null terminated before "
225 "the end of the prologue");
227 FileNames.push_back(FileEntry);
240 ContentDescriptors Descriptors;
241 int FormatCount = DebugLineData.
getU8(OffsetPtr, &Err);
242 bool HasPath =
false;
243 for (
int I = 0;
I != FormatCount && !Err; ++
I) {
244 ContentDescriptor Descriptor;
248 if (Descriptor.Type == dwarf::DW_LNCT_path)
252 Descriptors.push_back(Descriptor);
257 "failed to parse entry content descriptors: %s",
262 "failed to parse entry content descriptions"
263 " because no path was found");
272 std::vector<DWARFFormValue> &IncludeDirectories,
273 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
283 for (
auto Descriptor : *DirDescriptors) {
285 switch (Descriptor.Type) {
287 if (!
Value.extractValue(DebugLineData, OffsetPtr,
FormParams, &Ctx, U))
289 "failed to parse directory entry because "
290 "extracting the form value failed");
291 IncludeDirectories.push_back(
Value);
296 "failed to parse directory entry because "
297 "skipping the form value failed");
305 if (!FileDescriptors)
312 for (
auto Descriptor : *FileDescriptors) {
314 if (!
Value.extractValue(DebugLineData, OffsetPtr,
FormParams, &Ctx, U))
316 "failed to parse file entry because "
317 "extracting the form value failed");
318 switch (Descriptor.Type) {
322 case DW_LNCT_LLVM_source:
325 case DW_LNCT_directory_index:
328 case DW_LNCT_timestamp:
335 if (!
Value.getAsBlock() ||
Value.getAsBlock()->size() != 16)
338 "failed to parse file entry because the MD5 hash is invalid");
339 std::uninitialized_copy_n(
Value.getAsBlock()->begin(), 16,
346 FileNames.push_back(FileEntry);
353 sizeof(getVersion()) + sizeofPrologueLength();
354 if (getVersion() >= 5)
363 const uint64_t PrologueOffset = *OffsetPtr;
377 *OffsetPtr = Cursor.
tell();
380 "parsing line table prologue at offset 0x%8.8" PRIx64
381 ": unsupported version %" PRIu16,
382 PrologueOffset, getVersion());
385 if (getVersion() >= 5) {
389 "Line table header and data extractor disagree");
390 SegSelectorSize = DebugLineData.
getU8(Cursor);
395 const uint64_t EndPrologueOffset = PrologueLength + Cursor.
tell();
397 MinInstLength = DebugLineData.
getU8(Cursor);
398 if (getVersion() >= 4)
399 MaxOpsPerInst = DebugLineData.
getU8(Cursor);
400 DefaultIsStmt = DebugLineData.
getU8(Cursor);
401 LineBase = DebugLineData.
getU8(Cursor);
402 LineRange = DebugLineData.
getU8(Cursor);
403 OpcodeBase = DebugLineData.
getU8(Cursor);
405 if (Cursor && OpcodeBase == 0) {
411 "parsing line table prologue at offset 0x%8.8" PRIx64
412 " found opcode base of 0. Assuming no standard opcodes",
415 StandardOpcodeLengths.reserve(OpcodeBase - 1);
417 uint8_t OpLen = DebugLineData.
getU8(Cursor);
418 StandardOpcodeLengths.push_back(OpLen);
422 *OffsetPtr = Cursor.
tell();
429 "parsing line table prologue at offset 0x%8.8" PRIx64
": %s",
435 ContentTypes, IncludeDirectories, FileNames)
437 IncludeDirectories, FileNames);
442 "parsing line table prologue at 0x%8.8" PRIx64
443 " found an invalid directory or file table description at"
445 PrologueOffset, *OffsetPtr),
450 assert(*OffsetPtr <= EndPrologueOffset);
451 if (*OffsetPtr != EndPrologueOffset) {
454 "unknown data in line table prologue at offset 0x%8.8" PRIx64
455 ": parsing ended (at offset 0x%8.8" PRIx64
456 ") before reaching the prologue end at offset 0x%8.8" PRIx64,
457 PrologueOffset, *OffsetPtr, EndPrologueOffset));
468 EpilogueBegin =
false;
479 IsStmt = DefaultIsStmt;
483 EpilogueBegin =
false;
488 <<
"Address Line Column File ISA Discriminator Flags\n";
490 <<
"------------------ ------ ------ ------ --- ------------- "
495 OS <<
format(
"0x%16.16" PRIx64
" %6u %6u",
Address.Address, Line, Column)
496 <<
format(
" %6u %3u %13u ", File, Isa, Discriminator)
497 << (IsStmt ?
" is_stmt" :
"") << (
BasicBlock ?
" basic_block" :
"")
498 << (PrologueEnd ?
" prologue_end" :
"")
499 << (EpilogueBegin ?
" epilogue_begin" :
"")
523 for (
const Row &R : Rows) {
539DWARFDebugLine::ParsingState::ParsingState(
543 resetRowAndSequence();
546void DWARFDebugLine::ParsingState::resetRowAndSequence() {
547 Row.reset(LineTable->Prologue.DefaultIsStmt);
551void DWARFDebugLine::ParsingState::appendRowToMatrix() {
552 unsigned RowNumber = LineTable->Rows.size();
553 if (Sequence.Empty) {
555 Sequence.Empty =
false;
556 Sequence.LowPC = Row.Address.Address;
557 Sequence.FirstRowIndex = RowNumber;
559 LineTable->appendRow(Row);
560 if (Row.EndSequence) {
562 Sequence.HighPC = Row.Address.Address;
563 Sequence.LastRowIndex = RowNumber + 1;
564 Sequence.SectionIndex = Row.Address.SectionIndex;
566 LineTable->appendSequence(Sequence);
574 LineTableConstIter Pos = LineTableMap.find(
Offset);
575 if (Pos != LineTableMap.end())
585 " is not a valid debug line section offset",
588 std::pair<LineTableIter, bool> Pos =
593 LT->parse(DebugLineData, &
Offset, Ctx, U, RecoverableErrorHandler))
594 return std::move(Err);
601 LineTableMap.erase(
Offset);
606 if (Opcode < OpcodeBase)
611uint64_t DWARFDebugLine::ParsingState::advanceAddr(
uint64_t OperationAdvance,
618 if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
619 LineTable->Prologue.MaxOpsPerInst != 1)
622 "line table program at offset 0x%8.8" PRIx64
623 " contains a %s opcode at offset 0x%8.8" PRIx64
624 ", but the prologue maximum_operations_per_instruction value is %" PRId8
625 ", which is unsupported. Assuming a value of 1 instead",
626 LineTableOffset, OpcodeName.
data(), OpcodeOffset,
627 LineTable->Prologue.MaxOpsPerInst));
628 if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
631 "line table program at offset 0x%8.8" PRIx64
632 " contains a %s opcode at offset 0x%8.8" PRIx64
633 ", but the prologue minimum_instruction_length value "
634 "is 0, which prevents any address advancing",
635 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
636 ReportAdvanceAddrProblem =
false;
637 uint64_t AddrOffset = OperationAdvance * LineTable->Prologue.MinInstLength;
638 Row.Address.Address += AddrOffset;
643DWARFDebugLine::ParsingState::advanceAddrForOpcode(uint8_t Opcode,
645 assert(Opcode == DW_LNS_const_add_pc ||
646 Opcode >= LineTable->Prologue.OpcodeBase);
647 if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
652 "line table program at offset 0x%8.8" PRIx64
653 " contains a %s opcode at offset 0x%8.8" PRIx64
654 ", but the prologue line_range value is 0. The "
655 "address and line will not be adjusted",
656 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
657 ReportBadLineRange =
false;
660 uint8_t OpcodeValue = Opcode;
661 if (Opcode == DW_LNS_const_add_pc)
663 uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
665 LineTable->Prologue.LineRange != 0
666 ? AdjustedOpcode / LineTable->Prologue.LineRange
668 uint64_t AddrOffset = advanceAddr(OperationAdvance, Opcode, OpcodeOffset);
669 return {AddrOffset, AdjustedOpcode};
673DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
707 advanceAddrForOpcode(Opcode, OpcodeOffset);
708 int32_t LineOffset = 0;
709 if (LineTable->Prologue.LineRange != 0)
711 LineTable->Prologue.LineBase +
712 (AddrAdvanceResult.
AdjustedOpcode % LineTable->Prologue.LineRange);
713 Row.Line += LineOffset;
714 return {AddrAdvanceResult.
AddrDelta, LineOffset};
733 assert((
OS || !
Verbose) &&
"cannot have verbose output without stream");
734 const uint64_t DebugLineOffset = *OffsetPtr;
739 Prologue.
parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
758 assert(DebugLineData.
size() > DebugLineOffset &&
759 "prologue parsing should handle invalid offset");
760 uint64_t BytesRemaining = DebugLineData.
size() - DebugLineOffset;
761 RecoverableErrorHandler(
763 "line table program with offset 0x%8.8" PRIx64
764 " has length 0x%8.8" PRIx64
" but only 0x%8.8" PRIx64
765 " bytes are available",
766 DebugLineOffset, ProgramLength, BytesRemaining));
768 ProgramLength = BytesRemaining;
773 const uint64_t EndOffset = DebugLineOffset + ProgramLength;
783 ParsingState State(
this, DebugLineOffset, RecoverableErrorHandler);
786 if (
OS && *OffsetPtr < EndOffset) {
790 bool TombstonedAddress =
false;
792 if (!TombstonedAddress) {
799 State.appendRowToMatrix();
802 while (*OffsetPtr < EndOffset) {
806 *
OS <<
format(
"0x%08.08" PRIx64
": ", *OffsetPtr);
809 uint8_t Opcode = TableData.
getU8(Cursor);
810 size_t RowCount = Rows.size();
813 *
OS <<
format(
"%02.02" PRIx8
" ", Opcode);
824 *
OS <<
"Badly formed extended line op (length 0)\n";
828 RecoverableErrorHandler(Cursor.
takeError());
830 *OffsetPtr = Cursor.
tell();
834 uint8_t SubOpcode = TableData.
getU8(Cursor);
841 case DW_LNE_end_sequence:
849 State.Row.EndSequence =
true;
854 State.resetRowAndSequence();
857 case DW_LNE_set_address:
869 uint64_t OpcodeAddressSize = Len - 1;
870 if (ExtractorAddressSize != OpcodeAddressSize &&
871 ExtractorAddressSize != 0)
874 "mismatching address size at offset 0x%8.8" PRIx64
875 " expected 0x%2.2" PRIx8
" found 0x%2.2" PRIx64,
876 ExtOffset, ExtractorAddressSize, Len - 1));
881 if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
882 OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
885 "address size 0x%2.2" PRIx64
886 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
888 OpcodeAddressSize, ExtOffset));
889 TableData.
skip(Cursor, OpcodeAddressSize);
893 Cursor, &State.Row.Address.SectionIndex);
897 TombstonedAddress = State.Row.Address.Address == Tombstone;
900 if (ExtractorAddressSize != 0)
912 case DW_LNE_define_file:
943 *
OS <<
" (" <<
Name <<
", dir=" << FileEntry.
DirIdx <<
", mod_time="
945 <<
", length=" << FileEntry.
Length <<
")";
949 case DW_LNE_set_discriminator:
950 State.Row.Discriminator = TableData.
getULEB128(Cursor);
952 *
OS <<
" (" << State.Row.Discriminator <<
")";
957 *
OS <<
format(
"Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
958 <<
format(
" length %" PRIx64, Len);
961 TableData.
skip(Cursor, Len - 1);
969 if (Cursor && Cursor.
tell() !=
End)
972 "unexpected line op length at offset 0x%8.8" PRIx64
973 " expected 0x%2.2" PRIx64
" found 0x%2.2" PRIx64,
974 ExtOffset, Len, Cursor.
tell() - ExtOffset));
977 uint8_t Byte = TableData.
getU8(ByteCursor);
979 *
OS <<
" (<parsing error>";
982 Byte = TableData.
getU8(ByteCursor);
983 }
while (ByteCursor);
1004 case DW_LNS_advance_pc:
1008 if (std::optional<uint64_t> Operand =
1009 parseULEB128<uint64_t>(TableData, Cursor)) {
1011 State.advanceAddr(*Operand, Opcode, OpcodeOffset);
1013 *
OS <<
" (" << AddrOffset <<
")";
1017 case DW_LNS_advance_line:
1021 int64_t LineDelta = TableData.
getSLEB128(Cursor);
1023 State.Row.Line += LineDelta;
1025 *
OS <<
" (" << State.Row.Line <<
")";
1030 case DW_LNS_set_file:
1033 if (std::optional<uint16_t> File =
1034 parseULEB128<uint16_t>(TableData, Cursor)) {
1035 State.Row.File = *File;
1037 *
OS <<
" (" << State.Row.File <<
")";
1041 case DW_LNS_set_column:
1044 if (std::optional<uint16_t> Column =
1045 parseULEB128<uint16_t>(TableData, Cursor)) {
1046 State.Row.Column = *Column;
1048 *
OS <<
" (" << State.Row.Column <<
")";
1052 case DW_LNS_negate_stmt:
1055 State.Row.IsStmt = !State.Row.IsStmt;
1058 case DW_LNS_set_basic_block:
1061 State.Row.BasicBlock =
true;
1064 case DW_LNS_const_add_pc:
1078 State.advanceAddrForOpcode(Opcode, OpcodeOffset).AddrDelta;
1080 *
OS <<
format(
" (0x%16.16" PRIx64
")", AddrOffset);
1084 case DW_LNS_fixed_advance_pc:
1098 State.Row.Address.Address += PCOffset;
1100 *
OS <<
format(
" (0x%4.4" PRIx16
")", PCOffset);
1105 case DW_LNS_set_prologue_end:
1108 State.Row.PrologueEnd =
true;
1111 case DW_LNS_set_epilogue_begin:
1114 State.Row.EpilogueBegin =
true;
1117 case DW_LNS_set_isa:
1120 if (std::optional<uint8_t> Isa =
1121 parseULEB128<uint8_t>(TableData, Cursor)) {
1122 State.Row.Isa = *Isa;
1124 *
OS <<
" (" << (
uint64_t)State.Row.Isa <<
")";
1135 *
OS <<
"Unrecognized standard opcode";
1138 for (uint8_t
I = 0;
I < OpcodeLength; ++
I) {
1139 if (std::optional<uint64_t>
Value =
1140 parseULEB128<uint64_t>(TableData, Cursor))
1146 *
OS <<
" (operands: ";
1161 *OffsetPtr = Cursor.
tell();
1165 State.handleSpecialOpcode(Opcode, OpcodeOffset);
1168 *
OS <<
"address += " << Delta.
Address <<
", line += " << Delta.
Line;
1170 *OffsetPtr = Cursor.
tell();
1175 if (
Verbose && Rows.size() == RowCount)
1182 if (!Cursor && Opcode != 0) {
1189 RecoverableErrorHandler(Cursor.
takeError());
1192 if (!State.Sequence.Empty)
1195 "last sequence in debug line table at offset 0x%8.8" PRIx64
1196 " is not terminated",
1200 if (!Sequences.empty()) {
1218uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1222 return UnknownRowIndex;
1235 RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1,
Row,
1239 return RowPos - Rows.begin();
1248 if (Result != UnknownRowIndex ||
1254 return lookupAddressImpl(
Address);
1257uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
1265 if (It == Sequences.end() || It->SectionIndex !=
Address.SectionIndex)
1266 return UnknownRowIndex;
1267 return findRowInSeq(*It,
Address);
1272 std::vector<uint32_t> &Result)
const {
1275 if (lookupAddressRangeImpl(
Address,
Size, Result))
1283 return lookupAddressRangeImpl(
Address,
Size, Result);
1286bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1288 std::vector<uint32_t> &Result)
const {
1289 if (Sequences.empty())
1296 SequenceIter LastSeq = Sequences.end();
1299 if (SeqPos == LastSeq || !SeqPos->containsPC(
Address))
1302 SequenceIter StartPos = SeqPos;
1307 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
1312 if (SeqPos == StartPos)
1313 FirstRowIndex = findRowInSeq(CurSeq,
Address);
1317 findRowInSeq(CurSeq, {EndAddr - 1,
Address.SectionIndex});
1318 if (LastRowIndex == UnknownRowIndex)
1321 assert(FirstRowIndex != UnknownRowIndex);
1322 assert(LastRowIndex != UnknownRowIndex);
1324 for (
uint32_t I = FirstRowIndex;
I <= LastRowIndex; ++
I) {
1325 Result.push_back(
I);
1334std::optional<StringRef>
1335DWARFDebugLine::LineTable::getSourceByIndex(
uint64_t FileIndex,
1337 if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
1338 return std::nullopt;
1339 const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex);
1342 return std::nullopt;
1356 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
1363 if (Kind == FileLineInfoKind::RawValue ||
1365 Result = std::string(FileName);
1368 if (Kind == FileLineInfoKind::BaseNameOnly) {
1376 if (getVersion() >= 5) {
1379 if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1380 Entry.DirIdx < IncludeDirectories.size())
1383 if (0 < Entry.DirIdx && Entry.DirIdx <= IncludeDirectories.size())
1391 if (Kind == FileLineInfoKind::AbsoluteFilePath &&
1392 (getVersion() < 5 || Entry.DirIdx != 0) && !CompDir.
empty() &&
1396 assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1397 Kind == FileLineInfoKind::RelativeFilePath) &&
1398 "invalid FileLineInfo Kind");
1402 Result = std::string(FilePath.
str());
1411 if (RowIndex == -1U)
1414 const auto &
Row = Rows[RowIndex];
1415 if (!getFileNameByIndex(
Row.
File, CompDir, Kind, Result.FileName))
1420 Result.Source = getSourceByIndex(
Row.
File, Kind);
1449 for (
const auto &U : Units)
1450 if (
auto CUDIE = U->getUnitDIE())
1452 LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
1466 return TotalLength != 0u;
1474 "parsing should have terminated");
1480 UnrecoverableErrorHandler(std::move(Err));
1481 moveToNextTable(OldOffset, LT.Prologue);
1489 "parsing should have terminated");
1493 if (
Error Err = LT.Prologue.parse(DebugLineData, &
Offset,
1494 RecoverableErrorHandler,
Context, U))
1495 UnrecoverableErrorHandler(std::move(Err));
1496 moveToNextTable(OldOffset, LT.Prologue);
1501 auto It = LineToUnit.find(
Offset);
1502 if (It != LineToUnit.end())
1508bool DWARFDebugLine::SectionParser::hasValidVersion(
uint64_t Offset) {
1512 uint16_t Version = HeaderData.getU16(Cursor);
1523void DWARFDebugLine::SectionParser::moveToNextTable(
uint64_t OldOffset,
1524 const Prologue &
P) {
1528 if (!
P.totalLengthIsValid()) {
1533 Offset = OldOffset +
P.TotalLength +
P.sizeofTotalLength();
1541 if (hasValidVersion(
Offset))
1547 for (
unsigned Align : {4, 8}) {
1556 if (hasValidVersion(AlignedOffset)) {
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void clear(coro::Shape &Shape)
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 isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
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
@ EndSequence
End of the line table.
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
LLVM Basic Block Representation.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
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
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.
SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, DWARFUnitVector::iterator_range Units)
void clearLineTable(uint64_t Offset)
Expected< const LineTable * > getOrParseLineTable(DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx, const DWARFUnit *U, function_ref< void(Error)> RecoverableErrorHandler)
const LineTable * getLineTable(uint64_t Offset) const
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.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
const char * data() const
data - 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...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
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.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
StringRef LNExtendedString(unsigned Encoding)
StringRef FormatString(DwarfFormat Format)
StringRef LNStandardString(unsigned Standard)
@ C
The default llvm calling convention, compatible with C.
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)
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
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.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
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.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
void sort(IteratorTy Start, IteratorTy End)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
void consumeError(Error Err)
Consume a Error without doing anything.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
void trackContentType(dwarf::LineNumberEntryFormat ContentType)
Update tracked content types with ContentType.
bool getDirectoryForEntry(const FileNameEntry &Entry, std::string &Directory) const
Extracts directory name by its Entry in include directories table in prologue.
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.
uint32_t lookupAddress(object::SectionedAddress Address) const
Returns the index of the row with file/line info for a given address, or UnknownRowIndex if there is ...
bool getFileLineInfoForAddress(object::SectionedAddress Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result) const
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
bool hasFileAtIndex(uint64_t FileIndex) const
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
uint32_t sizeofTotalLength() const
uint16_t getVersion() const
std::optional< uint64_t > getLastValidFileIndex() const
Error parse(DWARFDataExtractor Data, uint64_t *OffsetPtr, function_ref< void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx, const DWARFUnit *U=nullptr)
std::vector< DWARFFormValue > IncludeDirectories
uint8_t OpcodeBase
The number assigned to the first special opcode.
std::vector< uint8_t > StandardOpcodeLengths
bool totalLengthIsValid() const
uint8_t getAddressSize() const
const llvm::DWARFDebugLine::FileNameEntry & getFileNameEntry(uint64_t Index) const
Get DWARF-version aware access to the file name entry at the provided index.
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result, sys::path::Style Style=sys::path::Style::native) const
uint64_t TotalLength
The size in bytes of the statement information for this compilation unit (not including the total_len...
uint64_t getLength() const
Length of the prologue in bytes.
std::vector< FileNameEntry > FileNames
Standard .debug_line state machine structure.
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.
object::SectionedAddress Address
The program-counter value corresponding to a machine instruction generated by the compiler and sectio...
void postAppend()
Called after a row is appended to the matrix.
uint16_t Column
An unsigned integer indicating a column number within a source line.
static void dumpTableHeader(raw_ostream &OS, unsigned Indent)
void reset(bool DefaultIsStmt)
Row(bool DefaultIsStmt=false)
void dump(raw_ostream &OS) const
Represents a series of contiguous machine instructions.
static bool orderByHighPC(const Sequence &LHS, const Sequence &RHS)
bool containsPC(object::SectionedAddress PC) const
uint64_t SectionIndex
If relocation information is present then this is the index of the section which contains above addre...
SmallString< 32 > digest() const
static const uint64_t UndefSection