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;
484 EpilogueBegin =
false;
489 <<
"Address Line Column File ISA Discriminator OpIndex "
492 <<
"------------------ ------ ------ ------ --- ------------- ------- "
497 OS <<
format(
"0x%16.16" PRIx64
" %6u %6u",
Address.Address, Line, Column)
498 <<
format(
" %6u %3u %13u %7u ", File, Isa, Discriminator,
OpIndex)
499 << (IsStmt ?
" is_stmt" :
"") << (
BasicBlock ?
" basic_block" :
"")
500 << (PrologueEnd ?
" prologue_end" :
"")
501 << (EpilogueBegin ?
" epilogue_begin" :
"")
525 for (
const Row &R : Rows) {
541DWARFDebugLine::ParsingState::ParsingState(
545 resetRowAndSequence();
548void DWARFDebugLine::ParsingState::resetRowAndSequence() {
549 Row.reset(LineTable->Prologue.DefaultIsStmt);
553void DWARFDebugLine::ParsingState::appendRowToMatrix() {
554 unsigned RowNumber = LineTable->Rows.size();
555 if (Sequence.Empty) {
557 Sequence.Empty =
false;
558 Sequence.LowPC = Row.Address.Address;
559 Sequence.FirstRowIndex = RowNumber;
561 LineTable->appendRow(Row);
562 if (Row.EndSequence) {
564 Sequence.HighPC = Row.Address.Address;
565 Sequence.LastRowIndex = RowNumber + 1;
566 Sequence.SectionIndex = Row.Address.SectionIndex;
568 LineTable->appendSequence(Sequence);
576 LineTableConstIter Pos = LineTableMap.find(
Offset);
577 if (Pos != LineTableMap.end())
587 " is not a valid debug line section offset",
590 std::pair<LineTableIter, bool> Pos =
595 LT->parse(DebugLineData, &
Offset, Ctx, U, RecoverableErrorHandler))
596 return std::move(Err);
603 LineTableMap.erase(
Offset);
608 if (Opcode < OpcodeBase)
614DWARFDebugLine::ParsingState::advanceAddrOpIndex(
uint64_t OperationAdvance,
621 if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
622 LineTable->Prologue.MaxOpsPerInst == 0)
625 "line table program at offset 0x%8.8" PRIx64
626 " contains a %s opcode at offset 0x%8.8" PRIx64
627 ", but the prologue maximum_operations_per_instruction value is 0"
628 ", which is invalid. Assuming a value of 1 instead",
629 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
635 if (ReportAdvanceAddrProblem && LineTable->Prologue.MaxOpsPerInst > 1)
638 "line table program at offset 0x%8.8" PRIx64
639 " contains a %s opcode at offset 0x%8.8" PRIx64
640 ", but the prologue maximum_operations_per_instruction value is %" PRId8
641 ", which is experimentally supported, so line number information "
643 LineTableOffset, OpcodeName.
data(), OpcodeOffset,
644 LineTable->Prologue.MaxOpsPerInst));
645 if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
648 "line table program at offset 0x%8.8" PRIx64
649 " contains a %s opcode at offset 0x%8.8" PRIx64
650 ", but the prologue minimum_instruction_length value "
651 "is 0, which prevents any address advancing",
652 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
653 ReportAdvanceAddrProblem =
false;
666 uint8_t MaxOpsPerInst =
667 std::max(LineTable->Prologue.MaxOpsPerInst, uint8_t{1});
669 uint64_t AddrOffset = ((Row.OpIndex + OperationAdvance) / MaxOpsPerInst) *
670 LineTable->Prologue.MinInstLength;
671 Row.Address.Address += AddrOffset;
673 uint8_t PrevOpIndex = Row.OpIndex;
674 Row.OpIndex = (Row.OpIndex + OperationAdvance) % MaxOpsPerInst;
675 int16_t OpIndexDelta =
static_cast<int16_t
>(Row.OpIndex) - PrevOpIndex;
677 return {AddrOffset, OpIndexDelta};
681DWARFDebugLine::ParsingState::advanceForOpcode(uint8_t Opcode,
683 assert(Opcode == DW_LNS_const_add_pc ||
684 Opcode >= LineTable->Prologue.OpcodeBase);
685 if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
690 "line table program at offset 0x%8.8" PRIx64
691 " contains a %s opcode at offset 0x%8.8" PRIx64
692 ", but the prologue line_range value is 0. The "
693 "address and line will not be adjusted",
694 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
695 ReportBadLineRange =
false;
698 uint8_t OpcodeValue = Opcode;
699 if (Opcode == DW_LNS_const_add_pc)
701 uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
703 LineTable->Prologue.LineRange != 0
704 ? AdjustedOpcode / LineTable->Prologue.LineRange
706 AddrOpIndexDelta Advance =
707 advanceAddrOpIndex(OperationAdvance, Opcode, OpcodeOffset);
708 return {Advance.AddrOffset, Advance.OpIndexDelta, AdjustedOpcode};
712DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
746 advanceForOpcode(Opcode, OpcodeOffset);
747 int32_t LineOffset = 0;
748 if (LineTable->Prologue.LineRange != 0)
750 LineTable->Prologue.LineBase +
751 (AddrAdvanceResult.
AdjustedOpcode % LineTable->Prologue.LineRange);
752 Row.Line += LineOffset;
753 return {AddrAdvanceResult.
AddrDelta, LineOffset,
773 assert((
OS || !
Verbose) &&
"cannot have verbose output without stream");
774 const uint64_t DebugLineOffset = *OffsetPtr;
779 Prologue.
parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
798 assert(DebugLineData.
size() > DebugLineOffset &&
799 "prologue parsing should handle invalid offset");
800 uint64_t BytesRemaining = DebugLineData.
size() - DebugLineOffset;
801 RecoverableErrorHandler(
803 "line table program with offset 0x%8.8" PRIx64
804 " has length 0x%8.8" PRIx64
" but only 0x%8.8" PRIx64
805 " bytes are available",
806 DebugLineOffset, ProgramLength, BytesRemaining));
808 ProgramLength = BytesRemaining;
813 const uint64_t EndOffset = DebugLineOffset + ProgramLength;
823 ParsingState State(
this, DebugLineOffset, RecoverableErrorHandler);
826 if (
OS && *OffsetPtr < EndOffset) {
830 bool TombstonedAddress =
false;
832 if (!TombstonedAddress) {
839 State.appendRowToMatrix();
842 while (*OffsetPtr < EndOffset) {
846 *
OS <<
format(
"0x%08.08" PRIx64
": ", *OffsetPtr);
849 uint8_t Opcode = TableData.
getU8(Cursor);
850 size_t RowCount = Rows.size();
853 *
OS <<
format(
"%02.02" PRIx8
" ", Opcode);
864 *
OS <<
"Badly formed extended line op (length 0)\n";
868 RecoverableErrorHandler(Cursor.
takeError());
870 *OffsetPtr = Cursor.
tell();
874 uint8_t SubOpcode = TableData.
getU8(Cursor);
881 case DW_LNE_end_sequence:
889 State.Row.EndSequence =
true;
894 State.resetRowAndSequence();
897 case DW_LNE_set_address:
910 uint64_t OpcodeAddressSize = Len - 1;
911 if (ExtractorAddressSize != OpcodeAddressSize &&
912 ExtractorAddressSize != 0)
915 "mismatching address size at offset 0x%8.8" PRIx64
916 " expected 0x%2.2" PRIx8
" found 0x%2.2" PRIx64,
917 ExtOffset, ExtractorAddressSize, Len - 1));
922 if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
923 OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
926 "address size 0x%2.2" PRIx64
927 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
929 OpcodeAddressSize, ExtOffset));
930 TableData.
skip(Cursor, OpcodeAddressSize);
934 Cursor, &State.Row.Address.SectionIndex);
935 State.Row.OpIndex = 0;
939 TombstonedAddress = State.Row.Address.Address == Tombstone;
942 if (ExtractorAddressSize != 0)
954 case DW_LNE_define_file:
985 *
OS <<
" (" <<
Name <<
", dir=" << FileEntry.
DirIdx <<
", mod_time="
987 <<
", length=" << FileEntry.
Length <<
")";
991 case DW_LNE_set_discriminator:
992 State.Row.Discriminator = TableData.
getULEB128(Cursor);
994 *
OS <<
" (" << State.Row.Discriminator <<
")";
999 *
OS <<
format(
"Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
1000 <<
format(
" length %" PRIx64, Len);
1003 TableData.
skip(Cursor, Len - 1);
1011 if (Cursor && Cursor.
tell() !=
End)
1014 "unexpected line op length at offset 0x%8.8" PRIx64
1015 " expected 0x%2.2" PRIx64
" found 0x%2.2" PRIx64,
1016 ExtOffset, Len, Cursor.
tell() - ExtOffset));
1019 uint8_t Byte = TableData.
getU8(ByteCursor);
1021 *
OS <<
" (<parsing error>";
1023 *
OS <<
format(
" %2.2" PRIx8, Byte);
1024 Byte = TableData.
getU8(ByteCursor);
1025 }
while (ByteCursor);
1046 case DW_LNS_advance_pc:
1050 if (std::optional<uint64_t> Operand =
1051 parseULEB128<uint64_t>(TableData, Cursor)) {
1053 State.advanceAddrOpIndex(*Operand, Opcode, OpcodeOffset);
1060 case DW_LNS_advance_line:
1064 int64_t LineDelta = TableData.
getSLEB128(Cursor);
1066 State.Row.Line += LineDelta;
1068 *
OS <<
" (" << State.Row.Line <<
")";
1073 case DW_LNS_set_file:
1076 if (std::optional<uint16_t> File =
1077 parseULEB128<uint16_t>(TableData, Cursor)) {
1078 State.Row.File = *File;
1080 *
OS <<
" (" << State.Row.File <<
")";
1084 case DW_LNS_set_column:
1087 if (std::optional<uint16_t> Column =
1088 parseULEB128<uint16_t>(TableData, Cursor)) {
1089 State.Row.Column = *Column;
1091 *
OS <<
" (" << State.Row.Column <<
")";
1095 case DW_LNS_negate_stmt:
1098 State.Row.IsStmt = !State.Row.IsStmt;
1101 case DW_LNS_set_basic_block:
1104 State.Row.BasicBlock =
true;
1107 case DW_LNS_const_add_pc:
1121 State.advanceForOpcode(Opcode, OpcodeOffset);
1123 *
OS <<
format(
" (addr += 0x%16.16" PRIx64
", op-index += %" PRIu8
1129 case DW_LNS_fixed_advance_pc:
1144 State.Row.Address.Address += PCOffset;
1145 State.Row.OpIndex = 0;
1147 *
OS <<
format(
" (addr += 0x%4.4" PRIx16
", op-index = 0)",
1153 case DW_LNS_set_prologue_end:
1156 State.Row.PrologueEnd =
true;
1159 case DW_LNS_set_epilogue_begin:
1162 State.Row.EpilogueBegin =
true;
1165 case DW_LNS_set_isa:
1168 if (std::optional<uint8_t> Isa =
1169 parseULEB128<uint8_t>(TableData, Cursor)) {
1170 State.Row.Isa = *Isa;
1172 *
OS <<
" (" << (
uint64_t)State.Row.Isa <<
")";
1183 *
OS <<
"Unrecognized standard opcode";
1186 for (uint8_t
I = 0;
I < OpcodeLength; ++
I) {
1187 if (std::optional<uint64_t>
Value =
1188 parseULEB128<uint64_t>(TableData, Cursor))
1194 *
OS <<
" (operands: ";
1209 *OffsetPtr = Cursor.
tell();
1213 State.handleSpecialOpcode(Opcode, OpcodeOffset);
1216 *
OS <<
"address += " << Delta.
Address <<
", line += " << Delta.
Line
1217 <<
", op-index += " << Delta.
OpIndex;
1219 *OffsetPtr = Cursor.
tell();
1224 if (
Verbose && Rows.size() == RowCount)
1231 if (!Cursor && Opcode != 0) {
1238 RecoverableErrorHandler(Cursor.
takeError());
1241 if (!State.Sequence.Empty)
1244 "last sequence in debug line table at offset 0x%8.8" PRIx64
1245 " is not terminated",
1249 if (!Sequences.empty()) {
1267uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1271 return UnknownRowIndex;
1287 RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1,
Row,
1291 return RowPos - Rows.begin();
1300 if (Result != UnknownRowIndex ||
1306 return lookupAddressImpl(
Address);
1309uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
1317 if (It == Sequences.end() || It->SectionIndex !=
Address.SectionIndex)
1318 return UnknownRowIndex;
1319 return findRowInSeq(*It,
Address);
1324 std::vector<uint32_t> &Result)
const {
1327 if (lookupAddressRangeImpl(
Address,
Size, Result))
1335 return lookupAddressRangeImpl(
Address,
Size, Result);
1338bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1340 std::vector<uint32_t> &Result)
const {
1341 if (Sequences.empty())
1348 SequenceIter LastSeq = Sequences.end();
1351 if (SeqPos == LastSeq || !SeqPos->containsPC(
Address))
1354 SequenceIter StartPos = SeqPos;
1359 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
1364 if (SeqPos == StartPos)
1365 FirstRowIndex = findRowInSeq(CurSeq,
Address);
1369 findRowInSeq(CurSeq, {EndAddr - 1,
Address.SectionIndex});
1370 if (LastRowIndex == UnknownRowIndex)
1373 assert(FirstRowIndex != UnknownRowIndex);
1374 assert(LastRowIndex != UnknownRowIndex);
1376 for (
uint32_t I = FirstRowIndex;
I <= LastRowIndex; ++
I) {
1377 Result.push_back(
I);
1386std::optional<StringRef>
1387DWARFDebugLine::LineTable::getSourceByIndex(
uint64_t FileIndex,
1389 if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
1390 return std::nullopt;
1391 const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex);
1394 return std::nullopt;
1408 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
1415 if (Kind == FileLineInfoKind::RawValue ||
1417 Result = std::string(FileName);
1420 if (Kind == FileLineInfoKind::BaseNameOnly) {
1428 if (getVersion() >= 5) {
1431 if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1432 Entry.DirIdx < IncludeDirectories.size())
1435 if (0 < Entry.DirIdx && Entry.DirIdx <= IncludeDirectories.size())
1443 if (Kind == FileLineInfoKind::AbsoluteFilePath &&
1444 (getVersion() < 5 || Entry.DirIdx != 0) && !CompDir.
empty() &&
1448 assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1449 Kind == FileLineInfoKind::RelativeFilePath) &&
1450 "invalid FileLineInfo Kind");
1454 Result = std::string(FilePath.
str());
1463 if (RowIndex == -1U)
1466 const auto &
Row = Rows[RowIndex];
1467 if (!getFileNameByIndex(
Row.
File, CompDir, Kind, Result.FileName))
1472 Result.Source = getSourceByIndex(
Row.
File, Kind);
1501 for (
const auto &U : Units)
1502 if (
auto CUDIE = U->getUnitDIE())
1504 LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
1518 return TotalLength != 0u;
1526 "parsing should have terminated");
1532 UnrecoverableErrorHandler(std::move(Err));
1533 moveToNextTable(OldOffset, LT.Prologue);
1541 "parsing should have terminated");
1545 if (
Error Err = LT.Prologue.parse(DebugLineData, &
Offset,
1546 RecoverableErrorHandler,
Context, U))
1547 UnrecoverableErrorHandler(std::move(Err));
1548 moveToNextTable(OldOffset, LT.Prologue);
1553 auto It = LineToUnit.find(
Offset);
1554 if (It != LineToUnit.end())
1560bool DWARFDebugLine::SectionParser::hasValidVersion(
uint64_t Offset) {
1564 uint16_t Version = HeaderData.getU16(Cursor);
1575void DWARFDebugLine::SectionParser::moveToNextTable(
uint64_t OldOffset,
1576 const Prologue &
P) {
1580 if (!
P.totalLengthIsValid()) {
1585 Offset = OldOffset +
P.TotalLength +
P.sizeofTotalLength();
1593 if (hasValidVersion(
Offset))
1599 for (
unsigned Align : {4, 8}) {
1608 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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
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