LLVM: lib/DebugInfo/DWARF/DWARFContext.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
54#include
55#include
56#include
57#include
58#include
59#include
60
61using namespace llvm;
62using namespace dwarf;
63using namespace object;
64
65#define DEBUG_TYPE "dwarf"
66
70
71
75 EntryMap Map;
76 const auto &DObj = C.getDWARFObj();
77 if (DObj.getCUIndexSection().empty())
78 return;
79
82 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
83 if (!(C.getParseCUTUIndexManually() ||
84 S.Data.size() >= std::numeric_limits<uint32_t>::max()))
85 return;
86
90 if (Error ExtractionErr = Header.extract(
91 C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
92 C.getWarningHandler()(
93 createError("Failed to parse CU header in DWP file: " +
94 toString(std::move(ExtractionErr))));
95 Map.clear();
96 break;
97 }
98
99 auto Iter = Map.insert({TruncOffset,
100 {Header.getOffset(), Header.getNextUnitOffset() -
101 Header.getOffset()}});
102 if (!Iter.second) {
104 createError("Collision occured between for truncated offset 0x" +
107 Map.clear();
108 return;
109 }
110
111 Offset = Header.getNextUnitOffset();
112 TruncOffset = Offset;
113 }
114 });
115
116 if (Map.empty())
117 return;
118
120 if (.isValid())
121 continue;
123 auto Iter = Map.find(CUOff.getOffset());
124 if (Iter == Map.end()) {
127 " in the Map"),
129 break;
130 }
131 CUOff.setOffset(Iter->second.getOffset());
132 if (CUOff.getOffset() != Iter->second.getOffset())
134 "match calculated length at offset 0x" +
137 }
138}
139
142
143 const auto &DObj = C.getDWARFObj();
144 DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
145 if (!(C.getParseCUTUIndexManually() ||
146 S.Data.size() >= std::numeric_limits<uint32_t>::max()))
147 return;
152 if (Error ExtractionErr = Header.extract(
153 C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
154 C.getWarningHandler()(
155 createError("Failed to parse CU header in DWP file: " +
156 toString(std::move(ExtractionErr))));
157 break;
158 }
159 bool CU = Header.getUnitType() == DW_UT_split_compile;
160 uint64_t Sig = CU ? *Header.getDWOId() : Header.getTypeHash();
161 Map[Sig] = Header.getOffset();
162 Offset = Header.getNextUnitOffset();
163 }
164 });
165 if (Map.empty())
166 return;
168 if (.isValid())
169 continue;
171 auto Iter = Map.find(E.getSignature());
172 if (Iter == Map.end()) {
174 createError("Could not find unit with signature 0x" +
177 break;
178 }
180 }
181}
182
184 if (Index.getVersion() < 5)
186 else
188}
189
190template
193 bool IsLittleEndian) {
194 if (Cache)
195 return *Cache;
197 DataExtractor StrData(StringSection, IsLittleEndian, 0);
198 Cache = std::make_unique(AccelSection, StrData);
199 if (Error E = Cache->extract())
201 return *Cache;
202}
203
204
205std::unique_ptr
207 auto Macro = std::make_unique();
210 ? D.compile_units()
211 : D.dwo_compile_units(),
213 ? D.getStringExtractor()
214 : D.getStringDWOExtractor(),
217 D.getRecoverableErrorHandler()(std::move(Err));
219 }
220 };
222 switch (SectionType) {
225 ParseAndDump(Data, false);
226 break;
227 }
230 ParseAndDump(Data, false);
231 break;
232 }
235 0);
236 ParseAndDump(Data, true);
237 break;
238 }
241 ParseAndDump(Data, true);
242 break;
243 }
244 }
246}
247
248namespace {
250
252 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
253 std::unique_ptr CUIndex;
254 std::unique_ptr GdbIndex;
255 std::unique_ptr TUIndex;
256 std::unique_ptr Abbrev;
257 std::unique_ptr Loc;
258 std::unique_ptr Aranges;
259 std::unique_ptr Line;
260 std::unique_ptr DebugFrame;
261 std::unique_ptr EHFrame;
262 std::unique_ptr Macro;
263 std::unique_ptr Macinfo;
264 std::unique_ptr Names;
265 std::unique_ptr AppleNames;
266 std::unique_ptr AppleTypes;
268 std::unique_ptr AppleObjC;
270 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
271 std::unique_ptr AbbrevDWO;
272 std::unique_ptr MacinfoDWO;
273 std::unique_ptr MacroDWO;
274 struct DWOFile {
276 std::unique_ptr Context;
277 };
279 std::weak_ptr DWP;
280 bool CheckedForDWP = false;
281 std::string DWPName;
282
283public:
284 ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP) :
286 DWPName(std::move(DWP)) {}
287
289 if (NormalUnits.empty()) {
293 });
297 });
298 }
299 return NormalUnits;
300 }
301
302 DWARFUnitVector &getDWOUnits(bool Lazy) override {
303 if (DWOUnits.empty()) {
304 const DWARFObject &DObj = D.getDWARFObj();
305
308 });
312 });
313 }
314 return DWOUnits;
315 }
316
317 const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
318 if (AbbrevDWO)
319 return AbbrevDWO.get();
320 const DWARFObject &DObj = D.getDWARFObj();
322 AbbrevDWO = std::make_unique(abbrData);
323 return AbbrevDWO.get();
324 }
325
326 const DWARFUnitIndex &getCUIndex() override {
327 if (CUIndex)
328 return *CUIndex;
329
330 DataExtractor Data(D.getDWARFObj().getCUIndexSection(),
331 D.isLittleEndian(), 0);
332 CUIndex = std::make_unique(DW_SECT_INFO);
333 if (CUIndex->parse(Data))
335 return *CUIndex;
336 }
337 const DWARFUnitIndex &getTUIndex() override {
338 if (TUIndex)
339 return *TUIndex;
340
341 DataExtractor Data(D.getDWARFObj().getTUIndexSection(),
342 D.isLittleEndian(), 0);
344 bool isParseSuccessful = TUIndex->parse(Data);
345
346
347 if (isParseSuccessful && TUIndex->getVersion() != 2)
349 return *TUIndex;
350 }
351
352 DWARFGdbIndex &getGdbIndex() override {
353 if (GdbIndex)
354 return *GdbIndex;
355
356 DataExtractor Data(D.getDWARFObj().getGdbIndexSection(), true , 0);
357 GdbIndex = std::make_unique();
358 GdbIndex->parse(Data);
359 return *GdbIndex;
360 }
361
362 const DWARFDebugAbbrev *getDebugAbbrev() override {
363 if (Abbrev)
364 return Abbrev.get();
365
366 DataExtractor Data(D.getDWARFObj().getAbbrevSection(),
367 D.isLittleEndian(), 0);
368 Abbrev = std::make_unique(Data);
369 return Abbrev.get();
370 }
371
372 const DWARFDebugLoc *getDebugLoc() override {
373 if (Loc)
374 return Loc.get();
375
376 const DWARFObject &DObj = D.getDWARFObj();
377
379 D.getNumCompileUnits()
380 ? DWARFDataExtractor(DObj, DObj.getLocSection(), D.isLittleEndian(),
381 D.getUnitAtIndex(0)->getAddressByteSize())
382 : DWARFDataExtractor("", D.isLittleEndian(), 0);
383 Loc = std::make_unique(std::move(Data));
384 return Loc.get();
385 }
386
387 const DWARFDebugAranges *getDebugAranges() override {
388 if (Aranges)
389 return Aranges.get();
390
391 Aranges = std::make_unique();
392 Aranges->generate(&D);
393 return Aranges.get();
394 }
395
396 Expected<const DWARFDebugLine::LineTable *>
397 getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
398 if (!Line)
399 Line = std::make_unique();
400
401 auto UnitDIE = U->getUnitDIE();
402 if (!UnitDIE)
403 return nullptr;
404
407 return nullptr;
408
409 uint64_t stmtOffset = *Offset + U->getLineTableOffset();
410
412 return lt;
413
414
415 if (stmtOffset >= U->getLineSection().Data.size())
416 return nullptr;
417
418
419 DWARFDataExtractor Data(U->getContext().getDWARFObj(), U->getLineSection(),
420 U->isLittleEndian(), U->getAddressByteSize());
421 return Line->getOrParseLineTable(Data, stmtOffset, U->getContext(), U,
422 RecoverableErrorHandler);
423
424 }
425
426 void clearLineTableForUnit(DWARFUnit *U) override {
427 if (!Line)
428 return;
429
430 auto UnitDIE = U->getUnitDIE();
431 if (!UnitDIE)
432 return;
433
436 return;
437
438 uint64_t stmtOffset = *Offset + U->getLineTableOffset();
439 Line->clearLineTable(stmtOffset);
440 }
441
442 Expected<const DWARFDebugFrame *> getDebugFrame() override {
445 const DWARFObject &DObj = D.getDWARFObj();
447
448
449
450
451
452
453
454
455
456
457 DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
459 auto DF =
460 std::make_unique(D.getArch(), false,
461 DS.Address);
463 return std::move(E);
464
467 }
468
469 Expected<const DWARFDebugFrame *> getEHFrame() override {
470 if (EHFrame)
471 return EHFrame.get();
472 const DWARFObject &DObj = D.getDWARFObj();
473
475 DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
477 auto DF =
478 std::make_unique(D.getArch(), true,
479 DS.Address);
481 return std::move(E);
482 EHFrame.swap(DF);
483 return EHFrame.get();
484 }
485
486 const DWARFDebugMacro *getDebugMacinfo() override {
487 if (!Macinfo)
488 Macinfo = parseMacroOrMacinfo(MacinfoSection);
489 return Macinfo.get();
490 }
491 const DWARFDebugMacro *getDebugMacinfoDWO() override {
492 if (!MacinfoDWO)
493 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
494 return MacinfoDWO.get();
495 }
496 const DWARFDebugMacro *getDebugMacro() override {
498 Macro = parseMacroOrMacinfo(MacroSection);
499 return Macro.get();
500 }
501 const DWARFDebugMacro *getDebugMacroDWO() override {
502 if (!MacroDWO)
503 MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
504 return MacroDWO.get();
505 }
506 const DWARFDebugNames &getDebugNames() override {
507 const DWARFObject &DObj = D.getDWARFObj();
510 }
511 const AppleAcceleratorTable &getAppleNames() override {
512 const DWARFObject &DObj = D.getDWARFObj();
515
516 }
517 const AppleAcceleratorTable &getAppleTypes() override {
518 const DWARFObject &DObj = D.getDWARFObj();
521
522 }
523 const AppleAcceleratorTable &getAppleNamespaces() override {
524 const DWARFObject &DObj = D.getDWARFObj();
528
529 }
530 const AppleAcceleratorTable &getAppleObjC() override {
531 const DWARFObject &DObj = D.getDWARFObj();
534 }
535
536 std::shared_ptr
537 getDWOContext(StringRef AbsolutePath) override {
538 if (auto S = DWP.lock()) {
539 DWARFContext *Ctxt = S->Context.get();
540 return std::shared_ptr(std::move(S), Ctxt);
541 }
542
543 std::weak_ptr *Entry = &DWOFiles[AbsolutePath];
544
545 if (auto S = Entry->lock()) {
546 DWARFContext *Ctxt = S->Context.get();
547 return std::shared_ptr(std::move(S), Ctxt);
548 }
549
550 const DWARFObject &DObj = D.getDWARFObj();
551
552 Expected<OwningBinary> Obj = [&] {
553 if (!CheckedForDWP) {
554 SmallString<128> DWPName;
556 this->DWPName.empty()
557 ? (DObj.getFileName() + ".dwp").toStringRef(DWPName)
558 : StringRef(this->DWPName));
559 if (Obj) {
561 return Obj;
562 } else {
563 CheckedForDWP = true;
564
565
567 }
568 }
569
571 }();
572
573 if (!Obj) {
574
576 return nullptr;
577 }
578
579 auto S = std::make_shared();
580 S->File = std::move(Obj.get());
581
582
583 bool ThreadSafe = isThreadSafe();
585 *S->File.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore,
589 auto *Ctxt = S->Context.get();
590 return std::shared_ptr(std::move(S), Ctxt);
591 }
592
593 bool isThreadSafe() const override { return false; }
594
595 const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {
596 if (!NormalTypeUnits) {
597 NormalTypeUnits.emplace();
598 for (const auto &U :D.normal_units()) {
600 (*NormalTypeUnits)[TU->getTypeHash()] = TU;
601 }
602 }
603 return *NormalTypeUnits;
604 }
605
606 const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {
607 if (!DWOTypeUnits) {
608 DWOTypeUnits.emplace();
609 for (const auto &U :D.dwo_units()) {
611 (*DWOTypeUnits)[TU->getTypeHash()] = TU;
612 }
613 }
614 return *DWOTypeUnits;
615 }
616
617 const DenseMap<uint64_t, DWARFTypeUnit *> &
618 getTypeUnitMap(bool IsDWO) override {
619 if (IsDWO)
620 return getDWOTypeUnitMap();
621 else
622 return getNormalTypeUnitMap();
623 }
624};
625
626class ThreadSafeState : public ThreadUnsafeDWARFContextState {
627 std::recursive_mutex Mutex;
628
629public:
630 ThreadSafeState(DWARFContext &DC, std::string &DWP) :
631 ThreadUnsafeDWARFContextState(DC, DWP) {}
632
633 DWARFUnitVector &getNormalUnits() override {
634 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
635 return ThreadUnsafeDWARFContextState::getNormalUnits();
636 }
637 DWARFUnitVector &getDWOUnits(bool Lazy) override {
638 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
639
640
641
642 return ThreadUnsafeDWARFContextState::getDWOUnits(false);
643 }
644 const DWARFUnitIndex &getCUIndex() override {
645 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
646 return ThreadUnsafeDWARFContextState::getCUIndex();
647 }
648 const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
649 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
650 return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();
651 }
652
653 const DWARFUnitIndex &getTUIndex() override {
654 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
655 return ThreadUnsafeDWARFContextState::getTUIndex();
656 }
657 DWARFGdbIndex &getGdbIndex() override {
658 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
659 return ThreadUnsafeDWARFContextState::getGdbIndex();
660 }
661 const DWARFDebugAbbrev *getDebugAbbrev() override {
662 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
663 return ThreadUnsafeDWARFContextState::getDebugAbbrev();
664 }
665 const DWARFDebugLoc *getDebugLoc() override {
666 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
667 return ThreadUnsafeDWARFContextState::getDebugLoc();
668 }
669 const DWARFDebugAranges *getDebugAranges() override {
670 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
671 return ThreadUnsafeDWARFContextState::getDebugAranges();
672 }
673 Expected<const DWARFDebugLine::LineTable *>
674 getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
675 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
676 return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);
677 }
678 void clearLineTableForUnit(DWARFUnit *U) override {
679 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
680 return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U);
681 }
682 Expected<const DWARFDebugFrame *> getDebugFrame() override {
683 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
684 return ThreadUnsafeDWARFContextState::getDebugFrame();
685 }
686 Expected<const DWARFDebugFrame *> getEHFrame() override {
687 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
688 return ThreadUnsafeDWARFContextState::getEHFrame();
689 }
690 const DWARFDebugMacro *getDebugMacinfo() override {
691 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
692 return ThreadUnsafeDWARFContextState::getDebugMacinfo();
693 }
694 const DWARFDebugMacro *getDebugMacinfoDWO() override {
695 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
696 return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();
697 }
698 const DWARFDebugMacro *getDebugMacro() override {
699 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
700 return ThreadUnsafeDWARFContextState::getDebugMacro();
701 }
702 const DWARFDebugMacro *getDebugMacroDWO() override {
703 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
704 return ThreadUnsafeDWARFContextState::getDebugMacroDWO();
705 }
706 const DWARFDebugNames &getDebugNames() override {
707 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
708 return ThreadUnsafeDWARFContextState::getDebugNames();
709 }
710 const AppleAcceleratorTable &getAppleNames() override {
711 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
712 return ThreadUnsafeDWARFContextState::getAppleNames();
713 }
714 const AppleAcceleratorTable &getAppleTypes() override {
715 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
716 return ThreadUnsafeDWARFContextState::getAppleTypes();
717 }
718 const AppleAcceleratorTable &getAppleNamespaces() override {
719 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
720 return ThreadUnsafeDWARFContextState::getAppleNamespaces();
721 }
722 const AppleAcceleratorTable &getAppleObjC() override {
723 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
724 return ThreadUnsafeDWARFContextState::getAppleObjC();
725 }
726 std::shared_ptr
727 getDWOContext(StringRef AbsolutePath) override {
728 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
729 return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);
730 }
731
732 bool isThreadSafe() const override { return true; }
733
734 const DenseMap<uint64_t, DWARFTypeUnit *> &
735 getTypeUnitMap(bool IsDWO) override {
736 std::unique_lockstd::recursive\_mutex LockGuard(Mutex);
737 return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
738 }
739};
740}
741
743 std::string DWPName,
744 std::function<void(Error)> RecoverableErrorHandler,
745 std::function<void(Error)> WarningHandler,
746 bool ThreadSafe)
748 RecoverableErrorHandler(RecoverableErrorHandler),
749 WarningHandler(WarningHandler), DObj(std::move(DObj)) {
750 if (ThreadSafe)
751 State = std::make_unique(*this, DWPName);
752 else
753 State = std::make_unique(*this, DWPName);
754 }
755
757
758
762 return;
763 for (auto LC : MachO->load_commands()) {
765 if (LC.C.cmd == MachO::LC_UUID) {
766 if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
767 OS << "error: UUID load command is too short.\n";
768 return;
769 }
770 OS << "UUID: ";
771 memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
774 OS << " (" << T.getArchName() << ')';
775 OS << ' ' << MachO->getFileName() << '\n';
776 }
777 }
778}
779
781 std::vector<std::optional>;
782
783
784
788 for (const auto &U : Units)
789 if (const auto &C = U->getStringOffsetsTableContribution())
790 Contributions.push_back(C);
791
792
793
795 [](const std::optional &L,
796 const std::optional &R) {
797 if (L && R)
798 return L->Base < R->Base;
799 return R.has_value();
800 });
801
802
803
804
805 Contributions.erase(
807 Contributions,
808 [](const std::optional &L,
809 const std::optional &R) {
810 if (L && R)
811 return L->Base == R->Base && L->Size == R->Size;
812 return false;
813 }),
814 Contributions.end());
815 return Contributions;
816}
817
818
819
820
821
822
823
824
825
832 bool LittleEndian) {
834 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
835 DataExtractor StrData(StringSection, LittleEndian, 0);
838 for (auto &Contribution : Contributions) {
839
840 if (!Contribution) {
841 OS << "error: invalid contribution to string offsets table in section ."
843 return;
844 }
845
848 uint16_t Version = Contribution->getVersion();
849 uint64_t ContributionHeader = Contribution->Base;
850
851
852
853
854 if (Version >= 5)
855 ContributionHeader -= Format == DWARF32 ? 8 : 16;
856
857
858 if (Offset > ContributionHeader) {
861 "overlapping contributions to string offsets table in section .%s.",
863 }
864
865 if (Offset < ContributionHeader) {
866 OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
867 OS << (ContributionHeader - Offset) << "\n";
868 }
869 OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
870
871
872
873
874 OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
876 << ", Version = " << Version << "\n";
877
878 Offset = Contribution->Base;
879 unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
880 while (Offset - Contribution->Base < Contribution->Size) {
884 OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);
885 const char *S = StrData.getCStr(&StringOffset);
886 if (S)
887 OS << format("\"%s\"", S);
888 OS << "\n";
889 }
890 }
891
892 if (Offset < SectionSize) {
893 OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
894 OS << (SectionSize - Offset) << "\n";
895 }
896}
897
898
906 if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
909
910
911 if (auto TableLength = AddrTable.getFullLength()) {
912 Offset = TableOffset + *TableLength;
913 continue;
914 }
915 break;
916 }
917 AddrTable.dump(OS, DumpOpts);
918 }
919}
920
921
925 LookupPooledAddress,
934
935
937 break;
939 } else {
940 Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
941 }
942 }
943}
944
945
948 std::optional<uint64_t> DumpOffset) {
950
955 return;
956 }
957
958 Header.dump(Data, OS, DumpOpts);
959
960 uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
961 Data.setAddressSize(Header.getAddrSize());
963 if (DumpOffset) {
964 if (DumpOffset >= Offset && DumpOffset < EndOffset) {
965 Offset = *DumpOffset;
966 Loc.dumpLocationList(&Offset, OS, std::nullopt, Obj,
967 nullptr, DumpOpts, 0);
968 OS << "\n";
969 return;
970 }
971 } else {
972 Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts);
973 }
975 }
976}
977
984
987 std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
989
991 bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
992
993
994 const auto *ObjFile = DObj->getFile();
997
998
999
1000
1001 bool Explicit = DumpType != DIDT_All && !IsDWO;
1002 bool ExplicitDWO = Explicit && IsDWO;
1003 auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
1004 StringRef Section) -> std::optional<uint64_t> * {
1005 unsigned Mask = 1U << ID;
1006 bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
1007 if (!Should)
1008 return nullptr;
1009 OS << "\n" << Name << " contents:\n";
1010 return &DumpOffsets[ID];
1011 };
1012
1013
1014 if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
1015 DObj->getAbbrevSection()))
1017 if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
1018 DObj->getAbbrevDWOSection()))
1020
1022 OS << '\n' << Name << " contents:\n";
1023 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
1024 for (const auto &U : Units) {
1025 U->getDIEForOffset(*DumpOffset)
1027 DWARFDie CUDie = U->getUnitDIE(false);
1028 DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);
1029 if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
1033 }
1034 }
1035 else
1036 for (const auto &U : Units)
1037 U->dump(OS, DumpOpts);
1038 };
1039 if ((DumpType & DIDT_DebugInfo)) {
1044 }
1045
1047 OS << '\n' << Name << " contents:\n";
1048 for (const auto &U : Units)
1049 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
1050 U->getDIEForOffset(*DumpOffset)
1052 else
1053 U->dump(OS, DumpOpts);
1054 };
1055 if ((DumpType & DIDT_DebugTypes)) {
1060 }
1061
1065
1066 if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
1067 DObj->getLocSection().Data)) {
1069 }
1070 if (const auto *Off =
1071 shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
1072 DObj->getLoclistsSection().Data)) {
1074 0);
1076 }
1077 if (const auto *Off =
1078 shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
1079 DObj->getLoclistsDWOSection().Data)) {
1083 }
1084
1085 if (const auto *Off =
1086 shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
1087 DObj->getLocDWOSection().Data)) {
1089 4);
1091 if (*Off) {
1093 Loc.dumpLocationList(&Offset, OS,
1094 std::nullopt, *DObj, nullptr,
1095 LLDumpOpts,
1096 0);
1097 OS << "\n";
1098 } else {
1099 Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts);
1100 }
1101 }
1102
1103 if (const std::optional<uint64_t> *Off =
1104 shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
1105 DObj->getFrameSection().Data)) {
1107 (*DF)->dump(OS, DumpOpts, *Off);
1108 else
1109 RecoverableErrorHandler(DF.takeError());
1110 }
1111
1112 if (const std::optional<uint64_t> *Off =
1113 shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
1114 DObj->getEHFrameSection().Data)) {
1116 (*DF)->dump(OS, DumpOpts, *Off);
1117 else
1118 RecoverableErrorHandler(DF.takeError());
1119 }
1120
1121 if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
1122 DObj->getMacroSection().Data)) {
1124 Macro->dump(OS);
1125 }
1126
1127 if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
1128 DObj->getMacroDWOSection())) {
1130 MacroDWO->dump(OS);
1131 }
1132
1133 if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
1134 DObj->getMacinfoSection())) {
1136 Macinfo->dump(OS);
1137 }
1138
1139 if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
1140 DObj->getMacinfoDWOSection())) {
1142 MacinfoDWO->dump(OS);
1143 }
1144
1145 if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
1146 DObj->getArangesSection())) {
1149 0);
1154 RecoverableErrorHandler(std::move(E));
1155 break;
1156 }
1157 set.dump(OS);
1158 }
1159 }
1160
1163 std::optional<uint64_t> DumpOffset) {
1164 while (.done()) {
1165 if (DumpOffset && Parser.getOffset() != *DumpOffset) {
1167 continue;
1168 }
1169 OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
1170 << "]\n";
1173 }
1174 };
1175
1176 auto DumpStrSection = [&](StringRef Section) {
1182 const char *CStr = StrData.getCStr(&Offset, &Err);
1183 if (Err) {
1185 return;
1186 }
1187 OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
1189 OS << "\"\n";
1191 }
1192 };
1193
1194 if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
1195 DObj->getLineSection().Data)) {
1197 0);
1199 DumpLineSection(Parser, DumpOpts, *Off);
1200 }
1201
1202 if (const auto *Off =
1203 shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
1204 DObj->getLineDWOSection().Data)) {
1208 DumpLineSection(Parser, DumpOpts, *Off);
1209 }
1210
1211 if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
1212 DObj->getCUIndexSection())) {
1214 }
1215
1216 if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
1217 DObj->getTUIndexSection())) {
1219 }
1220
1221 if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
1222 DObj->getStrSection()))
1223 DumpStrSection(DObj->getStrSection());
1224
1225 if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
1226 DObj->getStrDWOSection()))
1227 DumpStrSection(DObj->getStrDWOSection());
1228
1229 if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
1230 DObj->getLineStrSection()))
1231 DumpStrSection(DObj->getLineStrSection());
1232
1233 if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
1234 DObj->getAddrSection().Data)) {
1238 }
1239
1240 if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
1241 DObj->getRangesSection().Data)) {
1248 if (Error E = rangeList.extract(rangesData, &offset)) {
1250 break;
1251 }
1252 rangeList.dump(OS);
1253 }
1254 }
1255
1256 auto LookupPooledAddress =
1257 [&](uint32_t Index) -> std::optional {
1259 auto I = CUs.begin();
1260 if (I == CUs.end())
1261 return std::nullopt;
1262 return (*I)->getAddrOffsetSectionItem(Index);
1263 };
1264
1265 if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
1266 DObj->getRnglistsSection().Data)) {
1270 }
1271
1272 if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
1273 DObj->getRnglistsDWOSection().Data)) {
1274 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
1277 }
1278
1279 if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
1280 DObj->getPubnamesSection().Data)) {
1284 }
1285
1286 if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
1287 DObj->getPubtypesSection().Data)) {
1291 }
1292
1293 if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
1294 DObj->getGnuPubnamesSection().Data)) {
1295 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
1298 }
1299
1300 if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
1301 DObj->getGnuPubtypesSection().Data)) {
1302 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
1305 }
1306
1307 if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
1308 DObj->getStrOffsetsSection().Data))
1310 OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
1312 if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
1313 DObj->getStrOffsetsDWOSection().Data))
1315 DObj->getStrOffsetsDWOSection(),
1316 DObj->getStrDWOSection(), dwo_units(),
1318
1319 if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
1320 DObj->getGdbIndexSection())) {
1322 }
1323
1324 if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
1325 DObj->getAppleNamesSection().Data))
1327
1328 if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
1329 DObj->getAppleTypesSection().Data))
1331
1332 if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
1333 DObj->getAppleNamespacesSection().Data))
1335
1336 if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
1337 DObj->getAppleObjCSection().Data))
1339 if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
1340 DObj->getNamesSection().Data))
1342}
1343
1346 if (const auto &TUI = getTUIndex()) {
1347 if (const auto *R = TUI.getFromHash(Hash)) {
1348 if (TUI.getVersion() >= 5) {
1351 } else {
1354 if (!TypesUnit)
1355 TypesUnit =
1357 });
1359 }
1360 }
1361 return nullptr;
1362 }
1363 return State->getTypeUnitMap(IsDWO).lookup(Hash);
1364}
1365
1367 DWARFUnitVector &DWOUnits = State->getDWOUnits(LazyParse);
1368
1369 if (const auto &CUI = getCUIndex()) {
1370 if (const auto *R = CUI.getFromHash(Hash))
1373 return nullptr;
1374 }
1375
1376
1377
1378
1379
1381
1382 if (!DWOCU->getDWOId()) {
1383 if (std::optional<uint64_t> DWOId =
1384 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
1385 DWOCU->setDWOId(*DWOId);
1386 else
1387
1388 continue;
1389 }
1390 if (DWOCU->getDWOId() == Hash)
1392 }
1393 return nullptr;
1394}
1395
1397 if (auto *CU = State->getNormalUnits().getUnitForOffset(Offset))
1398 return CU->getDIEForOffset(Offset);
1400}
1401
1405
1407 if (DumpOpts.DumpType & DIDT_DebugCUIndex)
1409 if (DumpOpts.DumpType & DIDT_DebugTUIndex)
1411 if (DumpOpts.DumpType & DIDT_DebugInfo)
1413 if (DumpOpts.DumpType & DIDT_DebugLine)
1415 if (DumpOpts.DumpType & DIDT_DebugStrOffsets)
1420}
1421
1423 return State->getCUIndex();
1424}
1425
1427 return State->getTUIndex();
1428}
1429
1431 return State->getGdbIndex();
1432}
1433
1435 return State->getDebugAbbrev();
1436}
1437
1439 return State->getDebugAbbrevDWO();
1440}
1441
1443 return State->getDebugLoc();
1444}
1445
1447 return State->getDebugAranges();
1448}
1449
1451 return State->getDebugFrame();
1452}
1453
1455 return State->getEHFrame();
1456}
1457
1459 return State->getDebugMacro();
1460}
1461
1463 return State->getDebugMacroDWO();
1464}
1465
1467 return State->getDebugMacinfo();
1468}
1469
1471 return State->getDebugMacinfoDWO();
1472}
1473
1474
1476 return State->getDebugNames();
1477}
1478
1480 return State->getAppleNames();
1481}
1482
1484 return State->getAppleTypes();
1485}
1486
1488 return State->getAppleNamespaces();
1489}
1490
1492 return State->getAppleObjC();
1493}
1494
1499 if (!ExpectedLineTable) {
1500 WarningHandler(ExpectedLineTable.takeError());
1501 return nullptr;
1502 }
1503 return *ExpectedLineTable;
1504}
1505
1508 return State->getLineTableForUnit(U, RecoverableErrorHandler);
1509}
1510
1512 return State->clearLineTableForUnit(U);
1513}
1514
1516 return State->getDWOUnits(Lazy);
1517}
1518
1520 return State->getNormalUnits().getUnitForOffset(Offset);
1521}
1522
1526
1531
1535 return OffsetCU;
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547 for (std::unique_ptr &CU : compile_units()) {
1548 if (CU->getVariableForAddress(Address)) {
1550 }
1551 }
1552 return nullptr;
1553}
1554
1556 bool CheckDWO) {
1558
1560 if ()
1561 return Result;
1562
1563 if (CheckDWO) {
1564
1565
1566
1567 DWARFDie CUDie = CU->getUnitDIE(false);
1568 DWARFDie CUDwoDie = CU->getNonSkeletonUnitDIE(false);
1569 if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {
1570
1573 if (CUDwo) {
1575 if (Result.FunctionDIE)
1576 Result.CompileUnit = CUDwo;
1577 }
1578 }
1579 }
1580
1581
1582
1583 if (!Result) {
1584 Result.CompileUnit = CU;
1585 Result.FunctionDIE = CU->getSubroutineForAddress(Address);
1586 }
1587
1588 std::vector Worklist;
1589 Worklist.push_back(Result.FunctionDIE);
1590 while (!Worklist.empty()) {
1592 Worklist.pop_back();
1593
1594 if (.isValid())
1595 continue;
1596
1597 if (DIE.getTag() == DW_TAG_lexical_block &&
1598 DIE.addressRangeContainsAddress(Address)) {
1599 Result.BlockDIE = DIE;
1600 break;
1601 }
1602
1604 }
1605
1606 return Result;
1607}
1608
1609
1610
1614 std::string &FunctionName, std::string &StartFile, uint32_t &StartLine,
1615 std::optional<uint64_t> &StartAddress) {
1616
1617
1618
1620 CU->getInlinedChainForAddress(Address, InlinedChain);
1621 if (InlinedChain.empty())
1622 return false;
1623
1625 bool FoundResult = false;
1626 const char *Name = nullptr;
1627 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
1628 FunctionName = Name;
1629 FoundResult = true;
1630 }
1631 std::string DeclFile = DIE.getDeclFile(FileNameKind);
1632 if (!DeclFile.empty()) {
1633 StartFile = DeclFile;
1634 FoundResult = true;
1635 }
1636 if (auto DeclLineResult = DIE.getDeclLine()) {
1637 StartLine = DeclLineResult;
1638 FoundResult = true;
1639 }
1641 StartAddress = LowPcAddr->Address;
1642 return FoundResult;
1643}
1644
1645static std::optional<int64_t>
1647 std::optional FrameBaseReg) {
1648 if (!Expr.empty() &&
1649 (Expr[0] == DW_OP_fbreg ||
1650 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1653
1656
1657 if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1659
1660 }
1661 return std::nullopt;
1662}
1663
1665 DWARFDie Die, std::vector &Result) {
1666 if (Die.getTag() == DW_TAG_variable ||
1667 Die.getTag() == DW_TAG_formal_parameter) {
1671
1672 std::optional FrameBaseReg;
1673 if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
1674 if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
1675 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1676 (*Expr)[0] <= DW_OP_reg31) {
1677 FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1678 }
1679
1680 if (Expected<std::vector> Loc =
1682 for (const auto &Entry : *Loc) {
1683 if (std::optional<int64_t> FrameOffset =
1685 Local.FrameOffset = *FrameOffset;
1686 break;
1687 }
1688 }
1689 } else {
1690
1691
1693 }
1694
1695 if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
1696 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
1697
1698 if (auto Origin =
1700 Die = Origin;
1701 if (auto NameAttr = Die.find(DW_AT_name))
1702 if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
1706 if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
1708 LT->getFileNameByIndex(
1709 *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(),
1711 Local.DeclFile);
1712 }
1713 if (auto DeclLineAttr = Die.find(DW_AT_decl_line))
1714 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
1715
1717 return;
1718 }
1719
1720 if (Die.getTag() == DW_TAG_inlined_subroutine)
1721 if (auto Origin =
1723 Subprogram = Origin;
1724
1725 for (auto Child : Die)
1726 addLocalsForDie(CU, Subprogram, Child, Result);
1727}
1728
1729std::vector
1731 std::vector Result;
1733 if ()
1734 return Result;
1735
1736 DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);
1737 if (Subprogram.isValid())
1738 addLocalsForDie(CU, Subprogram, Subprogram, Result);
1739 return Result;
1740}
1741
1742std::optional
1746 if ()
1747 return std::nullopt;
1748
1751 CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,
1752 Result.StartFileName, Result.StartLine, Result.StartAddress);
1753 if (Spec.FLIKind != FileLineInfoKind::None) {
1755 LineTable->getFileLineInfoForAddress(
1757 CU->getCompilationDir(), Spec.FLIKind, Result);
1758 }
1759 }
1760
1761 return Result;
1762}
1763
1764std::optional
1768 if ()
1769 return Result;
1770
1771 if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
1772 Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
1774 }
1775
1776 return Result;
1777}
1778
1783 if ()
1784 return Lines;
1785
1787 std::string StartFileName;
1789 std::optional<uint64_t> StartAddress;
1791 Spec.FLIKind, FunctionName,
1792 StartFileName, StartLine, StartAddress);
1793
1794
1795
1796 if (Spec.FLIKind == FileLineInfoKind::None) {
1798 Result.FunctionName = FunctionName;
1799 Result.StartFileName = StartFileName;
1800 Result.StartLine = StartLine;
1801 Result.StartAddress = StartAddress;
1802 Lines.push_back(std::make_pair(Address.Address, Result));
1803 return Lines;
1804 }
1805
1807
1808
1809 std::vector<uint32_t> RowVector;
1810 if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1811 Size, RowVector)) {
1812 return Lines;
1813 }
1814
1815 for (uint32_t RowIndex : RowVector) {
1816
1820 Spec.FLIKind, Result.FileName);
1821 Result.FunctionName = FunctionName;
1822 Result.Line = Row.Line;
1823 Result.Column = Row.Column;
1824 Result.StartFileName = StartFileName;
1825 Result.StartLine = StartLine;
1826 Result.StartAddress = StartAddress;
1827 Lines.push_back(std::make_pair(Row.Address.Address, Result));
1828 }
1829
1830 return Lines;
1831}
1832
1837
1839 if ()
1840 return InliningInfo;
1841
1844 CU->getInlinedChainForAddress(Address.Address, InlinedChain);
1845 if (InlinedChain.size() == 0) {
1846
1847
1848 if (Spec.FLIKind != FileLineInfoKind::None) {
1851 if (LineTable &&
1853 {Address.Address, Address.SectionIndex}, Spec.ApproximateLine,
1854 CU->getCompilationDir(), Spec.FLIKind, Frame))
1855 InliningInfo.addFrame(Frame);
1856 }
1857 return InliningInfo;
1858 }
1859
1860 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1861 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1862 DWARFDie &FunctionDIE = InlinedChain[i];
1864
1867 if (auto DeclLineResult = FunctionDIE.getDeclLine())
1868 Frame.StartLine = DeclLineResult;
1872 if (Spec.FLIKind != FileLineInfoKind::None) {
1873 if (i == 0) {
1874
1875
1877
1878 if (LineTable)
1881 CU->getCompilationDir(), Spec.FLIKind, Frame);
1882 } else {
1883
1884
1885 if (LineTable)
1888 Frame.Line = CallLine;
1889 Frame.Column = CallColumn;
1891 }
1892
1893 if (i + 1 < n) {
1894 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1895 CallDiscriminator);
1896 }
1897 }
1898 InliningInfo.addFrame(Frame);
1899 }
1900 return InliningInfo;
1901}
1902
1903std::shared_ptr
1905 return State->getDWOContext(AbsolutePath);
1906}
1907
1912
1913
1914
1919
1920
1921
1925 std::map<SymbolRef, SymInfo> &Cache) {
1929
1930 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1931
1932
1933 if (Sym != Obj.symbol_end()) {
1934 bool New;
1935 std::tie(CacheIt, New) = Cache.try_emplace(*Sym);
1936 if (!New)
1937 return CacheIt->second;
1938
1940 if (!SymAddrOrErr)
1941 return createError("failed to compute symbol address: ",
1943
1944
1946 if (!SectOrErr)
1947 return createError("failed to get symbol section: ",
1948 SectOrErr.takeError());
1949
1950 RSec = *SectOrErr;
1951 Ret.Address = *SymAddrOrErr;
1953 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1955 }
1956
1957 if (RSec != Obj.section_end())
1959
1960
1961
1962
1963
1964
1965
1966
1967 if (L && RSec != Obj.section_end())
1968 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1970
1971 if (CacheIt != Cache.end())
1972 CacheIt->second = Ret;
1973
1974 return Ret;
1975}
1976
1980 if (!MachObj)
1981 return false;
1982
1983
1986}
1987
1988namespace {
1989struct DWARFSectionMap final : public DWARFSection {
1991};
1992
1993class DWARFObjInMemory final : public DWARFObject {
1994 bool IsLittleEndian;
1995 uint8_t AddressSize;
1996 StringRef FileName;
1997 const object::ObjectFile *Obj = nullptr;
1999
2000 using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
2001 std::map<object::SectionRef, unsigned>>;
2002
2003 InfoSectionMap InfoSections;
2004 InfoSectionMap TypesSections;
2005 InfoSectionMap InfoDWOSections;
2006 InfoSectionMap TypesDWOSections;
2007
2008 DWARFSectionMap LocSection;
2009 DWARFSectionMap LoclistsSection;
2010 DWARFSectionMap LoclistsDWOSection;
2011 DWARFSectionMap LineSection;
2012 DWARFSectionMap RangesSection;
2013 DWARFSectionMap RnglistsSection;
2014 DWARFSectionMap StrOffsetsSection;
2015 DWARFSectionMap LineDWOSection;
2016 DWARFSectionMap FrameSection;
2017 DWARFSectionMap EHFrameSection;
2018 DWARFSectionMap LocDWOSection;
2019 DWARFSectionMap StrOffsetsDWOSection;
2020 DWARFSectionMap RangesDWOSection;
2021 DWARFSectionMap RnglistsDWOSection;
2022 DWARFSectionMap AddrSection;
2023 DWARFSectionMap AppleNamesSection;
2024 DWARFSectionMap AppleTypesSection;
2025 DWARFSectionMap AppleNamespacesSection;
2026 DWARFSectionMap AppleObjCSection;
2027 DWARFSectionMap NamesSection;
2028 DWARFSectionMap PubnamesSection;
2029 DWARFSectionMap PubtypesSection;
2030 DWARFSectionMap GnuPubnamesSection;
2031 DWARFSectionMap GnuPubtypesSection;
2032 DWARFSectionMap MacroSection;
2033
2034 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
2035 return StringSwitch<DWARFSectionMap *>(Name)
2036 .Case("debug_loc", &LocSection)
2037 .Case("debug_loclists", &LoclistsSection)
2038 .Case("debug_loclists.dwo", &LoclistsDWOSection)
2039 .Case("debug_line", &LineSection)
2040 .Case("debug_frame", &FrameSection)
2041 .Case("eh_frame", &EHFrameSection)
2042 .Case("debug_str_offsets", &StrOffsetsSection)
2043 .Case("debug_ranges", &RangesSection)
2044 .Case("debug_rnglists", &RnglistsSection)
2045 .Case("debug_loc.dwo", &LocDWOSection)
2046 .Case("debug_line.dwo", &LineDWOSection)
2047 .Case("debug_names", &NamesSection)
2048 .Case("debug_rnglists.dwo", &RnglistsDWOSection)
2049 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
2050 .Case("debug_addr", &AddrSection)
2051 .Case("apple_names", &AppleNamesSection)
2052 .Case("debug_pubnames", &PubnamesSection)
2053 .Case("debug_pubtypes", &PubtypesSection)
2054 .Case("debug_gnu_pubnames", &GnuPubnamesSection)
2055 .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
2056 .Case("apple_types", &AppleTypesSection)
2057 .Case("apple_namespaces", &AppleNamespacesSection)
2058 .Case("apple_namespac", &AppleNamespacesSection)
2059 .Case("apple_objc", &AppleObjCSection)
2060 .Case("debug_macro", &MacroSection)
2061 .Default(nullptr);
2062 }
2063
2064 StringRef AbbrevSection;
2065 StringRef ArangesSection;
2066 StringRef StrSection;
2067 StringRef MacinfoSection;
2068 StringRef MacinfoDWOSection;
2069 StringRef MacroDWOSection;
2070 StringRef AbbrevDWOSection;
2071 StringRef StrDWOSection;
2072 StringRef CUIndexSection;
2073 StringRef GdbIndexSection;
2074 StringRef TUIndexSection;
2075 StringRef LineStrSection;
2076
2077
2078
2079 std::deque<SmallString<0>> UncompressedSections;
2080
2081 StringRef *mapSectionToMember(StringRef Name) {
2082 if (DWARFSection *Sec = mapNameToDWARFSection(Name))
2083 return &Sec->Data;
2084 return StringSwitch<StringRef *>(Name)
2085 .Case("debug_abbrev", &AbbrevSection)
2086 .Case("debug_aranges", &ArangesSection)
2087 .Case("debug_str", &StrSection)
2088 .Case("debug_macinfo", &MacinfoSection)
2089 .Case("debug_macinfo.dwo", &MacinfoDWOSection)
2090 .Case("debug_macro.dwo", &MacroDWOSection)
2091 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
2092 .Case("debug_str.dwo", &StrDWOSection)
2093 .Case("debug_cu_index", &CUIndexSection)
2094 .Case("debug_tu_index", &TUIndexSection)
2095 .Case("gdb_index", &GdbIndexSection)
2096 .Case("debug_line_str", &LineStrSection)
2097
2098 .Default(nullptr);
2099 }
2100
2101
2102
2103 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
2104 StringRef &Data) {
2107
2108 Expected Decompressor =
2110 if (!Decompressor)
2111 return Decompressor.takeError();
2112
2113 SmallString<0> Out;
2114 if (auto Err = Decompressor->resizeAndDecompress(Out))
2115 return Err;
2116
2117 UncompressedSections.push_back(std::move(Out));
2118 Data = UncompressedSections.back();
2119
2121 }
2122
2123public:
2124 DWARFObjInMemory(const StringMap<std::unique_ptr> &Sections,
2125 uint8_t AddrSize, bool IsLittleEndian)
2126 : IsLittleEndian(IsLittleEndian) {
2127 for (const auto &SecIt : Sections) {
2128 if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
2129 *SectionData = SecIt.second->getBuffer();
2130 else if (SecIt.first() == "debug_info")
2131
2132
2133 InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
2134 else if (SecIt.first() == "debug_info.dwo")
2135 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
2136 else if (SecIt.first() == "debug_types")
2137 TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
2138 else if (SecIt.first() == "debug_types.dwo")
2139 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
2140 }
2141 }
2142 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
2143 function_ref<void(Error)> HandleError,
2144 function_ref<void(Error)> HandleWarning,
2146 : IsLittleEndian(Obj.isLittleEndian()),
2147 AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
2149
2150 StringMap SectionAmountMap;
2151 for (const SectionRef &Section : Obj.sections()) {
2152 StringRef Name;
2153 if (auto NameOrErr = Section.getName())
2154 Name = *NameOrErr;
2155 else
2156 consumeError(NameOrErr.takeError());
2157
2158 ++SectionAmountMap[Name];
2159 SectionNames.push_back({ Name, true });
2160
2161
2163 continue;
2164
2165
2167 continue;
2168
2169 StringRef Data;
2170 Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
2171 if (!SecOrErr) {
2172 HandleError(createError("failed to get relocated section: ",
2173 SecOrErr.takeError()));
2174 continue;
2175 }
2176
2177
2178
2179
2181 Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
2182 if (!L || ->getLoadedSectionContents(*RelocatedSection, Data)) {
2183 Expected E = Section.getContents();
2184 if (E)
2185 Data = *E;
2186 else
2187
2188 consumeError(E.takeError());
2189 }
2190
2191 if (auto Err = maybeDecompress(Section, Name, Data)) {
2192 HandleError(createError("failed to decompress '" + Name + "', ",
2193 std::move(Err)));
2194 continue;
2195 }
2196
2197
2198
2199 Name = Name.substr(Name.find_first_not_of("._"));
2200 Name = Obj.mapDebugSectionName(Name);
2201
2202 if (StringRef *SectionData = mapSectionToMember(Name)) {
2203 *SectionData = Data;
2204 if (Name == "debug_ranges") {
2205
2206 RangesDWOSection.Data = Data;
2207 } else if (Name == "debug_frame" || Name == "eh_frame") {
2208 if (DWARFSection *S = mapNameToDWARFSection(Name))
2210 }
2211 } else if (InfoSectionMap *Sections =
2212 StringSwitch<InfoSectionMap *>(Name)
2213 .Case("debug_info", &InfoSections)
2214 .Case("debug_info.dwo", &InfoDWOSections)
2215 .Case("debug_types", &TypesSections)
2216 .Case("debug_types.dwo", &TypesDWOSections)
2218
2219
2220 DWARFSectionMap &S = (*Sections)[Section];
2221 S.Data = Data;
2222 }
2223
2224 if (RelocatedSection == Obj.section_end() ||
2225 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
2226 continue;
2227
2228 StringRef RelSecName;
2229 if (auto NameOrErr = RelocatedSection->getName())
2230 RelSecName = *NameOrErr;
2231 else
2233
2234
2235
2236
2237 StringRef RelSecData;
2238 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
2239 continue;
2240
2241
2242
2243
2244
2245
2247 continue;
2248
2249 if (.relocations().empty() && Name.ends_with(".dwo") &&
2250 RelSecName.starts_with(".debug")) {
2251 HandleWarning(createError("unexpected relocations for dwo section '" +
2252 RelSecName + "'"));
2253 }
2254
2255
2256
2257 RelSecName = RelSecName.substr(RelSecName.find_first_not_of("._"));
2258 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
2260 if (!Map) {
2261
2262
2263 if (RelSecName == "debug_info")
2264 Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
2265 .Relocs;
2266 else if (RelSecName == "debug_types")
2268 &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
2269 .Relocs;
2270 else
2271 continue;
2272 }
2273
2274 if (Section.relocations().empty())
2275 continue;
2276
2277
2278 std::map<SymbolRef, SymInfo> AddrCache;
2282 for (const RelocationRef &Reloc : Section.relocations()) {
2283
2284
2285 if (isRelocScattered(Obj, Reloc))
2286 continue;
2287
2288 Expected SymInfoOrErr =
2289 getSymbolInfo(Obj, Reloc, L, AddrCache);
2290 if (!SymInfoOrErr) {
2291 HandleError(SymInfoOrErr.takeError());
2292 continue;
2293 }
2294
2295
2296
2297
2298
2299 if (Supports && Supports(Reloc.getType())) {
2300 auto I = Map->try_emplace(
2301 Reloc.getOffset(),
2302 RelocAddrEntry{
2303 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
2304 std::optionalobject::RelocationRef(), 0, Resolver});
2305
2306
2307
2308 if (.second) {
2309 RelocAddrEntry &entry = I.first->getSecond();
2310 if (entry.Reloc2) {
2311 HandleError(createError(
2312 "At most two relocations per offset are supported"));
2313 }
2314 entry.Reloc2 = Reloc;
2315 entry.SymbolValue2 = SymInfoOrErr->Address;
2316 }
2317 } else {
2320
2321 HandleWarning(
2322 createError("failed to compute relocation: " + Type + ", ",
2324 }
2325 }
2326 }
2327
2329 if (SectionAmountMap[S.Name] > 1)
2330 S.IsNameUnique = false;
2331 }
2332
2334 uint64_t Pos) const override {
2335 auto &Sec = static_cast<const DWARFSectionMap &>(S);
2337 if (AI == Sec.Relocs.end())
2338 return std::nullopt;
2339 return AI->second;
2340 }
2341
2343
2346 }
2347
2348 bool isLittleEndian() const override { return IsLittleEndian; }
2349 StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
2350 const DWARFSection &getLineDWOSection() const override {
2351 return LineDWOSection;
2352 }
2353 const DWARFSection &getLocDWOSection() const override {
2354 return LocDWOSection;
2355 }
2356 StringRef getStrDWOSection() const override { return StrDWOSection; }
2357 const DWARFSection &getStrOffsetsDWOSection() const override {
2358 return StrOffsetsDWOSection;
2359 }
2360 const DWARFSection &getRangesDWOSection() const override {
2361 return RangesDWOSection;
2362 }
2363 const DWARFSection &getRnglistsDWOSection() const override {
2364 return RnglistsDWOSection;
2365 }
2366 const DWARFSection &getLoclistsDWOSection() const override {
2367 return LoclistsDWOSection;
2368 }
2369 const DWARFSection &getAddrSection() const override { return AddrSection; }
2370 StringRef getCUIndexSection() const override { return CUIndexSection; }
2371 StringRef getGdbIndexSection() const override { return GdbIndexSection; }
2372 StringRef getTUIndexSection() const override { return TUIndexSection; }
2373
2374
2375 const DWARFSection &getStrOffsetsSection() const override {
2376 return StrOffsetsSection;
2377 }
2378 StringRef getLineStrSection() const override { return LineStrSection; }
2379
2380
2381 void forEachInfoDWOSections(
2383 for (auto &P : InfoDWOSections)
2385 }
2386 void forEachTypesDWOSections(
2388 for (auto &P : TypesDWOSections)
2390 }
2391
2392 StringRef getAbbrevSection() const override { return AbbrevSection; }
2393 const DWARFSection &getLocSection() const override { return LocSection; }
2394 const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
2395 StringRef getArangesSection() const override { return ArangesSection; }
2396 const DWARFSection &getFrameSection() const override {
2397 return FrameSection;
2398 }
2400 return EHFrameSection;
2401 }
2402 const DWARFSection &getLineSection() const override { return LineSection; }
2403 StringRef getStrSection() const override { return StrSection; }
2404 const DWARFSection &getRangesSection() const override { return RangesSection; }
2405 const DWARFSection &getRnglistsSection() const override {
2406 return RnglistsSection;
2407 }
2408 const DWARFSection &getMacroSection() const override { return MacroSection; }
2409 StringRef getMacroDWOSection() const override { return MacroDWOSection; }
2410 StringRef getMacinfoSection() const override { return MacinfoSection; }
2411 StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
2412 const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
2413 const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
2414 const DWARFSection &getGnuPubnamesSection() const override {
2415 return GnuPubnamesSection;
2416 }
2417 const DWARFSection &getGnuPubtypesSection() const override {
2418 return GnuPubtypesSection;
2419 }
2420 const DWARFSection &getAppleNamesSection() const override {
2421 return AppleNamesSection;
2422 }
2423 const DWARFSection &getAppleTypesSection() const override {
2424 return AppleTypesSection;
2425 }
2426 const DWARFSection &getAppleNamespacesSection() const override {
2427 return AppleNamespacesSection;
2428 }
2429 const DWARFSection &getAppleObjCSection() const override {
2430 return AppleObjCSection;
2431 }
2432 const DWARFSection &getNamesSection() const override {
2433 return NamesSection;
2434 }
2435
2437 uint8_t getAddressSize() const override { return AddressSize; }
2438 void forEachInfoSections(
2440 for (auto &P : InfoSections)
2442 }
2443 void forEachTypesSections(
2445 for (auto &P : TypesSections)
2447 }
2448};
2449}
2450
2451std::unique_ptr
2455 std::function<void(Error)> RecoverableErrorHandler,
2456 std::function<void(Error)> WarningHandler,
2457 bool ThreadSafe) {
2458 auto DObj = std::make_unique(
2459 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
2460 return std::make_unique(std::move(DObj),
2461 std::move(DWPName),
2462 RecoverableErrorHandler,
2463 WarningHandler,
2464 ThreadSafe);
2465}
2466
2467std::unique_ptr
2470 std::function<void(Error)> RecoverableErrorHandler,
2471 std::function<void(Error)> WarningHandler,
2472 bool ThreadSafe) {
2473 auto DObj =
2474 std::make_unique(Sections, AddrSize, isLittleEndian);
2475 return std::make_unique(
2476 std::move(DObj), "", RecoverableErrorHandler, WarningHandler, ThreadSafe);
2477}
2478
2480
2481
2482
2483
2484
2486 return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
2487}
2488
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const DWARFObject &Obj, std::optional< uint64_t > DumpOffset)
Definition DWARFContext.cpp:946
static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)
Definition DWARFContext.cpp:922
static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj)
Dump the UUID load command.
Definition DWARFContext.cpp:759
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, DILineInfoSpecifier::FileLineInfoKind FileNameKind, std::string &FunctionName, std::string &StartFile, uint32_t &StartLine, std::optional< uint64_t > &StartAddress)
TODO: change input parameter from "uint64_t Address" into "SectionedAddress Address".
Definition DWARFContext.cpp:1611
static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, bool GnuStyle)
Definition DWARFContext.cpp:978
void fixupIndex(DWARFContext &C, DWARFUnitIndex &Index)
Definition DWARFContext.cpp:183
static Expected< SymInfo > getSymbolInfo(const object::ObjectFile &Obj, const RelocationRef &Reloc, const LoadedObjectInfo *L, std::map< SymbolRef, SymInfo > &Cache)
Returns the address of symbol relocation used against and a section index.
Definition DWARFContext.cpp:1922
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize)
Definition DWARFContext.cpp:899
static T & getAccelTable(std::unique_ptr< T > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)
Definition DWARFContext.cpp:191
void fixupIndexV4(DWARFContext &C, DWARFUnitIndex &Index)
Definition DWARFContext.cpp:72
static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)
Definition DWARFContext.cpp:786
std::vector< std::optional< StrOffsetsContributionDescriptor > > ContributionCollection
Definition DWARFContext.cpp:780
DWARFDebugLine::LineTable DWARFLineTable
Definition DWARFContext.cpp:67
static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)
Definition DWARFContext.cpp:1977
static std::optional< int64_t > getExpressionFrameOffset(ArrayRef< uint8_t > Expr, std::optional< unsigned > FrameBaseReg)
Definition DWARFContext.cpp:1646
void fixupIndexV5(DWARFContext &C, DWARFUnitIndex &Index)
Definition DWARFContext.cpp:140
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian)
Definition DWARFContext.cpp:826
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file contains constants used for implementing Dwarf debug support.
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
This file implements a map that provides insertion order iteration.
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
std::pair< llvm::MachO::Target, std::string > UUID
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
void dump(raw_ostream &OS) const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
DIContext(DIContextKind K)
A structured debug information entry.
dwarf::Tag getTag() const
A format-neutral container for inlined code description.
void addFrame(const DILineInfo &Frame)
DWARFContextState This structure contains all member variables for DWARFContext that need to be prote...
MacroSecType
Helper enum to distinguish between macro[.dwo] and macinfo[.dwo] section.
LLVM_ABI std::unique_ptr< DWARFDebugMacro > parseMacroOrMacinfo(MacroSecType SectionType)
Parse a macro[.dwo] or macinfo[.dwo] section.
Definition DWARFContext.cpp:206
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
DWARFCompileUnit * getCompileUnitForCodeAddress(uint64_t Address)
Return the compile unit which contains instruction with provided address.
Definition DWARFContext.cpp:1527
uint8_t getCUAddrSize()
Get address size from CUs.
Definition DWARFContext.cpp:2479
std::optional< DILineInfo > getLineInfoForDataAddress(object::SectionedAddress Address) override
Definition DWARFContext.cpp:1765
DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition DWARFContext.cpp:1834
Expected< const DWARFDebugFrame * > getDebugFrame()
Get a pointer to the parsed frame information object.
Definition DWARFContext.cpp:1450
DWARFGdbIndex & getGdbIndex()
Definition DWARFContext.cpp:1430
unsigned getNumCompileUnits()
Get the number of compile units in this context.
DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)
Definition DWARFContext.cpp:742
DWARFDie getDIEForOffset(uint64_t Offset)
Get a DIE given an exact offset.
Definition DWARFContext.cpp:1396
unsigned getNumTypeUnits()
Get the number of type units in this context.
DWARFUnitVector::iterator_range unit_iterator_range
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
Definition DWARFContext.cpp:1438
compile_unit_range compile_units()
Get compile units in this context.
const AppleAcceleratorTable & getAppleObjC()
Get a reference to the parsed accelerator table object.
Definition DWARFContext.cpp:1491
const DWARFUnitIndex & getTUIndex()
Definition DWARFContext.cpp:1426
DWARFCompileUnit * getCompileUnitForDataAddress(uint64_t Address)
Return the compile unit which contains data with the provided address.
Definition DWARFContext.cpp:1532
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
Definition DWARFContext.cpp:1434
std::vector< DILocal > getLocalsForAddress(object::SectionedAddress Address) override
Definition DWARFContext.cpp:1730
DWARFCompileUnit * getCompileUnitForOffset(uint64_t Offset)
Return the compile unit that includes an offset (relative to .debug_info).
Definition DWARFContext.cpp:1523
const DWARFDebugNames & getDebugNames()
Get a reference to the parsed accelerator table object.
Definition DWARFContext.cpp:1475
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
const DWARFDebugMacro * getDebugMacroDWO()
Get a pointer to the parsed DebugMacroDWO information object.
Definition DWARFContext.cpp:1462
DILineInfoTable getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition DWARFContext.cpp:1779
bool isDWP() const
Return true of this DWARF context is a DWP file.
Definition DWARFContext.cpp:2489
bool isLittleEndian() const
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
Definition DWARFContext.cpp:1496
void clearLineTableForUnit(DWARFUnit *U)
Definition DWARFContext.cpp:1511
const AppleAcceleratorTable & getAppleTypes()
Get a reference to the parsed accelerator table object.
Definition DWARFContext.cpp:1483
const AppleAcceleratorTable & getAppleNames()
Get a reference to the parsed accelerator table object.
Definition DWARFContext.cpp:1479
DWARFUnit * getUnitForOffset(uint64_t Offset)
Return the DWARF unit that includes an offset (relative to .debug_info).
Definition DWARFContext.cpp:1519
compile_unit_range dwo_compile_units()
Get compile units in the DWO context.
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
Definition DWARFContext.cpp:1442
const DWARFDebugMacro * getDebugMacinfoDWO()
Get a pointer to the parsed DebugMacinfoDWO information object.
Definition DWARFContext.cpp:1470
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
Definition DWARFContext.cpp:1402
unit_iterator_range dwo_types_section_units()
Get units from .debug_types.dwo in the DWO context.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::array< std::optional< uint64_t >, DIDT_ID_Count > DumpOffsets)
Dump a textual representation to OS.
Definition DWARFContext.cpp:985
DWARFTypeUnit * getTypeUnitForHash(uint64_t Hash, bool IsDWO)
Definition DWARFContext.cpp:1344
unit_iterator_range normal_units()
Get all normal compile/type units in this context.
unit_iterator_range types_section_units()
Get units from .debug_types in this context.
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
Definition DWARFContext.cpp:1904
DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)
Definition DWARFContext.cpp:1366
unsigned getNumDWOCompileUnits()
Get the number of compile units in the DWO context.
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
Definition DWARFContext.cpp:1446
const DWARFUnitIndex & getCUIndex()
Definition DWARFContext.cpp:1422
Expected< const DWARFDebugFrame * > getEHFrame()
Get a pointer to the parsed eh frame information object.
Definition DWARFContext.cpp:1454
DIEsForAddress getDIEsForAddress(uint64_t Address, bool CheckDWO=false)
Get the compilation unit, the function DIE and lexical block DIE for the given address where applicab...
Definition DWARFContext.cpp:1555
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
const AppleAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
Definition DWARFContext.cpp:1487
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro information object.
Definition DWARFContext.cpp:1458
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction=ProcessDebugRelocations::Process, const LoadedObjectInfo *L=nullptr, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)
Definition DWARFContext.cpp:2452
const DWARFDebugMacro * getDebugMacinfo()
Get a pointer to the parsed DebugMacinfo information object.
Definition DWARFContext.cpp:1466
unit_iterator_range dwo_units()
Get all units in the DWO context.
const DWARFObject & getDWARFObj() const
std::optional< DILineInfo > getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition DWARFContext.cpp:1743
LLVM_ABI void dump(raw_ostream &OS) const
A class representing an address table as specified in DWARF v5.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
Error extract(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, uint16_t CUVersion, uint8_t CUAddrSize, std::function< void(Error)> WarnCallback)
Extract the entire table, including all addresses.
std::optional< uint64_t > getFullLength() const
Return the full length of this table, including the length field.
LLVM_ABI void dump(raw_ostream &OS) const
LLVM_ABI Error extract(DWARFDataExtractor data, uint64_t *offset_ptr, function_ref< void(Error)> WarningHandler=nullptr)
uint64_t findAddress(uint64_t Address) const
Helper to allow for parsing of an entire .debug_line section in sequence.
void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, std::optional< uint64_t > Offset) const
Print the location lists found within the debug_loc section.
.debug_names section consists of one or more units.
void dump(raw_ostream &OS) const override
Represents structure for holding and parsing .debug_pub* tables.
LLVM_ABI void extract(DWARFDataExtractor Data, bool GnuStyle, function_ref< void(Error)> RecoverableErrorHandler)
LLVM_ABI void dump(raw_ostream &OS) const
LLVM_ABI Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)
LLVM_ABI void dump(raw_ostream &OS) const
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
LLVM_ABI DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
DWARFUnit * getDwarfUnit() const
LLVM_ABI const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name,...
LLVM_ABI void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) const
Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...
LLVM_ABI std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const
LLVM_ABI uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
dwarf::Tag getTag() const
LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
LLVM_ABI void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const
Dump the DIE and all of its attributes to the supplied stream.
void dump(raw_ostream &OS)
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr)
Extract an entire table, including all list entries.
void dump(DWARFDataExtractor Data, raw_ostream &OS, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
virtual StringRef getFileName() const
virtual StringRef getAbbrevDWOSection() const
virtual const DWARFSection & getFrameSection() const
virtual const DWARFSection & getNamesSection() const
virtual const DWARFSection & getAppleNamespacesSection() const
virtual void forEachInfoDWOSections(function_ref< void(const DWARFSection &)> F) const
virtual const DWARFSection & getAppleTypesSection() const
virtual void forEachInfoSections(function_ref< void(const DWARFSection &)> F) const
virtual const DWARFSection & getAppleNamesSection() const
virtual const DWARFSection & getEHFrameSection() const
virtual void forEachTypesSections(function_ref< void(const DWARFSection &)> F) const
virtual const DWARFSection & getLocSection() const
virtual const DWARFSection & getAppleObjCSection() const
virtual void forEachTypesDWOSections(function_ref< void(const DWARFSection &)> F) const
virtual StringRef getStrSection() const
virtual uint8_t getAddressSize() const
void setOffset(uint64_t Value)
uint64_t getOffset() const
LLVM_ABI void dump(raw_ostream &OS) const
Describe a collection of units.
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ....
LLVM_ABI DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E, DWARFSectionKind Sec, const DWARFSection *Section=nullptr)
Returns the Unit from the .debug_info or .debug_types section by the index entry.
LLVM_ABI void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
LLVM_ABI void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)
Read units from a .debug_info.dwo or .debug_types.dwo section.
DWARFContext & getContext() const
DWARFDie getDIEForOffset(uint64_t Offset)
Return the DIE object for a given offset Offset inside the unit's DIE vector.
const char * getCompilationDir()
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
A class that verifies DWARF debug information given a DWARF Context.
LLVM_ABI bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
LLVM_ABI bool handleDebugTUIndex()
Verify the information in the .debug_tu_index section.
LLVM_ABI bool handleDebugStrOffsets()
Verify the information in the .debug_str_offsets[.dwo].
LLVM_ABI bool handleDebugCUIndex()
Verify the information in the .debug_cu_index section.
LLVM_ABI bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
LLVM_ABI bool handleDebugLine()
Verify the information in the .debug_line section.
LLVM_ABI void summarize()
Emits any aggregate information collected, depending on the dump options.
LLVM_ABI bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev,...
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(uint64_t Val)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI void defaultWarningHandler(Error Warning)
Implement default handling for Warning.
static LLVM_ABI void defaultErrorHandler(Error Err)
Implement default handling for Error.
An efficient, type-erasing, non-owning reference to a callable.
static LLVM_ABI Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
This is a value type class that represents a single relocation in the list of relocations in the obje...
uint64_t getIndex() const
bool isCompressed() const
uint64_t getAddress() const
Expected< StringRef > getName() const
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_uuid(const uuid_t UUID)
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
LLVM_ABI StringRef FormatString(DwarfFormat Format)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
static constexpr StringLiteral SectionNames[SectionKindsNum]
Calculates the starting offsets for various sections within the .debug_names section.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
std::optional< object::SectionedAddress > toSectionedAddress(const std::optional< DWARFFormValue > &V)
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
LLVM_ABI Section * getEHFrameSection(LinkGraph &G)
Returns a pointer to the DWARF eh-frame section if the graph contains a non-empty one,...
content_iterator< SectionRef > section_iterator
Error createError(const Twine &Err)
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
LLVM_ABI std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
bool(*)(uint64_t) SupportsRelocation
LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
SmartMutex< false > Mutex
Mutex - A standard, always enforced mutex.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
SmallVector< std::pair< uint64_t, DILineInfo >, 16 > DILineInfoTable
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
auto unique(Range &&R, Predicate P)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto dyn_cast_or_null(const Y &Val)
void sort(IteratorTy Start, IteratorTy End)
static Error createError(const Twine &Err)
FunctionAddr VTableAddr Count
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
DenseMap< uint64_t, RelocAddrEntry > RelocAddrMap
In place of applying the relocations to the data we've read from disk we use a separate mapping table...
void consumeError(Error Err)
Consume a Error without doing anything.
Implement std::hash so that hash_code can be used in STL containers.
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
Definition DWARFContext.cpp:1915
uint64_t Address
Definition DWARFContext.cpp:1916
uint64_t SectionIndex
Definition DWARFContext.cpp:1917
Container for dump options that control which debug information will be dumped.
std::function< void(Error)> WarningHandler
std::function< void(Error)> RecoverableErrorHandler
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Controls which fields of DILineInfo container should be filled with data.
DINameKind FunctionNameKind
A format-neutral container for source line information.
static constexpr const char *const BadString
std::optional< uint64_t > StartAddress
std::string StartFileName
Wraps the returned DIEs for a given address.
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.
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
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...
Standard .debug_line state machine structure.