1//===- DWARFDebugLine.cpp -------------------------------------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 35structContentDescriptor {
42}
// end anonymous namespace 45return Version >= 2 && Version <= 5;
51case dwarf::DW_LNCT_timestamp:
54case dwarf::DW_LNCT_size:
57case dwarf::DW_LNCT_MD5:
60case dwarf::DW_LNCT_LLVM_source:
64// We only care about values we consider optional, and new values may be 65// added in the vendor extension range, so we do not match exhaustively. 75"line table prologue has no dwarf version information");
77return FileIndex < FileNames.size();
78return FileIndex != 0 && FileIndex <= FileNames.size();
81std::optional<uint64_t>
87"line table prologue has no dwarf version information");
88// In DWARF v5 the file names are 0-indexed. 90return FileNames.size() - 1;
91return FileNames.size();
98"line table prologue has no dwarf version information");
99// In DWARF v5 the file names are 0-indexed. 100if (DwarfVersion >= 5)
101return FileNames[
Index];
102return FileNames[
Index - 1];
106 TotalLength = PrologueLength = 0;
108 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
112 StandardOpcodeLengths.clear();
113 IncludeDirectories.clear();
119if (!totalLengthIsValid())
122OS <<
"Line table prologue:\n" 123 <<
format(
" total_length: 0x%0*" PRIx64
"\n", OffsetDumpWidth,
126 <<
format(
" version: %u\n", getVersion());
129if (getVersion() >= 5)
130OS <<
format(
" address_size: %u\n", getAddressSize())
131 <<
format(
" seg_select_size: %u\n", SegSelectorSize);
132OS <<
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);
141for (
uint32_tI = 0;
I != StandardOpcodeLengths.size(); ++
I)
142OS <<
formatv(
"standard_opcode_lengths[{0}] = {1}\n",
144 StandardOpcodeLengths[
I]);
146if (!IncludeDirectories.empty()) {
147// DWARF v5 starts directory indexes at 0. 148uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
149for (
uint32_tI = 0;
I != IncludeDirectories.size(); ++
I) {
150OS <<
format(
"include_directories[%3u] = ",
I + DirBase);
151 IncludeDirectories[
I].dump(
OS, DumpOptions);
156if (!FileNames.empty()) {
157// DWARF v5 starts file indexes at 0. 158uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
161OS <<
format(
"file_names[%3u]:\n",
I + FileBase);
165if (ContentTypes.HasMD5)
167if (ContentTypes.HasModTime)
169if (ContentTypes.HasLength)
171if (ContentTypes.HasSource) {
175elseif ((*Source)[0]) {
185// Parse v2-v4 directory and file tables. 190 std::vector<DWARFFormValue> &IncludeDirectories,
191 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
198"include directories table was not null " 199"terminated before the end of the prologue");
205 IncludeDirectories.push_back(Dir);
214if (!Err &&
Name.empty())
228"file names table was not null terminated before " 229"the end of the prologue");
231 FileNames.push_back(FileEntry);
237// Parse v5 directory/file entry content descriptions. 238// Returns the descriptors, or an error if we did not find a path or ran off 239// the end of the prologue. 244 ContentDescriptors Descriptors;
245int FormatCount = DebugLineData.
getU8(OffsetPtr, &Err);
247for (
intI = 0;
I != FormatCount && !Err; ++
I) {
248 ContentDescriptor Descriptor;
252if (Descriptor.Type == dwarf::DW_LNCT_path)
256 Descriptors.push_back(Descriptor);
261"failed to parse entry content descriptors: %s",
266"failed to parse entry content descriptions" 267" because no path was found");
276 std::vector<DWARFFormValue> &IncludeDirectories,
277 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
278// Get the directory entry description. 284// Get the directory entries, according to the format described above. 287for (
auto Descriptor : *DirDescriptors) {
289switch (Descriptor.Type) {
293"failed to parse directory entry because " 294"extracting the form value failed");
295 IncludeDirectories.push_back(
Value);
300"failed to parse directory entry because " 301"skipping the form value failed");
306// Get the file entry description. 312// Get the file entries, according to the format described above. 316for (
auto Descriptor : *FileDescriptors) {
320"failed to parse file entry because " 321"extracting the form value failed");
322switch (Descriptor.Type) {
326case DW_LNCT_LLVM_source:
329case DW_LNCT_directory_index:
332case DW_LNCT_timestamp:
339if (!
Value.getAsBlock() ||
Value.getAsBlock()->size() != 16)
342"failed to parse file entry because the MD5 hash is invalid");
343 std::uninitialized_copy_n(
Value.getAsBlock()->begin(), 16,
350 FileNames.push_back(FileEntry);
357sizeof(getVersion()) + sizeofPrologueLength();
358if (getVersion() >= 5)
359Length += 2;
// Address + Segment selector sizes. 367constuint64_t PrologueOffset = *OffsetPtr;
378// Treat this error as unrecoverable - we cannot be sure what any of 379// the data represents including the length field, so cannot skip it or make 380// any reasonable assumptions. 381 *OffsetPtr = Cursor.
tell();
384"parsing line table prologue at offset 0x%8.8" PRIx64
385": unsupported version %" PRIu16,
386 PrologueOffset, getVersion());
389if (getVersion() >= 5) {
392constuint8_t PrologueAddrSize = getAddressSize();
394if (DataAddrSize == 0) {
395if (PrologueAddrSize != 4 && PrologueAddrSize != 8) {
398"parsing line table prologue at offset 0x%8.8" PRIx64
399": invalid address size %" PRIu8,
400 PrologueOffset, PrologueAddrSize));
402 }
elseif (DataAddrSize != PrologueAddrSize) {
405"parsing line table prologue at offset 0x%8.8" PRIx64
": address " 406"size %" PRIu8
" doesn't match architecture address size %" PRIu8,
407 PrologueOffset, PrologueAddrSize, DataAddrSize));
410 SegSelectorSize = DebugLineData.
getU8(Cursor);
415constuint64_t EndPrologueOffset = PrologueLength + Cursor.
tell();
417 MinInstLength = DebugLineData.
getU8(Cursor);
418if (getVersion() >= 4)
419 MaxOpsPerInst = DebugLineData.
getU8(Cursor);
420 DefaultIsStmt = DebugLineData.
getU8(Cursor);
421 LineBase = DebugLineData.
getU8(Cursor);
422 LineRange = DebugLineData.
getU8(Cursor);
423 OpcodeBase = DebugLineData.
getU8(Cursor);
425if (Cursor && OpcodeBase == 0) {
426// If the opcode base is 0, we cannot read the standard opcode lengths (of 427// which there are supposed to be one fewer than the opcode base). Assume 428// there are no standard opcodes and continue parsing. 431"parsing line table prologue at offset 0x%8.8" PRIx64
432" found opcode base of 0. Assuming no standard opcodes",
435 StandardOpcodeLengths.reserve(OpcodeBase - 1);
438 StandardOpcodeLengths.push_back(OpLen);
442 *OffsetPtr = Cursor.
tell();
443// A corrupt file name or directory table does not prevent interpretation of 444// the main line program, so check the cursor state now so that its errors can 445// be handled separately. 449"parsing line table prologue at offset 0x%8.8" PRIx64
": %s",
455 ContentTypes, IncludeDirectories, FileNames)
457 IncludeDirectories, FileNames);
462"parsing line table prologue at 0x%8.8" PRIx64
463" found an invalid directory or file table description at" 465 PrologueOffset, *OffsetPtr),
470assert(*OffsetPtr <= EndPrologueOffset);
471if (*OffsetPtr != EndPrologueOffset) {
474"unknown data in line table prologue at offset 0x%8.8" PRIx64
475": parsing ended (at offset 0x%8.8" PRIx64
476") before reaching the prologue end at offset 0x%8.8" PRIx64,
477 PrologueOffset, *OffsetPtr, EndPrologueOffset));
488 EpilogueBegin =
false;
499 IsStmt = DefaultIsStmt;
504 EpilogueBegin =
false;
509 <<
"Address Line Column File ISA Discriminator OpIndex " 512 <<
"------------------ ------ ------ ------ --- ------------- ------- " 518 <<
format(
" %6u %3u %13u %7u ", File, Isa, Discriminator,
OpIndex)
519 << (IsStmt ?
" is_stmt" :
"") << (
BasicBlock ?
" basic_block" :
"")
520 << (PrologueEnd ?
" prologue_end" :
"")
521 << (EpilogueBegin ?
" epilogue_begin" :
"")
545for (
constRow &R : Rows) {
550// Terminate the table with a final blank line to clearly delineate it from 561DWARFDebugLine::ParsingState::ParsingState(
565 resetRowAndSequence();
568void DWARFDebugLine::ParsingState::resetRowAndSequence() {
569 Row.reset(LineTable->Prologue.DefaultIsStmt);
573void DWARFDebugLine::ParsingState::appendRowToMatrix() {
574unsigned RowNumber = LineTable->Rows.size();
576// Record the beginning of instruction sequence. 577 Sequence.Empty =
false;
578 Sequence.LowPC = Row.Address.Address;
579 Sequence.FirstRowIndex = RowNumber;
581 LineTable->appendRow(Row);
582if (Row.EndSequence) {
583// Record the end of instruction sequence. 584Sequence.HighPC = Row.Address.Address;
585Sequence.LastRowIndex = RowNumber + 1;
586Sequence.SectionIndex = Row.Address.SectionIndex;
588 LineTable->appendSequence(Sequence);
596 LineTableConstIter Pos = LineTableMap.find(
Offset);
597if (Pos != LineTableMap.end())
607"offset 0x%8.8" PRIx64
608" is not a valid debug line section offset",
611 std::pair<LineTableIter, bool> Pos =
616 LT->parse(DebugLineData, &
Offset, Ctx, U, RecoverableErrorHandler))
617return std::move(Err);
624 LineTableMap.erase(
Offset);
629if (Opcode < OpcodeBase)
635DWARFDebugLine::ParsingState::advanceAddrOpIndex(
uint64_t OperationAdvance,
639// For versions less than 4, the MaxOpsPerInst member is set to 0, as the 640// maximum_operations_per_instruction field wasn't introduced until DWARFv4. 641// Don't warn about bad values in this situation. 642if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
643 LineTable->Prologue.MaxOpsPerInst == 0)
646"line table program at offset 0x%8.8" PRIx64
647" contains a %s opcode at offset 0x%8.8" PRIx64
648", but the prologue maximum_operations_per_instruction value is 0" 649", which is invalid. Assuming a value of 1 instead",
650 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
651// Although we are able to correctly parse line number programs with 652// MaxOpsPerInst > 1, the rest of DWARFDebugLine and its 653// users have not been updated to handle line information for all operations 654// in a multi-operation instruction, so warn about potentially incorrect 656if (ReportAdvanceAddrProblem && LineTable->Prologue.MaxOpsPerInst > 1)
659"line table program at offset 0x%8.8" PRIx64
660" contains a %s opcode at offset 0x%8.8" PRIx64
661", but the prologue maximum_operations_per_instruction value is %" PRId8
662", which is experimentally supported, so line number information " 664 LineTableOffset, OpcodeName.
data(), OpcodeOffset,
665 LineTable->Prologue.MaxOpsPerInst));
666if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
669"line table program at offset 0x%8.8" PRIx64
670" contains a %s opcode at offset 0x%8.8" PRIx64
671", but the prologue minimum_instruction_length value " 672"is 0, which prevents any address advancing",
673 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
674 ReportAdvanceAddrProblem =
false;
676// Advances the address and op_index according to DWARFv5, section 6.2.5.1: 678// new address = address + 679// minimum_instruction_length * 680// ((op_index + operation advance) / maximum_operations_per_instruction) 683// (op_index + operation advance) % maximum_operations_per_instruction 685// For versions less than 4, the MaxOpsPerInst member is set to 0, as the 686// maximum_operations_per_instruction field wasn't introduced until DWARFv4. 688 std::max(LineTable->Prologue.MaxOpsPerInst,
uint8_t{1});
690uint64_t AddrOffset = ((Row.OpIndex + OperationAdvance) / MaxOpsPerInst) *
691 LineTable->Prologue.MinInstLength;
692 Row.Address.Address += AddrOffset;
694uint8_t PrevOpIndex = Row.OpIndex;
695 Row.OpIndex = (Row.OpIndex + OperationAdvance) % MaxOpsPerInst;
696 int16_t OpIndexDelta =
static_cast<int16_t
>(Row.OpIndex) - PrevOpIndex;
698return {AddrOffset, OpIndexDelta};
702DWARFDebugLine::ParsingState::advanceForOpcode(
uint8_t Opcode,
704assert(Opcode == DW_LNS_const_add_pc ||
705 Opcode >= LineTable->Prologue.OpcodeBase);
706if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
711"line table program at offset 0x%8.8" PRIx64
712" contains a %s opcode at offset 0x%8.8" PRIx64
713", but the prologue line_range value is 0. The " 714"address and line will not be adjusted",
715 LineTableOffset, OpcodeName.
data(), OpcodeOffset));
716 ReportBadLineRange =
false;
720if (Opcode == DW_LNS_const_add_pc)
722uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
724 LineTable->Prologue.LineRange != 0
725 ? AdjustedOpcode / LineTable->Prologue.LineRange
727 AddrOpIndexDelta Advance =
728 advanceAddrOpIndex(OperationAdvance, Opcode, OpcodeOffset);
729return {Advance.AddrOffset, Advance.OpIndexDelta, AdjustedOpcode};
733DWARFDebugLine::ParsingState::handleSpecialOpcode(
uint8_t Opcode,
735// A special opcode value is chosen based on the amount that needs 736// to be added to the line and address registers. The maximum line 737// increment for a special opcode is the value of the line_base 738// field in the header, plus the value of the line_range field, 739// minus 1 (line base + line range - 1). If the desired line 740// increment is greater than the maximum line increment, a standard 741// opcode must be used instead of a special opcode. The "address 742// advance" is calculated by dividing the desired address increment 743// by the minimum_instruction_length field from the header. The 744// special opcode is then calculated using the following formula: 746// opcode = (desired line increment - line_base) + 747// (line_range * address advance) + opcode_base 749// If the resulting opcode is greater than 255, a standard opcode 750// must be used instead. 752// To decode a special opcode, subtract the opcode_base from the 753// opcode itself to give the adjusted opcode. The amount to 754// increment the address register is the result of the adjusted 755// opcode divided by the line_range multiplied by the 756// minimum_instruction_length field from the header. That is: 758// address increment = (adjusted opcode / line_range) * 759// minimum_instruction_length 761// The amount to increment the line register is the line_base plus 762// the result of the adjusted opcode modulo the line_range. That is: 764// line increment = line_base + (adjusted opcode % line_range) 767 advanceForOpcode(Opcode, OpcodeOffset);
768 int32_t LineOffset = 0;
769if (LineTable->Prologue.LineRange != 0)
771 LineTable->Prologue.LineBase +
772 (AddrAdvanceResult.
AdjustedOpcode % LineTable->Prologue.LineRange);
773 Row.Line += LineOffset;
774return {AddrAdvanceResult.
AddrDelta, LineOffset,
778/// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on 779/// success, or std::nullopt if \p Cursor is in a failing state. 795constuint64_t DebugLineOffset = *OffsetPtr;
800Prologue.
parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
809// Ensure there is a blank line after the prologue to clearly delineate it 819assert(DebugLineData.
size() > DebugLineOffset &&
820"prologue parsing should handle invalid offset");
821uint64_t BytesRemaining = DebugLineData.
size() - DebugLineOffset;
822 RecoverableErrorHandler(
824"line table program with offset 0x%8.8" PRIx64
825" has length 0x%8.8" PRIx64
" but only 0x%8.8" PRIx64
826" bytes are available",
827 DebugLineOffset, ProgramLength, BytesRemaining));
828// Continue by capping the length at the number of remaining bytes. 829 ProgramLength = BytesRemaining;
832// Create a DataExtractor which can only see the data up to the end of the 833// table, to prevent reading past the end. 834constuint64_t EndOffset = DebugLineOffset + ProgramLength;
837// See if we should tell the data extractor the address size. 844 ParsingState State(
this, DebugLineOffset, RecoverableErrorHandler);
847if (
OS && *OffsetPtr < EndOffset) {
851bool TombstonedAddress =
false;
853if (!TombstonedAddress) {
860 State.appendRowToMatrix();
863while (*OffsetPtr < EndOffset) {
867 *
OS <<
format(
"0x%08.08" PRIx64
": ", *OffsetPtr);
871size_t RowCount = Rows.size();
874 *
OS <<
format(
"%02.02" PRIx8
" ", Opcode);
877// Extended Opcodes always start with a zero opcode followed by 878// a uleb128 length so you can skip ones you don't know about 882// Tolerate zero-length; assume length is correct and soldier on. 885 *
OS <<
"Badly formed extended line op (length 0)\n";
889 RecoverableErrorHandler(Cursor.
takeError());
891 *OffsetPtr = Cursor.
tell();
896// OperandOffset will be the same as ExtOffset, if it was not possible to 897// read the SubOpcode. 902case DW_LNE_end_sequence:
903// Set the end_sequence register of the state machine to true and 904// append a row to the matrix using the current values of the 905// state-machine registers. Then reset the registers to the initial 906// values specified above. Every statement program sequence must end 907// with a DW_LNE_end_sequence instruction which creates a row whose 908// address is that of the byte after the last target machine instruction 910 State.Row.EndSequence =
true;
911// No need to test the Cursor is valid here, since it must be to get 912// into this code path - if it were invalid, the default case would be 915 State.resetRowAndSequence();
918case DW_LNE_set_address:
919// Takes a single relocatable address as an operand. The size of the 920// operand is the size appropriate to hold an address on the target 921// machine. Set the address register to the value given by the 922// relocatable address and set the op_index register to 0. All of the 923// other statement program opcodes that affect the address register 924// add a delta to it. This instruction stores a relocatable value into 927// Make sure the extractor knows the address size. If not, infer it 928// from the size of the operand. 931uint64_t OpcodeAddressSize = Len - 1;
932if (ExtractorAddressSize != OpcodeAddressSize &&
933 ExtractorAddressSize != 0)
936"mismatching address size at offset 0x%8.8" PRIx64
937" expected 0x%2.2" PRIx8
" found 0x%2.2" PRIx64,
938 ExtOffset, ExtractorAddressSize, Len - 1));
940// Assume that the line table is correct and temporarily override the 941// address size. If the size is unsupported, give up trying to read 942// the address and continue to the next opcode. 943if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
944 OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
947"address size 0x%2.2" PRIx64
948" of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
950 OpcodeAddressSize, ExtOffset));
951 TableData.
skip(Cursor, OpcodeAddressSize);
955 Cursor, &State.Row.Address.SectionIndex);
956 State.Row.OpIndex = 0;
960 TombstonedAddress = State.Row.Address.Address == Tombstone;
962// Restore the address size if the extractor already had it. 963if (ExtractorAddressSize != 0)
970 State.Row.Address.Address);
976case DW_LNE_define_file:
977// Takes 4 arguments. The first is a null terminated string containing 978// a source file name. The second is an unsigned LEB128 number 979// representing the directory index of the directory in which the file 980// was found. The third is an unsigned LEB128 number representing the 981// time of last modification of the file. The fourth is an unsigned 982// LEB128 number representing the length in bytes of the file. The time 983// and length fields may contain LEB128(0) if the information is not 986// The directory index represents an entry in the include_directories 987// section of the statement program prologue. The index is LEB128(0) 988// if the file was found in the current directory of the compilation, 989// LEB128(1) if it was found in the first directory in the 990// include_directories section, and so on. The directory index is 991// ignored for file names that represent full path names. 993// The files are numbered, starting at 1, in the order in which they 994// appear; the names in the prologue come before names defined by 995// the DW_LNE_define_file instruction. These numbers are used in the 996// the file register of the state machine. 1007 *
OS <<
" (" <<
Name <<
", dir=" << FileEntry.
DirIdx <<
", mod_time=" 1009 <<
", length=" << FileEntry.
Length <<
")";
1013case DW_LNE_set_discriminator:
1014 State.Row.Discriminator = TableData.
getULEB128(Cursor);
1016 *
OS <<
" (" << State.Row.Discriminator <<
")";
1021 *
OS <<
format(
"Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
1022 <<
format(
" length %" PRIx64, Len);
1023// Len doesn't include the zero opcode byte or the length itself, but 1024// it does include the sub_opcode, so we have to adjust for that. 1025 TableData.
skip(Cursor, Len - 1);
1028// Make sure the length as recorded in the table and the standard length 1029// for the opcode match. If they don't, continue from the end as claimed 1030// by the table. Similarly, continue from the claimed end in the event of 1033if (Cursor && Cursor.
tell() !=
End)
1036"unexpected line op length at offset 0x%8.8" PRIx64
1037" expected 0x%2.2" PRIx64
" found 0x%2.2" PRIx64,
1038 ExtOffset, Len, Cursor.
tell() - ExtOffset));
1043 *
OS <<
" (<parsing error>";
1046 Byte = TableData.
getU8(ByteCursor);
1047 }
while (ByteCursor);
1051// The only parse failure in this case should be if the end was reached. 1052// In that case, throw away the error, as the main Cursor's error will 1063// Takes no arguments. Append a row to the matrix using the 1064// current values of the state-machine registers. 1068case DW_LNS_advance_pc:
1069// Takes a single unsigned LEB128 operand as the operation advance 1070// and modifies the address and op_index registers of the state machine 1071// according to that. 1072if (std::optional<uint64_t> Operand =
1073 parseULEB128<uint64_t>(TableData, Cursor)) {
1075 State.advanceAddrOpIndex(*Operand, Opcode, OpcodeOffset);
1082case DW_LNS_advance_line:
1083// Takes a single signed LEB128 operand and adds that value to 1084// the line register of the state machine. 1086 int64_t LineDelta = TableData.
getSLEB128(Cursor);
1088 State.Row.Line += LineDelta;
1090 *
OS <<
" (" << State.Row.Line <<
")";
1095case DW_LNS_set_file:
1096// Takes a single unsigned LEB128 operand and stores it in the file 1097// register of the state machine. 1098if (std::optional<uint16_t> File =
1099 parseULEB128<uint16_t>(TableData, Cursor)) {
1100 State.Row.File = *File;
1102 *
OS <<
" (" << State.Row.File <<
")";
1106case DW_LNS_set_column:
1107// Takes a single unsigned LEB128 operand and stores it in the 1108// column register of the state machine. 1109if (std::optional<uint16_t> Column =
1110 parseULEB128<uint16_t>(TableData, Cursor)) {
1111 State.Row.Column = *Column;
1113 *
OS <<
" (" << State.Row.Column <<
")";
1117case DW_LNS_negate_stmt:
1118// Takes no arguments. Set the is_stmt register of the state 1119// machine to the logical negation of its current value. 1120 State.Row.IsStmt = !State.Row.IsStmt;
1123case DW_LNS_set_basic_block:
1124// Takes no arguments. Set the basic_block register of the 1125// state machine to true 1126 State.Row.BasicBlock =
true;
1129case DW_LNS_const_add_pc:
1130// Takes no arguments. Advance the address and op_index registers of 1131// the state machine by the increments corresponding to special 1132// opcode 255. The motivation for DW_LNS_const_add_pc is this: 1133// when the statement program needs to advance the address by a 1134// small amount, it can use a single special opcode, which occupies 1135// a single byte. When it needs to advance the address by up to 1136// twice the range of the last special opcode, it can use 1137// DW_LNS_const_add_pc followed by a special opcode, for a total 1138// of two bytes. Only if it needs to advance the address by more 1139// than twice that range will it need to use both DW_LNS_advance_pc 1140// and a special opcode, requiring three or more bytes. 1143 State.advanceForOpcode(Opcode, OpcodeOffset);
1145 *
OS <<
format(
" (addr += 0x%16.16" PRIx64
", op-index += %" PRIu8
1151case DW_LNS_fixed_advance_pc:
1152// Takes a single uhalf operand. Add to the address register of 1153// the state machine the value of the (unencoded) operand and set 1154// the op_index register to 0. This is the only extended opcode that 1155// takes an argument that is not a variable length number. 1156// The motivation for DW_LNS_fixed_advance_pc is this: existing 1157// assemblers cannot emit DW_LNS_advance_pc or special opcodes because 1158// they cannot encode LEB128 numbers or judge when the computation 1159// of a special opcode overflows and requires the use of 1160// DW_LNS_advance_pc. Such assemblers, however, can use 1161// DW_LNS_fixed_advance_pc instead, sacrificing compression. 1165 State.Row.Address.Address += PCOffset;
1166 State.Row.OpIndex = 0;
1168 *
OS <<
format(
" (addr += 0x%4.4" PRIx16
", op-index = 0)",
1174case DW_LNS_set_prologue_end:
1175// Takes no arguments. Set the prologue_end register of the 1176// state machine to true 1177 State.Row.PrologueEnd =
true;
1180case DW_LNS_set_epilogue_begin:
1181// Takes no arguments. Set the basic_block register of the 1182// state machine to true 1183 State.Row.EpilogueBegin =
true;
1187// Takes a single unsigned LEB128 operand and stores it in the 1188// ISA register of the state machine. 1189if (std::optional<uint8_t> Isa =
1190 parseULEB128<uint8_t>(TableData, Cursor)) {
1191 State.Row.Isa = *Isa;
1198// Handle any unknown standard opcodes here. We know the lengths 1199// of such opcodes because they are specified in the prologue 1200// as a multiple of LEB128 operands for each opcode. 1204 *
OS <<
"Unrecognized standard opcode";
1208if (std::optional<uint64_t>
Value =
1209 parseULEB128<uint64_t>(TableData, Cursor))
1215 *
OS <<
" (operands: ";
1230 *OffsetPtr = Cursor.
tell();
1234 State.handleSpecialOpcode(Opcode, OpcodeOffset);
1237 *
OS <<
"address += " << Delta.
Address <<
", line += " << Delta.
Line 1238 <<
", op-index += " << Delta.
OpIndex;
1240 *OffsetPtr = Cursor.
tell();
1243// When a row is added to the matrix, it is also dumped, which includes a 1244// new line already, so don't add an extra one. 1245if (
Verbose && Rows.size() == RowCount)
1248// Most parse failures other than when parsing extended opcodes are due to 1249// failures to read ULEBs. Bail out of parsing, since we don't know where to 1250// continue reading from as there is no stated length for such byte 1251// sequences. Print the final trailing new line if needed before doing so. 1252if (!Cursor && Opcode != 0) {
1259 RecoverableErrorHandler(Cursor.
takeError());
1262if (!State.Sequence.Empty)
1265"last sequence in debug line table at offset 0x%8.8" PRIx64
1266" is not terminated",
1269// Sort all sequences so that address lookup will work faster. 1270if (!Sequences.empty()) {
1272// Note: actually, instruction address ranges of sequences should not 1273// overlap (in shared objects and executables). If they do, the address 1274// lookup would still work, though, but result would be ambiguous. 1275// We don't report warning in this case. For example, 1276// sometimes .so compiled from multiple object files contains a few 1277// rudimentary sequences for address ranges [0x0, 0xsomething). 1280// Terminate the table with a final blank line to clearly delineate it from 1288uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1292return UnknownRowIndex;
1294// In some cases, e.g. first instruction in a function, the compiler generates 1295// two entries, both with the same address. We want the last one. 1297// In general we want a non-empty range: the last row whose address is less 1298// than or equal to Address. This can be computed as upper_bound - 1. 1300// TODO: This function, and its users, needs to be update to return multiple 1301// rows for bundles with multiple op-indexes. 1308 RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1,
Row,
1312return RowPos - Rows.begin();
1317bool *IsApproximateLine)
const{
1319// Search for relocatable addresses 1322if (Result != UnknownRowIndex ||
1326// Search for absolute addresses 1328return lookupAddressImpl(
Address, IsApproximateLine);
1333bool *IsApproximateLine)
const{
1334assert((!IsApproximateLine || !*IsApproximateLine) &&
1335"Make sure IsApproximateLine is appropriately " 1336"initialized, if provided");
1337// First, find an instruction sequence containing the given address. 1343if (It == Sequences.end() || It->SectionIndex !=
Address.SectionIndex)
1344return UnknownRowIndex;
1347if (RowIndex == UnknownRowIndex || !IsApproximateLine)
1350// Approximation will only be attempted if a valid RowIndex exists. 1352// Approximation Loop 1353for (; ApproxRowIndex >= It->FirstRowIndex; --ApproxRowIndex) {
1354if (Rows[ApproxRowIndex].Line)
1355return ApproxRowIndex;
1356 *IsApproximateLine =
true;
1358// Approximation Loop fails to find the valid ApproxRowIndex 1359if (ApproxRowIndex < It->FirstRowIndex)
1360 *IsApproximateLine =
false;
1367 std::vector<uint32_t> &Result)
const{
1369// Search for relocatable addresses 1376// Search for absolute addresses 1378return lookupAddressRangeImpl(
Address,
Size, Result);
1381bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1383 std::vector<uint32_t> &Result)
const{
1384if (Sequences.empty())
1387// First, find an instruction sequence containing the given address. 1391 SequenceIter LastSeq = Sequences.end();
1394if (SeqPos == LastSeq || !SeqPos->containsPC(
Address))
1397 SequenceIter StartPos = SeqPos;
1399// Add the rows from the first sequence to the vector, starting with the 1400// index we just calculated 1402while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
1404// For the first sequence, we need to find which row in the sequence is the 1405// first in our range. 1407if (SeqPos == StartPos)
1408 FirstRowIndex = findRowInSeq(CurSeq,
Address);
1410// Figure out the last row in the range. 1412 findRowInSeq(CurSeq, {EndAddr - 1,
Address.SectionIndex});
1413if (LastRowIndex == UnknownRowIndex)
1416assert(FirstRowIndex != UnknownRowIndex);
1417assert(LastRowIndex != UnknownRowIndex);
1419for (
uint32_tI = FirstRowIndex;
I <= LastRowIndex; ++
I) {
1420 Result.push_back(
I);
1429std::optional<StringRef>
1430DWARFDebugLine::LineTable::getSourceByIndex(
uint64_t FileIndex,
1432if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
1434const FileNameEntry &
Entry = Prologue.getFileNameEntry(FileIndex);
1441// Debug info can contain paths from any OS, not necessarily 1442// an OS we're currently running on. Moreover different compilation units can 1443// be compiled on different operating systems and linked together later. 1451if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
1458if (Kind == FileLineInfoKind::RawValue ||
1460 Result = std::string(FileName);
1463if (Kind == FileLineInfoKind::BaseNameOnly) {
1470// Be defensive about the contents of Entry. 1471if (getVersion() >= 5) {
1472// DirIdx 0 is the compilation directory, so don't include it for 1474if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1475 Entry.DirIdx < IncludeDirectories.size())
1478if (0 < Entry.DirIdx && Entry.DirIdx <= IncludeDirectories.size())
1482// For absolute paths only, include the compilation directory of compile unit, 1483// unless v5 DirIdx == 0 (IncludeDir indicates the compilation directory). We 1484// know that FileName is not absolute, the only way to have an absolute path 1485// at this point would be if IncludeDir is absolute. 1486if (Kind == FileLineInfoKind::AbsoluteFilePath &&
1487 (getVersion() < 5 || Entry.DirIdx != 0) && !CompDir.
empty() &&
1491assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1492 Kind == FileLineInfoKind::RelativeFilePath) &&
1493"invalid FileLineInfo Kind");
1495// sys::path::append skips empty strings. 1497 Result = std::string(FilePath);
1504// Get the index of row we're looking for in the line table. 1506 lookupAddress(
Address, Approximate ? &Result.IsApproximateLine :
nullptr);
1509// Take file number and line/column from the row. 1510constauto &
Row = Rows[RowIndex];
1511if (!getFileNameByIndex(
Row.
File, CompDir, Kind, Result.FileName))
1516 Result.Source = getSourceByIndex(
Row.
File, Kind);
1538// We want to supply the Unit associated with a .debug_line[.dwo] table when 1539// we dump it, if possible, but still dump the table even if there isn't a Unit. 1540// Therefore, collect up handles on all the Units that point into the 1541// line-table section. 1545for (
constauto &U : Units)
1546if (
auto CUDIE = U->getUnitDIE())
1548 LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
1555 : DebugLineData(
Data), Context(
C) {
1562return TotalLength != 0u;
1570"parsing should have terminated");
1574if (
Error Err = LT.parse(DebugLineData, &
Offset, Context, U,
1576 UnrecoverableErrorHandler(std::move(Err));
1577 moveToNextTable(OldOffset, LT.Prologue);
1585"parsing should have terminated");
1589if (
Error Err = LT.Prologue.parse(DebugLineData, &
Offset,
1590 RecoverableErrorHandler, Context, U))
1591 UnrecoverableErrorHandler(std::move(Err));
1592 moveToNextTable(OldOffset, LT.Prologue);
1597auto It = LineToUnit.find(
Offset);
1598if (It != LineToUnit.end())
1604bool DWARFDebugLine::SectionParser::hasValidVersion(
uint64_tOffset) {
1610// Ignore any error here. 1611// If this is not the end of the section parseNext() will still be 1612// attempted, where this error will occur again (and can be handled). 1619void DWARFDebugLine::SectionParser::moveToNextTable(
uint64_t OldOffset,
1621// If the length field is not valid, we don't know where the next table is, so 1622// cannot continue to parse. Mark the parser as done, and leave the Offset 1623// value as it currently is. This will be the end of the bad length field. 1624if (!
P.totalLengthIsValid()) {
1629Offset = OldOffset +
P.TotalLength +
P.sizeofTotalLength();
1635// Heuristic: If the version is valid, then this is probably a line table. 1636// Otherwise, the offset might need alignment (to a 4 or 8 byte boundary). 1637if (hasValidVersion(
Offset))
1640// ARM C/C++ Compiler aligns each line table to word boundaries and pads out 1641// the .debug_line section to a word multiple. Note that in the specification 1642// this does not seem forbidden since each unit has a DW_AT_stmt_list. 1643for (
unsignedAlign : {4, 8}) {
1646// This is almost certainly not another line table but some alignment 1647// padding. This assumes the alignments tested are ordered, and are 1648// smaller than the header size (which is true for 4 and 8). 1652if (hasValidVersion(AlignedOffset)) {
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
@ 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...
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx=nullptr) const
Extracts an address-sized value and applies a relocation to the result if one exists for the given of...
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(uint64_t *Off, Error *Err=nullptr) const
Extracts the DWARF "initial length" field, which can either be a 32-bit value smaller than 0xfffffff0...
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset.
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
void dumpAddress(raw_ostream &OS, uint64_t Address) const
static DWARFFormValue createFromPValue(dwarf::Form F, const char *V)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts=DIDumpOptions()) const
Expected< const char * > getAsCString() const
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
uint64_t tell() const
Return the current position of this Cursor.
Error takeError()
Return error contained inside this Cursor, if any.
size_t size() const
Return the number of bytes in the underlying buffer.
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
uint8_t getAddressSize() const
Get the address size for this extractor.
int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a signed LEB128 value from *offset_ptr.
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
void setAddressSize(uint8_t Size)
Set the address size for this extractor.
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
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...
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.
constexpr 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.
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
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 LLVM_LIFETIME_BOUND, 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.
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.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
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.
const char * toString(DWARFSectionKind Kind)
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.
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 ...
bool getDirectoryForEntry(const FileNameEntry &Entry, std::string &Directory) const
Extracts directory name by its Entry in include directories table in prologue.
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.
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 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
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
static const uint64_t UndefSection