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