LLVM 24.0.0git
DWARFDebugLine.cpp
Go to the documentation of this file.
1//===- DWARFDebugLine.cpp -------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
13#include "llvm/ADT/StringRef.h"
18#include "llvm/Support/Errc.h"
22#include <algorithm>
23#include <cassert>
24#include <cinttypes>
25#include <cstdint>
26#include <cstdio>
27#include <utility>
28
29using namespace llvm;
30using namespace dwarf;
31
32using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
33
34namespace {
35
36struct ContentDescriptor {
38 dwarf::Form Form;
39};
40
41using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
42
43} // end anonymous namespace
44
45static bool versionIsSupported(uint16_t Version) {
46 return Version >= 2 && Version <= 6;
47}
48
50 dwarf::LineNumberEntryFormat ContentType) {
51 switch (ContentType) {
52 case dwarf::DW_LNCT_timestamp:
53 HasModTime = true;
54 break;
55 case dwarf::DW_LNCT_size:
56 HasLength = true;
57 break;
58 case dwarf::DW_LNCT_MD5:
59 HasMD5 = true;
60 break;
61 case dwarf::DW_LNCT_LLVM_source:
62 HasSource = true;
63 break;
64 default:
65 // We only care about values we consider optional, and new values may be
66 // added in the vendor extension range, so we do not match exhaustively.
67 break;
68 }
69}
70
72
73bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const {
74 uint16_t DwarfVersion = getVersion();
75 assert(DwarfVersion != 0 &&
76 "line table prologue has no dwarf version information");
77 if (DwarfVersion >= 5)
78 return FileIndex < FileNames.size();
79 return FileIndex != 0 && FileIndex <= FileNames.size();
80}
81
82std::optional<uint64_t>
84 if (FileNames.empty())
85 return std::nullopt;
86 uint16_t DwarfVersion = getVersion();
87 assert(DwarfVersion != 0 &&
88 "line table prologue has no dwarf version information");
89 // In DWARF v5 the file names are 0-indexed.
90 if (DwarfVersion >= 5)
91 return FileNames.size() - 1;
92 return FileNames.size();
93}
94
97 uint16_t DwarfVersion = getVersion();
98 assert(DwarfVersion != 0 &&
99 "line table prologue has no dwarf version information");
100 // In DWARF v5 the file names are 0-indexed.
101 if (DwarfVersion >= 5)
102 return FileNames[Index];
103 return FileNames[Index - 1];
104}
105
117
119 DIDumpOptions DumpOptions) const {
120 if (!totalLengthIsValid())
121 return;
122 int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(FormParams.Format);
123 OS << "Line table prologue:\n"
124 << formatv(" total_length: 0x{0:x-}\n",
125 fmt_align(TotalLength, AlignStyle::Right, OffsetDumpWidth, '0'))
126 << " format: " << dwarf::FormatString(FormParams.Format) << "\n"
127 << formatv(" version: {0}\n", getVersion());
129 return;
130 if (getVersion() >= 5)
131 OS << formatv(" address_size: {0}\n", getAddressSize())
132 << formatv(" seg_select_size: {0}\n", SegSelectorSize);
133 OS << formatv(
134 " prologue_length: 0x{0:x-}\n",
135 fmt_align(PrologueLength, AlignStyle::Right, OffsetDumpWidth, '0'))
136 << formatv(" min_inst_length: {0}\n", MinInstLength);
137 if (getVersion() >= 4)
138 OS << formatv("max_ops_per_inst: {0}\n", MaxOpsPerInst);
139 OS << formatv(" default_is_stmt: {0}\n", DefaultIsStmt)
140 << formatv(" line_base: {0}\n", static_cast<int>(LineBase))
141 << formatv(" line_range: {0}\n", LineRange)
142 << formatv(" opcode_base: {0}\n", OpcodeBase);
143
144 for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
145 OS << formatv("standard_opcode_lengths[{0}] = {1}\n",
146 static_cast<dwarf::LineNumberOps>(I + 1),
148
149 if (!IncludeDirectories.empty()) {
150 // DWARF v5 starts directory indexes at 0.
151 uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
152 for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) {
153 OS << formatv("include_directories[{0,3}] = ", I + DirBase);
154 IncludeDirectories[I].dump(OS, DumpOptions);
155 OS << '\n';
156 }
157 }
158
159 if (!FileNames.empty()) {
160 // DWARF v5 starts file indexes at 0.
161 uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
162 for (uint32_t I = 0; I != FileNames.size(); ++I) {
163 const FileNameEntry &FileEntry = FileNames[I];
164 OS << formatv("file_names[{0,3}]:\n", I + FileBase);
165 OS << " name: ";
166 FileEntry.Name.dump(OS, DumpOptions);
167 OS << '\n' << formatv(" dir_index: {0}\n", FileEntry.DirIdx);
168 if (ContentTypes.HasMD5)
169 OS << " md5_checksum: " << FileEntry.Checksum.digest() << '\n';
170 if (ContentTypes.HasModTime)
171 OS << formatv(" mod_time: {0:x8}\n", FileEntry.ModTime);
172 if (ContentTypes.HasLength)
173 OS << formatv(" length: {0:x8}\n", FileEntry.Length);
174 if (ContentTypes.HasSource) {
175 auto Source = FileEntry.Source.getAsCString();
176 if (!Source)
177 consumeError(Source.takeError());
178 else if ((*Source)[0]) {
179 OS << " source: ";
180 FileEntry.Source.dump(OS, DumpOptions);
181 OS << '\n';
182 }
183 }
184 }
185 }
186}
187
188// Parse v2-v4 directory and file tables.
189static Error
191 uint64_t *OffsetPtr,
193 std::vector<DWARFFormValue> &IncludeDirectories,
194 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
195 while (true) {
196 Error Err = Error::success();
197 StringRef S = DebugLineData.getCStrRef(OffsetPtr, &Err);
198 if (Err) {
199 consumeError(std::move(Err));
201 "include directories table was not null "
202 "terminated before the end of the prologue");
203 }
204 if (S.empty())
205 break;
206 DWARFFormValue Dir =
207 DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, S.data());
208 IncludeDirectories.push_back(Dir);
209 }
210
211 ContentTypes.HasModTime = true;
212 ContentTypes.HasLength = true;
213
214 while (true) {
215 Error Err = Error::success();
216 StringRef Name = DebugLineData.getCStrRef(OffsetPtr, &Err);
217 if (!Err && Name.empty())
218 break;
219
221 FileEntry.Name =
222 DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name.data());
223 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr, &Err);
224 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr, &Err);
225 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr, &Err);
226
227 if (Err) {
228 consumeError(std::move(Err));
229 return createStringError(
231 "file names table was not null terminated before "
232 "the end of the prologue");
233 }
234 FileNames.push_back(FileEntry);
235 }
236
237 return Error::success();
238}
239
240// Parse v5 directory/file entry content descriptions.
241// Returns the descriptors, or an error if we did not find a path or ran off
242// the end of the prologue.
243static llvm::Expected<ContentDescriptors>
244parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
246 Error Err = Error::success();
247 ContentDescriptors Descriptors;
248 int FormatCount = DebugLineData.getU8(OffsetPtr, &Err);
249 bool HasPath = false;
250 for (int I = 0; I != FormatCount && !Err; ++I) {
251 ContentDescriptor Descriptor;
252 Descriptor.Type =
253 dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr, &Err));
254 Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr, &Err));
255 if (Descriptor.Type == dwarf::DW_LNCT_path)
256 HasPath = true;
257 if (ContentTypes)
258 ContentTypes->trackContentType(Descriptor.Type);
259 Descriptors.push_back(Descriptor);
260 }
261
262 if (Err)
264 "failed to parse entry content descriptors: %s",
265 toString(std::move(Err)).c_str());
266
267 if (!HasPath)
269 "failed to parse entry content descriptions"
270 " because no path was found");
271 return Descriptors;
272}
273
274static Error
276 uint64_t *OffsetPtr, const dwarf::FormParams &FormParams,
277 const DWARFContext &Ctx, const DWARFUnit *U,
279 std::vector<DWARFFormValue> &IncludeDirectories,
280 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
281 // Get the directory entry description.
283 parseV5EntryFormat(DebugLineData, OffsetPtr, nullptr);
284 if (!DirDescriptors)
285 return DirDescriptors.takeError();
286
287 // Get the directory entries, according to the format described above.
288 uint64_t DirEntryCount = DebugLineData.getULEB128(OffsetPtr);
289 for (uint64_t I = 0; I != DirEntryCount; ++I) {
290 for (auto Descriptor : *DirDescriptors) {
291 DWARFFormValue Value(Descriptor.Form);
292 switch (Descriptor.Type) {
293 case DW_LNCT_path:
294 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
296 "failed to parse directory entry because "
297 "extracting the form value failed");
298 IncludeDirectories.push_back(Value);
299 break;
300 default:
301 if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
303 "failed to parse directory entry because "
304 "skipping the form value failed");
305 }
306 }
307 }
308
309 // Get the file entry description.
310 llvm::Expected<ContentDescriptors> FileDescriptors =
311 parseV5EntryFormat(DebugLineData, OffsetPtr, &ContentTypes);
312 if (!FileDescriptors)
313 return FileDescriptors.takeError();
314
315 // Get the file entries, according to the format described above.
316 uint64_t FileEntryCount = DebugLineData.getULEB128(OffsetPtr);
317 for (uint64_t I = 0; I != FileEntryCount; ++I) {
319 for (auto Descriptor : *FileDescriptors) {
320 DWARFFormValue Value(Descriptor.Form);
321 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
323 "failed to parse file entry because "
324 "extracting the form value failed");
325 switch (Descriptor.Type) {
326 case DW_LNCT_path:
327 FileEntry.Name = Value;
328 break;
329 case DW_LNCT_LLVM_source:
330 FileEntry.Source = Value;
331 break;
332 case DW_LNCT_directory_index:
333 FileEntry.DirIdx = *Value.getAsUnsignedConstant();
334 break;
335 case DW_LNCT_timestamp:
336 FileEntry.ModTime = *Value.getAsUnsignedConstant();
337 break;
338 case DW_LNCT_size:
339 FileEntry.Length = *Value.getAsUnsignedConstant();
340 break;
341 case DW_LNCT_MD5:
342 if (!Value.getAsBlock() || Value.getAsBlock()->size() != 16)
343 return createStringError(
345 "failed to parse file entry because the MD5 hash is invalid");
346 llvm::uninitialized_copy(*Value.getAsBlock(),
347 FileEntry.Checksum.begin());
348 break;
349 default:
350 break;
351 }
352 }
353 FileNames.push_back(FileEntry);
354 }
355 return Error::success();
356}
357
360 sizeof(getVersion()) + sizeofPrologueLength();
361 if (getVersion() >= 5)
362 Length += 2; // Address + Segment selector sizes.
363 return Length;
364}
365
367 DWARFDataExtractor DebugLineData, uint64_t *OffsetPtr,
368 function_ref<void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx,
369 const DWARFUnit *U) {
370 const uint64_t PrologueOffset = *OffsetPtr;
371
372 clear();
373 DataExtractor::Cursor Cursor(*OffsetPtr);
374 std::tie(TotalLength, FormParams.Format) =
375 DebugLineData.getInitialLength(Cursor);
376
377 DebugLineData =
378 DWARFDataExtractor(DebugLineData, Cursor.tell() + TotalLength);
379 FormParams.Version = DebugLineData.getU16(Cursor);
380 if (Cursor && !versionIsSupported(getVersion())) {
381 // Treat this error as unrecoverable - we cannot be sure what any of
382 // the data represents including the length field, so cannot skip it or make
383 // any reasonable assumptions.
384 *OffsetPtr = Cursor.tell();
385 return createStringError(
387 "parsing line table prologue at offset 0x%8.8" PRIx64
388 ": unsupported version %" PRIu16,
389 PrologueOffset, getVersion());
390 }
391
392 if (getVersion() >= 5) {
393 FormParams.AddrSize = DebugLineData.getU8(Cursor);
394 const uint8_t DataAddrSize = DebugLineData.getAddressSize();
395 const uint8_t PrologueAddrSize = getAddressSize();
396 if (Cursor) {
397 if (DataAddrSize == 0) {
398 if (PrologueAddrSize != 4 && PrologueAddrSize != 8) {
399 RecoverableErrorHandler(createStringError(
401 "parsing line table prologue at offset 0x%8.8" PRIx64
402 ": invalid address size %" PRIu8,
403 PrologueOffset, PrologueAddrSize));
404 }
405 } else if (DataAddrSize != PrologueAddrSize) {
406 RecoverableErrorHandler(createStringError(
408 "parsing line table prologue at offset 0x%8.8" PRIx64 ": address "
409 "size %" PRIu8 " doesn't match architecture address size %" PRIu8,
410 PrologueOffset, PrologueAddrSize, DataAddrSize));
411 }
412 }
413 SegSelectorSize = DebugLineData.getU8(Cursor);
414 }
415
417 DebugLineData.getRelocatedValue(Cursor, sizeofPrologueLength());
418 const uint64_t EndPrologueOffset = PrologueLength + Cursor.tell();
419 DebugLineData = DWARFDataExtractor(DebugLineData, EndPrologueOffset);
420 MinInstLength = DebugLineData.getU8(Cursor);
421 if (getVersion() >= 4)
422 MaxOpsPerInst = DebugLineData.getU8(Cursor);
423 DefaultIsStmt = DebugLineData.getU8(Cursor);
424 LineBase = DebugLineData.getU8(Cursor);
425 LineRange = DebugLineData.getU8(Cursor);
426 OpcodeBase = DebugLineData.getU8(Cursor);
427
428 if (Cursor && OpcodeBase == 0) {
429 // If the opcode base is 0, we cannot read the standard opcode lengths (of
430 // which there are supposed to be one fewer than the opcode base). Assume
431 // there are no standard opcodes and continue parsing.
432 RecoverableErrorHandler(createStringError(
434 "parsing line table prologue at offset 0x%8.8" PRIx64
435 " found opcode base of 0. Assuming no standard opcodes",
436 PrologueOffset));
437 } else if (Cursor) {
439 for (uint32_t I = 1; I < OpcodeBase; ++I) {
440 uint8_t OpLen = DebugLineData.getU8(Cursor);
441 StandardOpcodeLengths.push_back(OpLen);
442 }
443 }
444
445 *OffsetPtr = Cursor.tell();
446 // A corrupt file name or directory table does not prevent interpretation of
447 // the main line program, so check the cursor state now so that its errors can
448 // be handled separately.
449 if (!Cursor)
450 return createStringError(
452 "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
453 PrologueOffset, toString(Cursor.takeError()).c_str());
454
455 Error E =
456 getVersion() >= 5
457 ? parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
459 : parseV2DirFileTables(DebugLineData, OffsetPtr, ContentTypes,
461 if (E) {
462 RecoverableErrorHandler(joinErrors(
465 "parsing line table prologue at 0x%8.8" PRIx64
466 " found an invalid directory or file table description at"
467 " 0x%8.8" PRIx64,
468 PrologueOffset, *OffsetPtr),
469 std::move(E)));
470 return Error::success();
471 }
472
473 assert(*OffsetPtr <= EndPrologueOffset);
474 if (*OffsetPtr != EndPrologueOffset) {
475 RecoverableErrorHandler(createStringError(
477 "unknown data in line table prologue at offset 0x%8.8" PRIx64
478 ": parsing ended (at offset 0x%8.8" PRIx64
479 ") before reaching the prologue end at offset 0x%8.8" PRIx64,
480 PrologueOffset, *OffsetPtr, EndPrologueOffset));
481 }
482 return Error::success();
483}
484
485DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
486
488 Discriminator = 0;
489 BasicBlock = false;
490 PrologueEnd = false;
491 EpilogueBegin = false;
492}
493
494void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
495 Address.Address = 0;
497 Line = 1;
498 Column = 0;
499 File = 1;
500 Isa = 0;
501 Discriminator = 0;
502 IsStmt = DefaultIsStmt;
503 OpIndex = 0;
504 BasicBlock = false;
505 EndSequence = false;
506 PrologueEnd = false;
507 EpilogueBegin = false;
508}
509
511 OS.indent(Indent)
512 << "Address Line Column File ISA Discriminator OpIndex "
513 "Flags\n";
514 OS.indent(Indent)
515 << "------------------ ------ ------ ------ --- ------------- ------- "
516 "-------------\n";
517}
518
520 OS << formatv("{0:x16} {1,6} {2,6}", Address.Address, Line, Column)
521 << formatv(" {0,6} {1,3} {2,13} {3,7} ", File, Isa, Discriminator, OpIndex)
522 << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
523 << (PrologueEnd ? " prologue_end" : "")
524 << (EpilogueBegin ? " epilogue_begin" : "")
525 << (EndSequence ? " end_sequence" : "") << '\n';
526}
527
529
539
541
543 DIDumpOptions DumpOptions) const {
544 Prologue.dump(OS, DumpOptions);
545
546 if (!Rows.empty()) {
547 OS << '\n';
549 for (const Row &R : Rows) {
550 R.dump(OS);
551 }
552 }
553
554 // Terminate the table with a final blank line to clearly delineate it from
555 // later dumps.
556 OS << '\n';
557}
558
560 Prologue.clear();
561 Rows.clear();
562 Sequences.clear();
563}
564
565DWARFDebugLine::ParsingState::ParsingState(
566 struct LineTable *LT, uint64_t TableOffset,
568 : LineTable(LT), LineTableOffset(TableOffset), ErrorHandler(ErrorHandler) {}
569
570void DWARFDebugLine::ParsingState::resetRowAndSequence(uint64_t Offset) {
571 Row.reset(LineTable->Prologue.DefaultIsStmt);
572 Sequence.reset();
573 Sequence.StmtSeqOffset = Offset;
574}
575
576void DWARFDebugLine::ParsingState::appendRowToMatrix() {
577 unsigned RowNumber = LineTable->Rows.size();
578 if (Sequence.Empty) {
579 // Record the beginning of instruction sequence.
580 Sequence.Empty = false;
581 Sequence.LowPC = Row.Address.Address;
582 Sequence.FirstRowIndex = RowNumber;
583 }
585 if (Row.EndSequence) {
586 // Record the end of instruction sequence.
588 Sequence.LastRowIndex = RowNumber + 1;
590 if (Sequence.isValid())
592 Sequence.reset();
593 }
594 Row.postAppend();
595}
596
597const DWARFDebugLine::LineTable *
599 LineTableConstIter Pos = LineTableMap.find(Offset);
600 if (Pos != LineTableMap.end())
601 return &Pos->second;
602 return nullptr;
603}
604
606 DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx,
607 const DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
608 if (!DebugLineData.isValidOffset(Offset))
610 "offset 0x%8.8" PRIx64
611 " is not a valid debug line section offset",
612 Offset);
613
614 std::pair<LineTableIter, bool> Pos =
615 LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
616 LineTable *LT = &Pos.first->second;
617 if (Pos.second) {
618 if (Error Err =
619 LT->parse(DebugLineData, &Offset, Ctx, U, RecoverableErrorHandler))
620 return std::move(Err);
621 return LT;
622 }
623 return LT;
624}
625
627 LineTableMap.erase(Offset);
628}
629
630static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase) {
631 assert(Opcode != 0);
632 if (Opcode < OpcodeBase)
633 return LNStandardString(Opcode);
634 return "special";
635}
636
637DWARFDebugLine::ParsingState::AddrOpIndexDelta
638DWARFDebugLine::ParsingState::advanceAddrOpIndex(uint64_t OperationAdvance,
639 uint8_t Opcode,
640 uint64_t OpcodeOffset) {
641 StringRef OpcodeName = getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
642 // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
643 // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
644 // Don't warn about bad values in this situation.
645 if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
649 "line table program at offset 0x%8.8" PRIx64
650 " contains a %s opcode at offset 0x%8.8" PRIx64
651 ", but the prologue maximum_operations_per_instruction value is 0"
652 ", which is invalid. Assuming a value of 1 instead",
653 LineTableOffset, OpcodeName.data(), OpcodeOffset));
654 // Although we are able to correctly parse line number programs with
655 // MaxOpsPerInst > 1, the rest of DWARFDebugLine and its
656 // users have not been updated to handle line information for all operations
657 // in a multi-operation instruction, so warn about potentially incorrect
658 // results.
659 if (ReportAdvanceAddrProblem && LineTable->Prologue.MaxOpsPerInst > 1)
662 "line table program at offset 0x%8.8" PRIx64
663 " contains a %s opcode at offset 0x%8.8" PRIx64
664 ", but the prologue maximum_operations_per_instruction value is %" PRId8
665 ", which is experimentally supported, so line number information "
666 "may be incorrect",
667 LineTableOffset, OpcodeName.data(), OpcodeOffset,
669 if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
672 "line table program at offset 0x%8.8" PRIx64
673 " contains a %s opcode at offset 0x%8.8" PRIx64
674 ", but the prologue minimum_instruction_length value "
675 "is 0, which prevents any address advancing",
676 LineTableOffset, OpcodeName.data(), OpcodeOffset));
677 ReportAdvanceAddrProblem = false;
678
679 // Advances the address and op_index according to DWARFv5, section 6.2.5.1:
680 //
681 // new address = address +
682 // minimum_instruction_length *
683 // ((op_index + operation advance) / maximum_operations_per_instruction)
684 //
685 // new op_index =
686 // (op_index + operation advance) % maximum_operations_per_instruction
687
688 // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
689 // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
690 uint8_t MaxOpsPerInst =
691 std::max(LineTable->Prologue.MaxOpsPerInst, uint8_t{1});
692
693 uint64_t AddrOffset = ((Row.OpIndex + OperationAdvance) / MaxOpsPerInst) *
695 Row.Address.Address += AddrOffset;
696
697 uint8_t PrevOpIndex = Row.OpIndex;
698 Row.OpIndex = (Row.OpIndex + OperationAdvance) % MaxOpsPerInst;
699 int16_t OpIndexDelta = static_cast<int16_t>(Row.OpIndex) - PrevOpIndex;
700
701 return {AddrOffset, OpIndexDelta};
702}
703
704DWARFDebugLine::ParsingState::OpcodeAdvanceResults
705DWARFDebugLine::ParsingState::advanceForOpcode(uint8_t Opcode,
706 uint64_t OpcodeOffset) {
707 assert(Opcode == DW_LNS_const_add_pc ||
708 Opcode >= LineTable->Prologue.OpcodeBase);
709 if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
710 StringRef OpcodeName =
714 "line table program at offset 0x%8.8" PRIx64
715 " contains a %s opcode at offset 0x%8.8" PRIx64
716 ", but the prologue line_range value is 0. The "
717 "address and line will not be adjusted",
718 LineTableOffset, OpcodeName.data(), OpcodeOffset));
719 ReportBadLineRange = false;
720 }
721
722 uint8_t OpcodeValue = Opcode;
723 if (Opcode == DW_LNS_const_add_pc)
724 OpcodeValue = 255;
725 uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
726 uint64_t OperationAdvance =
728 ? AdjustedOpcode / LineTable->Prologue.LineRange
729 : 0;
730 AddrOpIndexDelta Advance =
731 advanceAddrOpIndex(OperationAdvance, Opcode, OpcodeOffset);
732 return {Advance.AddrOffset, Advance.OpIndexDelta, AdjustedOpcode};
733}
734
735DWARFDebugLine::ParsingState::SpecialOpcodeDelta
736DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
737 uint64_t OpcodeOffset) {
738 // A special opcode value is chosen based on the amount that needs
739 // to be added to the line and address registers. The maximum line
740 // increment for a special opcode is the value of the line_base
741 // field in the header, plus the value of the line_range field,
742 // minus 1 (line base + line range - 1). If the desired line
743 // increment is greater than the maximum line increment, a standard
744 // opcode must be used instead of a special opcode. The "address
745 // advance" is calculated by dividing the desired address increment
746 // by the minimum_instruction_length field from the header. The
747 // special opcode is then calculated using the following formula:
748 //
749 // opcode = (desired line increment - line_base) +
750 // (line_range * address advance) + opcode_base
751 //
752 // If the resulting opcode is greater than 255, a standard opcode
753 // must be used instead.
754 //
755 // To decode a special opcode, subtract the opcode_base from the
756 // opcode itself to give the adjusted opcode. The amount to
757 // increment the address register is the result of the adjusted
758 // opcode divided by the line_range multiplied by the
759 // minimum_instruction_length field from the header. That is:
760 //
761 // address increment = (adjusted opcode / line_range) *
762 // minimum_instruction_length
763 //
764 // The amount to increment the line register is the line_base plus
765 // the result of the adjusted opcode modulo the line_range. That is:
766 //
767 // line increment = line_base + (adjusted opcode % line_range)
768
769 DWARFDebugLine::ParsingState::OpcodeAdvanceResults AddrAdvanceResult =
770 advanceForOpcode(Opcode, OpcodeOffset);
771 int32_t LineOffset = 0;
772 if (LineTable->Prologue.LineRange != 0)
773 LineOffset =
775 (AddrAdvanceResult.AdjustedOpcode % LineTable->Prologue.LineRange);
776 Row.Line += LineOffset;
777 return {AddrAdvanceResult.AddrDelta, LineOffset,
778 AddrAdvanceResult.OpIndexDelta};
779}
780
781/// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on
782/// success, or std::nullopt if \p Cursor is in a failing state.
783template <typename T>
784static std::optional<T> parseULEB128(DWARFDataExtractor &Data,
785 DataExtractor::Cursor &Cursor) {
786 T Value = Data.getULEB128(Cursor);
787 if (Cursor)
788 return Value;
789 return std::nullopt;
790}
791
793 DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
794 const DWARFContext &Ctx, const DWARFUnit *U,
795 function_ref<void(Error)> RecoverableErrorHandler, raw_ostream *OS,
796 bool Verbose) {
797 assert((OS || !Verbose) && "cannot have verbose output without stream");
798 const uint64_t DebugLineOffset = *OffsetPtr;
799
800 clear();
801
802 Error PrologueErr =
803 Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
804
805 if (OS) {
806 DIDumpOptions DumpOptions;
807 DumpOptions.Verbose = Verbose;
808 Prologue.dump(*OS, DumpOptions);
809 }
810
811 if (PrologueErr) {
812 // Ensure there is a blank line after the prologue to clearly delineate it
813 // from later dumps.
814 if (OS)
815 *OS << "\n";
816 return PrologueErr;
817 }
818
819 uint64_t ProgramLength = Prologue.TotalLength + Prologue.sizeofTotalLength();
820 if (!DebugLineData.isValidOffsetForDataOfSize(DebugLineOffset,
821 ProgramLength)) {
822 assert(DebugLineData.size() > DebugLineOffset &&
823 "prologue parsing should handle invalid offset");
824 uint64_t BytesRemaining = DebugLineData.size() - DebugLineOffset;
825 RecoverableErrorHandler(
827 "line table program with offset 0x%8.8" PRIx64
828 " has length 0x%8.8" PRIx64 " but only 0x%8.8" PRIx64
829 " bytes are available",
830 DebugLineOffset, ProgramLength, BytesRemaining));
831 // Continue by capping the length at the number of remaining bytes.
832 ProgramLength = BytesRemaining;
833 }
834
835 // Create a DataExtractor which can only see the data up to the end of the
836 // table, to prevent reading past the end.
837 const uint64_t EndOffset = DebugLineOffset + ProgramLength;
838 DWARFDataExtractor TableData(DebugLineData, EndOffset);
839
840 // See if we should tell the data extractor the address size.
841 if (TableData.getAddressSize() == 0)
842 TableData.setAddressSize(Prologue.getAddressSize());
843 else
844 assert(Prologue.getAddressSize() == 0 ||
845 Prologue.getAddressSize() == TableData.getAddressSize());
846
847 ParsingState State(this, DebugLineOffset, RecoverableErrorHandler);
848
849 *OffsetPtr = DebugLineOffset + Prologue.getLength();
850 if (OS && *OffsetPtr < EndOffset) {
851 *OS << '\n';
852 Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
853 }
854 // *OffsetPtr points to the end of the prologue - i.e. the start of the first
855 // sequence. So initialize the first sequence offset accordingly.
856 State.resetRowAndSequence(*OffsetPtr);
857
858 bool TombstonedAddress = false;
859 auto EmitRow = [&] {
860 if (!TombstonedAddress) {
861 if (Verbose) {
862 *OS << "\n";
863 OS->indent(12);
864 }
865 if (OS)
866 State.Row.dump(*OS);
867 State.appendRowToMatrix();
868 }
869 };
870 while (*OffsetPtr < EndOffset) {
871 DataExtractor::Cursor Cursor(*OffsetPtr);
872
873 if (Verbose)
874 *OS << formatv("{0:x8}: ", *OffsetPtr);
875
876 uint64_t OpcodeOffset = *OffsetPtr;
877 uint8_t Opcode = TableData.getU8(Cursor);
878 size_t RowCount = Rows.size();
879
880 if (Cursor && Verbose)
881 *OS << formatv("{0:x-2} ", Opcode);
882
883 if (Opcode == 0) {
884 // Extended Opcodes always start with a zero opcode followed by
885 // a uleb128 length so you can skip ones you don't know about
886 uint64_t Len = TableData.getULEB128(Cursor);
887 uint64_t ExtOffset = Cursor.tell();
888
889 // Tolerate zero-length; assume length is correct and soldier on.
890 if (Len == 0) {
891 if (Cursor && Verbose)
892 *OS << "Badly formed extended line op (length 0)\n";
893 if (!Cursor) {
894 if (Verbose)
895 *OS << "\n";
896 RecoverableErrorHandler(Cursor.takeError());
897 }
898 *OffsetPtr = Cursor.tell();
899 continue;
900 }
901
902 uint8_t SubOpcode = TableData.getU8(Cursor);
903 // OperandOffset will be the same as ExtOffset, if it was not possible to
904 // read the SubOpcode.
905 uint64_t OperandOffset = Cursor.tell();
906 if (Verbose)
907 *OS << LNExtendedString(SubOpcode);
908 switch (SubOpcode) {
909 case DW_LNE_end_sequence:
910 // Set the end_sequence register of the state machine to true and
911 // append a row to the matrix using the current values of the
912 // state-machine registers. Then reset the registers to the initial
913 // values specified above. Every statement program sequence must end
914 // with a DW_LNE_end_sequence instruction which creates a row whose
915 // address is that of the byte after the last target machine instruction
916 // of the sequence.
917 State.Row.EndSequence = true;
918 // No need to test the Cursor is valid here, since it must be to get
919 // into this code path - if it were invalid, the default case would be
920 // followed.
921 EmitRow();
922 // Cursor now points to right after the end_sequence opcode - so points
923 // to the start of the next sequence - if one exists.
924 State.resetRowAndSequence(Cursor.tell());
925 break;
926
927 case DW_LNE_set_address:
928 // Takes a single relocatable address as an operand. The size of the
929 // operand is the size appropriate to hold an address on the target
930 // machine. Set the address register to the value given by the
931 // relocatable address and set the op_index register to 0. All of the
932 // other statement program opcodes that affect the address register
933 // add a delta to it. This instruction stores a relocatable value into
934 // it instead.
935 //
936 // Make sure the extractor knows the address size. If not, infer it
937 // from the size of the operand.
938 {
939 uint8_t ExtractorAddressSize = TableData.getAddressSize();
940 uint64_t OpcodeAddressSize = Len - 1;
941 if (ExtractorAddressSize != OpcodeAddressSize &&
942 ExtractorAddressSize != 0)
943 RecoverableErrorHandler(createStringError(
945 "mismatching address size at offset 0x%8.8" PRIx64
946 " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
947 ExtOffset, ExtractorAddressSize, Len - 1));
948
949 // Assume that the line table is correct and temporarily override the
950 // address size. If the size is unsupported, give up trying to read
951 // the address and continue to the next opcode.
952 if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
953 OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
954 RecoverableErrorHandler(createStringError(
956 "address size 0x%2.2" PRIx64
957 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
958 " is unsupported",
959 OpcodeAddressSize, ExtOffset));
960 TableData.skip(Cursor, OpcodeAddressSize);
961 } else {
962 TableData.setAddressSize(OpcodeAddressSize);
963 State.Row.Address.Address = TableData.getRelocatedAddress(
964 Cursor, &State.Row.Address.SectionIndex);
965 State.Row.OpIndex = 0;
966
967 uint64_t Tombstone =
968 dwarf::computeTombstoneAddress(OpcodeAddressSize);
969 TombstonedAddress = State.Row.Address.Address == Tombstone;
970
971 // Restore the address size if the extractor already had it.
972 if (ExtractorAddressSize != 0)
973 TableData.setAddressSize(ExtractorAddressSize);
974 }
975
976 if (Cursor && Verbose) {
977 *OS << " (";
978 DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize,
979 State.Row.Address.Address);
980 *OS << ')';
981 }
982 }
983 break;
984
985 case DW_LNE_define_file:
986 // Takes 4 arguments. The first is a null terminated string containing
987 // a source file name. The second is an unsigned LEB128 number
988 // representing the directory index of the directory in which the file
989 // was found. The third is an unsigned LEB128 number representing the
990 // time of last modification of the file. The fourth is an unsigned
991 // LEB128 number representing the length in bytes of the file. The time
992 // and length fields may contain LEB128(0) if the information is not
993 // available.
994 //
995 // The directory index represents an entry in the include_directories
996 // section of the statement program prologue. The index is LEB128(0)
997 // if the file was found in the current directory of the compilation,
998 // LEB128(1) if it was found in the first directory in the
999 // include_directories section, and so on. The directory index is
1000 // ignored for file names that represent full path names.
1001 //
1002 // The files are numbered, starting at 1, in the order in which they
1003 // appear; the names in the prologue come before names defined by
1004 // the DW_LNE_define_file instruction. These numbers are used in the
1005 // the file register of the state machine.
1006 {
1007 FileNameEntry FileEntry;
1008 const char *Name = TableData.getCStr(Cursor);
1009 FileEntry.Name =
1010 DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name);
1011 FileEntry.DirIdx = TableData.getULEB128(Cursor);
1012 FileEntry.ModTime = TableData.getULEB128(Cursor);
1013 FileEntry.Length = TableData.getULEB128(Cursor);
1014 Prologue.FileNames.push_back(FileEntry);
1015 if (Cursor && Verbose)
1016 *OS << " (" << Name << ", dir=" << FileEntry.DirIdx
1017 << ", mod_time=" << formatv("({0:x16})", FileEntry.ModTime)
1018 << ", length=" << FileEntry.Length << ")";
1019 }
1020 break;
1021
1022 case DW_LNE_set_discriminator:
1023 State.Row.Discriminator = TableData.getULEB128(Cursor);
1024 if (Cursor && Verbose)
1025 *OS << " (" << State.Row.Discriminator << ")";
1026 break;
1027
1028 default:
1029 if (Cursor && Verbose)
1030 *OS << formatv("Unrecognized extended op {0:x2}", SubOpcode)
1031 << formatv(" length {0:x-}", Len);
1032 // Len doesn't include the zero opcode byte or the length itself, but
1033 // it does include the sub_opcode, so we have to adjust for that.
1034 TableData.skip(Cursor, Len - 1);
1035 break;
1036 }
1037 // Make sure the length as recorded in the table and the standard length
1038 // for the opcode match. If they don't, continue from the end as claimed
1039 // by the table. Similarly, continue from the claimed end in the event of
1040 // a parsing error.
1041 uint64_t End = ExtOffset + Len;
1042 if (Cursor && Cursor.tell() != End)
1043 RecoverableErrorHandler(createStringError(
1045 "unexpected line op length at offset 0x%8.8" PRIx64
1046 " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
1047 ExtOffset, Len, Cursor.tell() - ExtOffset));
1048 if (!Cursor && Verbose) {
1049 DWARFDataExtractor::Cursor ByteCursor(OperandOffset);
1050 uint8_t Byte = TableData.getU8(ByteCursor);
1051 if (ByteCursor) {
1052 *OS << " (<parsing error>";
1053 do {
1054 *OS << formatv(" {0:x-2}", Byte);
1055 Byte = TableData.getU8(ByteCursor);
1056 } while (ByteCursor);
1057 *OS << ")";
1058 }
1059
1060 // The only parse failure in this case should be if the end was reached.
1061 // In that case, throw away the error, as the main Cursor's error will
1062 // be sufficient.
1063 consumeError(ByteCursor.takeError());
1064 }
1065 *OffsetPtr = End;
1066 } else if (Opcode < Prologue.OpcodeBase) {
1067 if (Verbose)
1068 *OS << LNStandardString(Opcode);
1069 switch (Opcode) {
1070 // Standard Opcodes
1071 case DW_LNS_copy:
1072 // Takes no arguments. Append a row to the matrix using the
1073 // current values of the state-machine registers.
1074 EmitRow();
1075 break;
1076
1077 case DW_LNS_advance_pc:
1078 // Takes a single unsigned LEB128 operand as the operation advance
1079 // and modifies the address and op_index registers of the state machine
1080 // according to that.
1081 if (std::optional<uint64_t> Operand =
1082 parseULEB128<uint64_t>(TableData, Cursor)) {
1084 State.advanceAddrOpIndex(*Operand, Opcode, OpcodeOffset);
1085 if (Verbose)
1086 *OS << " (addr += " << Advance.AddrOffset
1087 << ", op-index += " << Advance.OpIndexDelta << ")";
1088 }
1089 break;
1090
1091 case DW_LNS_advance_line:
1092 // Takes a single signed LEB128 operand and adds that value to
1093 // the line register of the state machine.
1094 {
1095 int64_t LineDelta = TableData.getSLEB128(Cursor);
1096 if (Cursor) {
1097 State.Row.Line += LineDelta;
1098 if (Verbose)
1099 *OS << " (" << State.Row.Line << ")";
1100 }
1101 }
1102 break;
1103
1104 case DW_LNS_set_file:
1105 // Takes a single unsigned LEB128 operand and stores it in the file
1106 // register of the state machine.
1107 if (std::optional<uint16_t> File =
1108 parseULEB128<uint16_t>(TableData, Cursor)) {
1109 State.Row.File = *File;
1110 if (Verbose)
1111 *OS << " (" << State.Row.File << ")";
1112 }
1113 break;
1114
1115 case DW_LNS_set_column:
1116 // Takes a single unsigned LEB128 operand and stores it in the
1117 // column register of the state machine.
1118 if (std::optional<uint16_t> Column =
1119 parseULEB128<uint16_t>(TableData, Cursor)) {
1120 State.Row.Column = *Column;
1121 if (Verbose)
1122 *OS << " (" << State.Row.Column << ")";
1123 }
1124 break;
1125
1126 case DW_LNS_negate_stmt:
1127 // Takes no arguments. Set the is_stmt register of the state
1128 // machine to the logical negation of its current value.
1129 State.Row.IsStmt = !State.Row.IsStmt;
1130 break;
1131
1132 case DW_LNS_set_basic_block:
1133 // Takes no arguments. Set the basic_block register of the
1134 // state machine to true
1135 State.Row.BasicBlock = true;
1136 break;
1137
1138 case DW_LNS_const_add_pc:
1139 // Takes no arguments. Advance the address and op_index registers of
1140 // the state machine by the increments corresponding to special
1141 // opcode 255. The motivation for DW_LNS_const_add_pc is this:
1142 // when the statement program needs to advance the address by a
1143 // small amount, it can use a single special opcode, which occupies
1144 // a single byte. When it needs to advance the address by up to
1145 // twice the range of the last special opcode, it can use
1146 // DW_LNS_const_add_pc followed by a special opcode, for a total
1147 // of two bytes. Only if it needs to advance the address by more
1148 // than twice that range will it need to use both DW_LNS_advance_pc
1149 // and a special opcode, requiring three or more bytes.
1150 {
1152 State.advanceForOpcode(Opcode, OpcodeOffset);
1153 if (Verbose)
1154 *OS << formatv(" (addr += {0:x16}, op-index += {1})",
1155 Advance.AddrDelta, Advance.OpIndexDelta);
1156 }
1157 break;
1158
1159 case DW_LNS_fixed_advance_pc:
1160 // Takes a single uhalf operand. Add to the address register of
1161 // the state machine the value of the (unencoded) operand and set
1162 // the op_index register to 0. This is the only extended opcode that
1163 // takes an argument that is not a variable length number.
1164 // The motivation for DW_LNS_fixed_advance_pc is this: existing
1165 // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
1166 // they cannot encode LEB128 numbers or judge when the computation
1167 // of a special opcode overflows and requires the use of
1168 // DW_LNS_advance_pc. Such assemblers, however, can use
1169 // DW_LNS_fixed_advance_pc instead, sacrificing compression.
1170 {
1171 uint16_t PCOffset = TableData.getRelocatedValue(Cursor, 2);
1172 if (Cursor) {
1173 State.Row.Address.Address += PCOffset;
1174 State.Row.OpIndex = 0;
1175 if (Verbose)
1176 *OS << formatv(" (addr += {0:x4}, op-index = 0)", PCOffset);
1177 }
1178 }
1179 break;
1180
1181 case DW_LNS_set_prologue_end:
1182 // Takes no arguments. Set the prologue_end register of the
1183 // state machine to true
1184 State.Row.PrologueEnd = true;
1185 break;
1186
1187 case DW_LNS_set_epilogue_begin:
1188 // Takes no arguments. Set the basic_block register of the
1189 // state machine to true
1190 State.Row.EpilogueBegin = true;
1191 break;
1192
1193 case DW_LNS_set_isa:
1194 // Takes a single unsigned LEB128 operand and stores it in the
1195 // ISA register of the state machine.
1196 if (std::optional<uint8_t> Isa =
1197 parseULEB128<uint8_t>(TableData, Cursor)) {
1198 State.Row.Isa = *Isa;
1199 if (Verbose)
1200 *OS << " (" << (uint64_t)State.Row.Isa << ")";
1201 }
1202 break;
1203
1204 default:
1205 // Handle any unknown standard opcodes here. We know the lengths
1206 // of such opcodes because they are specified in the prologue
1207 // as a multiple of LEB128 operands for each opcode.
1208 {
1209 assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
1210 if (Verbose)
1211 *OS << "Unrecognized standard opcode";
1212 uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
1213 std::vector<uint64_t> Operands;
1214 for (uint8_t I = 0; I < OpcodeLength; ++I) {
1215 if (std::optional<uint64_t> Value =
1216 parseULEB128<uint64_t>(TableData, Cursor))
1217 Operands.push_back(*Value);
1218 else
1219 break;
1220 }
1221 if (Verbose && !Operands.empty()) {
1222 *OS << " (operands: ";
1223 ListSeparator LS;
1224 for (uint64_t Value : Operands)
1225 *OS << LS << formatv("{0:x16}", Value);
1226 *OS << ')';
1227 }
1228 }
1229 break;
1230 }
1231
1232 *OffsetPtr = Cursor.tell();
1233 } else {
1234 // Special Opcodes.
1236 State.handleSpecialOpcode(Opcode, OpcodeOffset);
1237
1238 if (Verbose)
1239 *OS << "address += " << Delta.Address << ", line += " << Delta.Line
1240 << ", op-index += " << Delta.OpIndex;
1241 EmitRow();
1242 *OffsetPtr = Cursor.tell();
1243 }
1244
1245 // When a row is added to the matrix, it is also dumped, which includes a
1246 // new line already, so don't add an extra one.
1247 if (Verbose && Rows.size() == RowCount)
1248 *OS << "\n";
1249
1250 // Most parse failures other than when parsing extended opcodes are due to
1251 // failures to read ULEBs. Bail out of parsing, since we don't know where to
1252 // continue reading from as there is no stated length for such byte
1253 // sequences. Print the final trailing new line if needed before doing so.
1254 if (!Cursor && Opcode != 0) {
1255 if (Verbose)
1256 *OS << "\n";
1257 return Cursor.takeError();
1258 }
1259
1260 if (!Cursor)
1261 RecoverableErrorHandler(Cursor.takeError());
1262 }
1263
1264 if (!State.Sequence.Empty)
1265 RecoverableErrorHandler(createStringError(
1267 "last sequence in debug line table at offset 0x%8.8" PRIx64
1268 " is not terminated",
1269 DebugLineOffset));
1270
1271 Rows.shrink_to_fit();
1272 Sequences.shrink_to_fit();
1273
1274 // Sort all sequences so that address lookup will work faster.
1275 if (!Sequences.empty()) {
1277 // Note: actually, instruction address ranges of sequences should not
1278 // overlap (in shared objects and executables). If they do, the address
1279 // lookup would still work, though, but result would be ambiguous.
1280 // We don't report warning in this case. For example,
1281 // sometimes .so compiled from multiple object files contains a few
1282 // rudimentary sequences for address ranges [0x0, 0xsomething).
1283 // Address ranges may also overlap when using ICF.
1284 }
1285
1286 // Terminate the table with a final blank line to clearly delineate it from
1287 // later dumps.
1288 if (OS)
1289 *OS << "\n";
1290
1291 return Error::success();
1292}
1293
1294uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1295 const DWARFDebugLine::Sequence &Seq,
1297 if (!Seq.containsPC(Address))
1298 return UnknownRowIndex;
1299 assert(Seq.SectionIndex == Address.SectionIndex);
1300 // In some cases, e.g. first instruction in a function, the compiler generates
1301 // two entries, both with the same address. We want the last one.
1302 //
1303 // In general we want a non-empty range: the last row whose address is less
1304 // than or equal to Address. This can be computed as upper_bound - 1.
1305 //
1306 // TODO: This function, and its users, needs to be update to return multiple
1307 // rows for bundles with multiple op-indexes.
1310 RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
1311 RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
1312 assert(FirstRow->Address.Address <= Row.Address.Address &&
1313 Row.Address.Address < LastRow[-1].Address.Address);
1314 RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1, Row,
1316 1;
1317 assert(Seq.SectionIndex == RowPos->Address.SectionIndex);
1318 return RowPos - Rows.begin();
1319}
1320
1323 bool *IsApproximateLine) const {
1324
1325 // Search for relocatable addresses
1326 uint32_t Result = lookupAddressImpl(Address, IsApproximateLine);
1327
1328 if (Result != UnknownRowIndex ||
1330 return Result;
1331
1332 // Search for absolute addresses
1334 return lookupAddressImpl(Address, IsApproximateLine);
1335}
1336
1338DWARFDebugLine::LineTable::lookupAddressImpl(object::SectionedAddress Address,
1339 bool *IsApproximateLine) const {
1340 assert((!IsApproximateLine || !*IsApproximateLine) &&
1341 "Make sure IsApproximateLine is appropriately "
1342 "initialized, if provided");
1343 // First, find an instruction sequence containing the given address.
1345 Sequence.SectionIndex = Address.SectionIndex;
1346 Sequence.HighPC = Address.Address;
1347 SequenceIter It = llvm::upper_bound(Sequences, Sequence,
1349 if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
1350 return UnknownRowIndex;
1351
1352 uint32_t RowIndex = findRowInSeq(*It, Address);
1353 if (RowIndex == UnknownRowIndex || !IsApproximateLine)
1354 return RowIndex;
1355
1356 // Approximation will only be attempted if a valid RowIndex exists.
1357 uint32_t ApproxRowIndex = RowIndex;
1358 // Approximation Loop
1359 for (; ApproxRowIndex >= It->FirstRowIndex; --ApproxRowIndex) {
1360 if (Rows[ApproxRowIndex].Line)
1361 return ApproxRowIndex;
1362 *IsApproximateLine = true;
1363 }
1364 // Approximation Loop fails to find the valid ApproxRowIndex
1365 if (ApproxRowIndex < It->FirstRowIndex)
1366 *IsApproximateLine = false;
1367
1368 return RowIndex;
1369}
1370
1373 std::vector<uint32_t> &Result,
1374 std::optional<uint64_t> StmtSequenceOffset) const {
1375
1376 // Search for relocatable addresses
1377 if (lookupAddressRangeImpl(Address, Size, Result, StmtSequenceOffset))
1378 return true;
1379
1381 return false;
1382
1383 // Search for absolute addresses
1385 return lookupAddressRangeImpl(Address, Size, Result, StmtSequenceOffset);
1386}
1387
1388bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1390 std::vector<uint32_t> &Result,
1391 std::optional<uint64_t> StmtSequenceOffset) const {
1392 if (Sequences.empty())
1393 return false;
1394 uint64_t EndAddr = Address.Address + Size;
1395 // First, find an instruction sequence containing the given address.
1397 Sequence.SectionIndex = Address.SectionIndex;
1398 Sequence.HighPC = Address.Address;
1399 SequenceIter LastSeq = Sequences.end();
1400 SequenceIter SeqPos;
1401
1402 if (StmtSequenceOffset) {
1403 // If we have a statement sequence offset, find the specific sequence.
1404 // Linear search for sequence with matching StmtSeqOffset
1405 SeqPos = std::find_if(Sequences.begin(), LastSeq,
1406 [&](const DWARFDebugLine::Sequence &S) {
1407 return S.StmtSeqOffset == *StmtSequenceOffset;
1408 });
1409
1410 // If sequence not found, return false
1411 if (SeqPos == LastSeq)
1412 return false;
1413
1414 // Set LastSeq to the next sequence since we only want the one matching
1415 // sequence (sequences are guaranteed to have unique StmtSeqOffset)
1416 LastSeq = SeqPos + 1;
1417 } else {
1418 // No specific sequence requested, find first sequence containing address
1419 SeqPos = std::upper_bound(Sequences.begin(), LastSeq, Sequence,
1421 if (SeqPos == LastSeq)
1422 return false;
1423 }
1424
1425 // If the start sequence doesn't contain the address, nothing to do
1426 if (!SeqPos->containsPC(Address))
1427 return false;
1428
1429 SequenceIter StartPos = SeqPos;
1430
1431 // Process sequences that overlap with the desired range
1432 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
1433 const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
1434 // For the first sequence, we need to find which row in the sequence is the
1435 // first in our range.
1436 uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
1437 if (SeqPos == StartPos)
1438 FirstRowIndex = findRowInSeq(CurSeq, Address);
1439
1440 // Figure out the last row in the range.
1441 uint32_t LastRowIndex =
1442 findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
1443 if (LastRowIndex == UnknownRowIndex)
1444 LastRowIndex = CurSeq.LastRowIndex - 1;
1445
1446 assert(FirstRowIndex != UnknownRowIndex);
1447 assert(LastRowIndex != UnknownRowIndex);
1448
1449 for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
1450 Result.push_back(I);
1451 }
1452
1453 ++SeqPos;
1454 }
1455
1456 return true;
1457}
1458
1459std::optional<StringRef>
1460DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
1461 FileLineInfoKind Kind) const {
1462 if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
1463 return std::nullopt;
1464 const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex);
1465 if (auto E = dwarf::toString(Entry.Source))
1466 return StringRef(*E);
1467 return std::nullopt;
1468}
1469
1470static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
1471 // Debug info can contain paths from any OS, not necessarily
1472 // an OS we're currently running on. Moreover different compilation units can
1473 // be compiled on different operating systems and linked together later.
1476}
1477
1479 uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind,
1480 std::string &Result, sys::path::Style Style) const {
1481 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
1482 return false;
1483 const FileNameEntry &Entry = getFileNameEntry(FileIndex);
1484 auto E = dwarf::toString(Entry.Name);
1485 if (!E)
1486 return false;
1487 StringRef FileName = *E;
1488 if (Kind == FileLineInfoKind::RawValue ||
1490 Result = std::string(FileName);
1491 return true;
1492 }
1493 if (Kind == FileLineInfoKind::BaseNameOnly) {
1494 Result = std::string(llvm::sys::path::filename(FileName));
1495 return true;
1496 }
1497
1498 SmallString<16> FilePath;
1499 StringRef IncludeDir;
1500 // Be defensive about the contents of Entry.
1501 if (getVersion() >= 5) {
1502 // DirIdx 0 is the compilation directory, so don't include it for
1503 // relative names.
1504 if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1505 Entry.DirIdx < IncludeDirectories.size())
1506 IncludeDir = dwarf::toStringRef(IncludeDirectories[Entry.DirIdx]);
1507 } else {
1508 if (0 < Entry.DirIdx && Entry.DirIdx <= IncludeDirectories.size())
1509 IncludeDir = dwarf::toStringRef(IncludeDirectories[Entry.DirIdx - 1]);
1510 }
1511
1512 // For absolute paths only, include the compilation directory of compile unit,
1513 // unless v5 DirIdx == 0 (IncludeDir indicates the compilation directory). We
1514 // know that FileName is not absolute, the only way to have an absolute path
1515 // at this point would be if IncludeDir is absolute.
1516 if (Kind == FileLineInfoKind::AbsoluteFilePath &&
1517 (getVersion() < 5 || Entry.DirIdx != 0) && !CompDir.empty() &&
1518 !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
1519 sys::path::append(FilePath, Style, CompDir);
1520
1521 assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1522 Kind == FileLineInfoKind::RelativeFilePath) &&
1523 "invalid FileLineInfo Kind");
1524
1525 // sys::path::append skips empty strings.
1526 sys::path::append(FilePath, Style, IncludeDir, FileName);
1527 Result = std::string(FilePath);
1528 return true;
1529}
1530
1532 object::SectionedAddress Address, bool Approximate, const char *CompDir,
1533 FileLineInfoKind Kind, DILineInfo &Result) const {
1534 // Get the index of row we're looking for in the line table.
1535 uint32_t RowIndex =
1536 lookupAddress(Address, Approximate ? &Result.IsApproximateLine : nullptr);
1537 if (RowIndex == -1U)
1538 return false;
1539 // Take file number and line/column from the row.
1540 const auto &Row = Rows[RowIndex];
1541 if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
1542 return false;
1543 Result.Line = Row.Line;
1544 Result.Column = Row.Column;
1545 Result.Discriminator = Row.Discriminator;
1546 Result.Source = getSourceByIndex(Row.File, Kind);
1547 return true;
1548}
1549
1551 const FileNameEntry &Entry, std::string &Directory) const {
1552 if (Prologue.getVersion() >= 5) {
1553 if (Entry.DirIdx < Prologue.IncludeDirectories.size()) {
1554 Directory =
1555 dwarf::toString(Prologue.IncludeDirectories[Entry.DirIdx], "");
1556 return true;
1557 }
1558 return false;
1559 }
1560 if (0 < Entry.DirIdx && Entry.DirIdx <= Prologue.IncludeDirectories.size()) {
1561 Directory =
1562 dwarf::toString(Prologue.IncludeDirectories[Entry.DirIdx - 1], "");
1563 return true;
1564 }
1565 return false;
1566}
1567
1568// We want to supply the Unit associated with a .debug_line[.dwo] table when
1569// we dump it, if possible, but still dump the table even if there isn't a Unit.
1570// Therefore, collect up handles on all the Units that point into the
1571// line-table section.
1575 for (const auto &U : Units)
1576 if (auto CUDIE = U->getUnitDIE())
1577 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
1578 LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
1579 return LineToUnit;
1580}
1581
1585 : DebugLineData(Data), Context(C) {
1586 LineToUnit = buildLineToUnitMap(Units);
1587 if (!DebugLineData.isValidOffset(Offset))
1588 Done = true;
1589}
1590
1592 return TotalLength != 0u;
1593}
1594
1596 function_ref<void(Error)> RecoverableErrorHandler,
1597 function_ref<void(Error)> UnrecoverableErrorHandler, raw_ostream *OS,
1598 bool Verbose) {
1599 assert(DebugLineData.isValidOffset(Offset) &&
1600 "parsing should have terminated");
1601 DWARFUnit *U = prepareToParse(Offset);
1602 uint64_t OldOffset = Offset;
1603 LineTable LT;
1604 if (Error Err = LT.parse(DebugLineData, &Offset, Context, U,
1605 RecoverableErrorHandler, OS, Verbose))
1606 UnrecoverableErrorHandler(std::move(Err));
1607 moveToNextTable(OldOffset, LT.Prologue);
1608 return LT;
1609}
1610
1612 function_ref<void(Error)> RecoverableErrorHandler,
1613 function_ref<void(Error)> UnrecoverableErrorHandler) {
1614 assert(DebugLineData.isValidOffset(Offset) &&
1615 "parsing should have terminated");
1616 DWARFUnit *U = prepareToParse(Offset);
1617 uint64_t OldOffset = Offset;
1618 LineTable LT;
1619 if (Error Err = LT.Prologue.parse(DebugLineData, &Offset,
1620 RecoverableErrorHandler, Context, U))
1621 UnrecoverableErrorHandler(std::move(Err));
1622 moveToNextTable(OldOffset, LT.Prologue);
1623}
1624
1625DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) {
1626 DWARFUnit *U = nullptr;
1627 auto It = LineToUnit.find(Offset);
1628 if (It != LineToUnit.end())
1629 U = It->second;
1630 DebugLineData.setAddressSize(U ? U->getAddressByteSize() : 0);
1631 return U;
1632}
1633
1634bool DWARFDebugLine::SectionParser::hasValidVersion(uint64_t Offset) {
1636 auto [TotalLength, _] = DebugLineData.getInitialLength(Cursor);
1637 DWARFDataExtractor HeaderData(DebugLineData, Cursor.tell() + TotalLength);
1638 uint16_t Version = HeaderData.getU16(Cursor);
1639 if (!Cursor) {
1640 // Ignore any error here.
1641 // If this is not the end of the section parseNext() will still be
1642 // attempted, where this error will occur again (and can be handled).
1643 consumeError(Cursor.takeError());
1644 return false;
1645 }
1646 return versionIsSupported(Version);
1647}
1648
1649void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
1650 const Prologue &P) {
1651 // If the length field is not valid, we don't know where the next table is, so
1652 // cannot continue to parse. Mark the parser as done, and leave the Offset
1653 // value as it currently is. This will be the end of the bad length field.
1654 if (!P.totalLengthIsValid()) {
1655 Done = true;
1656 return;
1657 }
1658
1659 Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
1660 if (!DebugLineData.isValidOffset(Offset)) {
1661 Done = true;
1662 return;
1663 }
1664
1665 // Heuristic: If the version is valid, then this is probably a line table.
1666 // Otherwise, the offset might need alignment (to a 4 or 8 byte boundary).
1667 if (hasValidVersion(Offset))
1668 return;
1669
1670 // ARM C/C++ Compiler aligns each line table to word boundaries and pads out
1671 // the .debug_line section to a word multiple. Note that in the specification
1672 // this does not seem forbidden since each unit has a DW_AT_stmt_list.
1673 for (unsigned Align : {4, 8}) {
1674 uint64_t AlignedOffset = alignTo(Offset, Align);
1675 if (!DebugLineData.isValidOffset(AlignedOffset)) {
1676 // This is almost certainly not another line table but some alignment
1677 // padding. This assumes the alignments tested are ordered, and are
1678 // smaller than the header size (which is true for 4 and 8).
1679 Done = true;
1680 return;
1681 }
1682 if (hasValidVersion(AlignedOffset)) {
1683 Offset = AlignedOffset;
1684 break;
1685 }
1686 }
1687}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const dwarf::FormParams &FormParams, const DWARFContext &Ctx, const DWARFUnit *U, DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector< DWARFFormValue > &IncludeDirectories, std::vector< DWARFDebugLine::FileNameEntry > &FileNames)
static Error parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector< DWARFFormValue > &IncludeDirectories, std::vector< DWARFDebugLine::FileNameEntry > &FileNames)
static llvm::Expected< ContentDescriptors > parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, DWARFDebugLine::ContentTypeTracker *ContentTypes)
static DWARFDebugLine::SectionParser::LineToUnitMap buildLineToUnitMap(DWARFUnitVector::iterator_range Units)
static bool versionIsSupported(uint16_t Version)
static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase)
static std::optional< T > parseULEB128(DWARFDataExtractor &Data, DataExtractor::Cursor &Cursor)
Parse a ULEB128 using the specified Cursor.
This file contains constants used for implementing Dwarf debug support.
static fatal_error_handler_t ErrorHandler
#define _
#define I(x, y, z)
Definition MD5.cpp:57
#define T
#define P(N)
SI Fold Operands
This file defines the SmallString class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
unsigned getAddressSize() const
Get the address size for this extractor.
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 getRelocatedAddress(uint64_t *Off, uint64_t *SecIx=nullptr) const
Extracts an address-sized value.
void setAddressSize(unsigned Size)
Set the address size for this extractor.
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and returns it as adjusted by the Relocator.
A DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
LLVM_ABI void skip(function_ref< void(Error)> RecoverableErrorHandler, function_ref< void(Error)> UnrecoverableErrorHandler)
Skip the current line table and go to the following line table (if present) immediately.
std::map< uint64_t, DWARFUnit * > LineToUnitMap
LLVM_ABI LineTable parseNext(function_ref< void(Error)> RecoverableErrorHandler, function_ref< void(Error)> UnrecoverableErrorHandler, raw_ostream *OS=nullptr, bool Verbose=false)
Get the next line table from the section.
LLVM_ABI SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, DWARFUnitVector::iterator_range Units)
LLVM_ABI void clearLineTable(uint64_t Offset)
LLVM_ABI Expected< const LineTable * > getOrParseLineTable(DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx, const DWARFUnit *U, function_ref< void(Error)> RecoverableErrorHandler)
LLVM_ABI const LineTable * getLineTable(uint64_t Offset) const
static LLVM_ABI DWARFFormValue createFromPValue(dwarf::Form F, const char *V)
LLVM_ABI void dumpAddress(raw_ostream &OS, uint64_t Address) const
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOpts=DIDumpOptions()) const
LLVM_ABI Expected< const char * > getAsCString() const
llvm::iterator_range< UnitVector::iterator > iterator_range
Definition DWARFUnit.h:139
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
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.
LLVM_ABI StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
LLVM_ABI uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
LLVM_ABI uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
LLVM_ABI int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a signed LEB128 value from *offset_ptr.
LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
LLVM_ABI void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
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.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
A helper class to return the specified delimiter string after the first invocation of operator String...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
LLVM_ABI StringRef LNExtendedString(unsigned Encoding)
Definition Dwarf.cpp:711
LLVM_ABI StringRef FormatString(DwarfFormat Format)
Definition Dwarf.cpp:1062
LLVM_ABI StringRef LNStandardString(unsigned Standard)
Definition Dwarf.cpp:700
#define UINT64_MAX
Definition DataTypes.h:77
@ Entry
Definition COFF.h:862
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
Definition Utils.h:116
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
LineNumberEntryFormat
Definition Dwarf.h:891
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.
Definition Dwarf.h:878
@ DWARF32
Definition Dwarf.h:93
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.
Definition Dwarf.h:1186
uint64_t computeTombstoneAddress(uint8_t AddressByteSize)
Definition Dwarf.h:1331
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition Path.cpp:688
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2116
@ Done
Definition Threading.h:60
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
auto uninitialized_copy(R &&Src, IterTy Dst)
Definition STLExtras.h:2111
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2065
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
@ illegal_byte_sequence
Definition Errc.h:52
@ not_supported
Definition Errc.h:69
@ invalid_argument
Definition Errc.h:56
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition Error.h:442
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
Container for dump options that control which debug information will be dumped.
Definition DIContext.h:196
A format-neutral container for source line information.
Definition DIContext.h:32
Tracks which optional content types are present in a DWARF file name entry format.
bool HasLength
Whether filename entries provide a file size.
bool HasSource
For v5, whether filename entries provide source text.
bool HasModTime
Whether filename entries provide a modification timestamp.
bool HasMD5
For v5, whether filename entries provide an MD5 checksum.
LLVM_ABI void trackContentType(dwarf::LineNumberEntryFormat ContentType)
Update tracked content types with ContentType.
LLVM_ABI uint32_t lookupAddress(object::SectionedAddress Address, bool *IsApproximateLine=nullptr) const
Returns the index of the row with file/line info for a given address, or UnknownRowIndex if there is ...
LLVM_ABI bool getDirectoryForEntry(const FileNameEntry &Entry, std::string &Directory) const
Extracts directory name by its Entry in include directories table in prologue.
const uint32_t UnknownRowIndex
Represents an invalid row.
LLVM_ABI bool getFileLineInfoForAddress(object::SectionedAddress Address, bool Approximate, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
LLVM_ABI Error parse(DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const DWARFContext &Ctx, const DWARFUnit *U, function_ref< void(Error)> RecoverableErrorHandler, raw_ostream *OS=nullptr, bool Verbose=false)
Parse prologue and all rows.
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
void appendSequence(const DWARFDebugLine::Sequence &S)
LLVM_ABI bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result, std::optional< uint64_t > StmtSequenceOffset=std::nullopt) const
Fills the Result argument with the indices of the rows that correspond to the address range specified...
void appendRow(const DWARFDebugLine::Row &R)
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
uint8_t MaxOpsPerInst
The maximum number of individual operations that may be encoded in an instruction.
uint8_t MinInstLength
The size in bytes of the smallest target machine instruction.
LLVM_ABI bool hasFileAtIndex(uint64_t FileIndex) const
uint64_t PrologueLength
The number of bytes following the prologue_length field to the beginning of the first byte of the sta...
LLVM_ABI void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
uint8_t SegSelectorSize
In v5, size in bytes of a segment selector.
int8_t LineBase
This parameter affects the meaning of the special opcodes. See below.
LLVM_ABI std::optional< uint64_t > getLastValidFileIndex() const
uint32_t sizeofPrologueLength() const
LLVM_ABI Error parse(DWARFDataExtractor Data, uint64_t *OffsetPtr, function_ref< void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx, const DWARFUnit *U=nullptr)
uint8_t LineRange
This parameter affects the meaning of the special opcodes. See below.
std::vector< DWARFFormValue > IncludeDirectories
uint8_t OpcodeBase
The number assigned to the first special opcode.
std::vector< uint8_t > StandardOpcodeLengths
LLVM_ABI bool totalLengthIsValid() const
LLVM_ABI const llvm::DWARFDebugLine::FileNameEntry & getFileNameEntry(uint64_t Index) const
Get DWARF-version aware access to the file name entry at the provided index.
LLVM_ABI bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result, sys::path::Style Style=sys::path::Style::native) const
uint8_t DefaultIsStmt
The initial value of theis_stmtregister.
uint64_t TotalLength
The size in bytes of the statement information for this compilation unit (not including the total_len...
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
LLVM_ABI uint64_t getLength() const
Length of the prologue in bytes.
ContentTypeTracker ContentTypes
This tracks which optional file format content types are present.
std::vector< FileNameEntry > FileNames
Standard .debug_line state machine structure.
uint8_t BasicBlock
A boolean indicating that the current instruction is the beginning of a basic block.
static bool orderByAddress(const Row &LHS, const Row &RHS)
uint32_t Line
An unsigned integer indicating a source line number.
uint16_t File
An unsigned integer indicating the identity of the source file corresponding to a machine instruction...
uint32_t Discriminator
An unsigned integer representing the DWARF path discriminator value for this location.
uint8_t EpilogueBegin
A boolean indicating that the current address is one (of possibly many) where execution should be sus...
object::SectionedAddress Address
The program-counter value corresponding to a machine instruction generated by the compiler and sectio...
LLVM_ABI void postAppend()
Called after a row is appended to the matrix.
uint8_t PrologueEnd
A boolean indicating that the current address is one (of possibly many) where execution should be sus...
uint16_t Column
An unsigned integer indicating a column number within a source line.
uint8_t EndSequence
A boolean indicating that the current address is that of the first byte after the end of a sequence o...
static LLVM_ABI void dumpTableHeader(raw_ostream &OS, unsigned Indent)
uint8_t IsStmt
A boolean indicating that the current instruction is the beginning of a statement.
LLVM_ABI void reset(bool DefaultIsStmt)
LLVM_ABI Row(bool DefaultIsStmt=false)
uint8_t Isa
An unsigned integer whose value encodes the applicable instruction set architecture for the current i...
LLVM_ABI void dump(raw_ostream &OS) const
uint8_t OpIndex
An unsigned integer representing the index of an operation within a VLIW instruction.
Represents a series of contiguous machine instructions.
uint64_t LowPC
Sequence describes instructions at address range [LowPC, HighPC) and is described by line table rows ...
static bool orderByHighPC(const Sequence &LHS, const Sequence &RHS)
bool containsPC(object::SectionedAddress PC) const
uint64_t StmtSeqOffset
The offset into the line table where this sequence begins.
uint64_t SectionIndex
If relocation information is present then this is the index of the section which contains above addre...
LLVM_ABI SmallString< 32 > digest() const
Definition MD5.cpp:280
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition Dwarf.h:1199
static const uint64_t UndefSection
Definition ObjectFile.h:148