LLVM: lib/DebugInfo/DWARF/DWARFUnit.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
32#include
33#include
34#include
35#include
36#include
37#include
38
39using namespace llvm;
40using namespace dwarf;
41
46 addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
47 &D.getLocSection(), D.getStrSection(),
48 D.getStrOffsetsSection(), &D.getAddrSection(),
49 D.getLineSection(), D.isLittleEndian(), false, false,
51}
52
56 bool Lazy) {
58 addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
59 &D.getLocDWOSection(), D.getStrDWOSection(),
60 D.getStrOffsetsDWOSection(), &D.getAddrSection(),
61 D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
63}
64
65void DWARFUnitVector::addUnitsImpl(
72
73 if (!Parser) {
74 Parser = [=, &Context, &Obj, &Section, &SOS,
78 -> std::unique_ptr {
79 const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
82 return nullptr;
84 if (Error ExtractErr =
86 Context.getWarningHandler()(std::move(ExtractErr));
87 return nullptr;
88 }
89 if (!IndexEntry && IsDWO) {
93 if (Header.isTypeUnit())
94 IndexEntry = Index.getFromHash(Header.getTypeHash());
95 else if (auto DWOId = Header.getDWOId())
96 IndexEntry = Index.getFromHash(*DWOId);
97 }
98 if (!IndexEntry)
99 IndexEntry = Index.getFromOffset(Header.getOffset());
100 }
101 if (IndexEntry) {
102 if (Error ApplicationErr = Header.applyIndexEntry(IndexEntry)) {
103 Context.getWarningHandler()(std::move(ApplicationErr));
104 return nullptr;
105 }
106 }
107 std::unique_ptr U;
108 if (Header.isTypeUnit())
109 U = std::make_unique(Context, InfoSection, Header, DA,
110 RS, LocSection, SS, SOS, AOS, LS,
111 LE, IsDWO, *this);
112 else
113 U = std::make_unique(Context, InfoSection, Header,
114 DA, RS, LocSection, SS, SOS,
115 AOS, LS, LE, IsDWO, *this);
116 return U;
117 };
118 }
119 if (Lazy)
120 return;
121
122
123
124
125
130 (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
131 ++I;
132 continue;
133 }
134 auto U = Parser(Offset, SectionKind, &Section, nullptr);
135
136 if (!U)
137 break;
138 Offset = U->getNextUnitOffset();
139 I = std::next(this->insert(I, std::move(U)));
140 }
141}
142
145 [](const std::unique_ptr &LHS,
146 const std::unique_ptr &RHS) {
147 return LHS->getOffset() < RHS->getOffset();
148 });
149 return this->insert(I, std::move(Unit))->get();
150}
151
154 auto *CU =
156 [](uint64_t LHS, const std::unique_ptr &RHS) {
157 return LHS < RHS->getNextUnitOffset();
158 });
159 if (CU != end && (*CU)->getOffset() <= Offset)
160 return CU->get();
161 return nullptr;
162}
163
167 const auto *CUOff = E.getContribution(Sec);
168 if (!CUOff)
169 return nullptr;
170
174
178 }
179
180 auto *CU =
181 std::upper_bound(begin, end, CUOff->getOffset(),
182 [](uint64_t LHS, const std::unique_ptr &RHS) {
183 return LHS < RHS->getNextUnitOffset();
184 });
185 if (CU != end && (*CU)->getOffset() <= Offset)
186 return CU->get();
187
188 if (!Parser)
189 return nullptr;
190
191 auto U = Parser(Offset, Sec, Section, &E);
192 if (!U)
193 return nullptr;
194
195 auto *NewCU = U.get();
196 this->insert(CU, std::move(U));
197 if (Sec == DW_SECT_INFO)
198 ++NumInfoUnits;
199 return NewCU;
200}
201
208 : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
209 RangeSection(RS), LineSection(LS), StringSection(SS),
210 StringOffsetSection(SOS), AddrOffsetSection(AOS), IsLittleEndian(LE),
211 IsDWO(IsDWO), UnitVector(UnitVector) {
213}
214
216
221
222std::optionalobject::SectionedAddress
224 if (!AddrOffsetSectionBase) {
225 auto R = Context.info_section_units();
226
227
228
229
231 return (*R.begin())->getAddrOffsetSectionItem(Index);
232
233 return std::nullopt;
234 }
235
238 return std::nullopt;
243 return {{Address, Section}};
244}
245
247 if (!StringOffsetsTableContribution)
249 "DW_FORM_strx used without a valid string offsets table",
253 if (StringOffsetSection.Data.size() < Offset + ItemSize)
255 ", which is too large",
258 IsLittleEndian, 0);
259 return DA.getRelocatedValue(ItemSize, &Offset);
260}
261
266 Offset = *offset_ptr;
268 IndexEntry = nullptr;
269 std::tie(Length, FormParams.Format) =
271 FormParams.Version = debug_info.getU16(offset_ptr, &Err);
272 if (FormParams.Version >= 5) {
273 UnitType = debug_info.getU8(offset_ptr, &Err);
274 FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
276 FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
277 } else {
279 FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
280 FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
281
282
284 UnitType = DW_UT_type;
285 else
286 UnitType = DW_UT_compile;
287 }
289 TypeHash = debug_info.getU64(offset_ptr, &Err);
291 offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
292 } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
293 DWOId = debug_info.getU64(offset_ptr, &Err);
294
295 if (Err)
299 "DWARF unit at 0x%8.8" PRIx64 " cannot be parsed:", Offset),
300 std::move(Err));
301
302
303 assert(*offset_ptr - Offset <= 255 && "unexpected header size");
304 Size = uint8_t(*offset_ptr - Offset);
306
309 "DWARF unit from offset 0x%8.8" PRIx64 " incl. "
310 "to offset 0x%8.8" PRIx64 " excl. "
311 "extends past section size 0x%8.8zx",
312 Offset, NextCUOffset, debug_info.size());
313
317 "DWARF unit at offset 0x%8.8" PRIx64 " "
318 "has unsupported version %" PRIu16 ", supported are 2-%u",
320
321
322
323 if (isTypeUnit() && TypeOffset < Size)
325 "DWARF type unit at offset "
326 "0x%8.8" PRIx64 " "
327 "has its relocated type_offset 0x%8.8" PRIx64 " "
328 "pointing inside the header",
329 Offset, Offset + TypeOffset);
330
334 "DWARF type unit from offset 0x%8.8" PRIx64 " incl. "
335 "to offset 0x%8.8" PRIx64 " excl. has its "
336 "relocated type_offset 0x%8.8" PRIx64 " pointing past the unit end",
337 Offset, NextCUOffset, Offset + TypeOffset);
338
341 "DWARF unit at offset 0x%8.8" PRIx64, Offset))
342 return SizeErr;
343
344
345 Context.setMaxVersionIfGreater(getVersion());
347}
348
352 IndexEntry = Entry;
353 if (AbbrOffset)
355 "DWARF package unit at offset 0x%8.8" PRIx64
356 " has a non-zero abbreviation offset",
357 Offset);
358
359 auto *UnitContrib = IndexEntry->getContribution();
360 if (!UnitContrib)
362 "DWARF package unit at offset 0x%8.8" PRIx64
363 " has no contribution index",
364 Offset);
365
367 if (UnitContrib->getLength() != IndexLength)
369 "DWARF package unit at offset 0x%8.8" PRIx64
370 " has an inconsistent index (expected: %" PRIu64
371 ", actual: %" PRIu64 ")",
372 Offset, UnitContrib->getLength(), IndexLength);
373
374 auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
375 if (!AbbrEntry)
377 "DWARF package unit at offset 0x%8.8" PRIx64
378 " missing abbreviation column",
379 Offset);
380
381 AbbrOffset = AbbrEntry->getOffset();
383}
384
387
388 assert(!DieArray.empty());
391 uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
392 return RangeList.extract(RangesData, &ActualRangeListOffset);
393}
394
396 Abbrevs = nullptr;
397 BaseAddr.reset();
398 RangeSectionBase = 0;
399 LocSectionBase = 0;
400 AddrOffsetSectionBase = std::nullopt;
401 SU = nullptr;
402 clearDIEs(false);
403 AddrDieMap.clear();
404 if (DWO)
405 DWO->clear();
406 DWO.reset();
407}
408
412
413void DWARFUnit::extractDIEsToVector(
414 bool AppendCUDie, bool AppendNonCUDies,
415 std::vector &Dies) const {
416 if (!AppendCUDie && !AppendNonCUDies)
417 return;
418
419
420
425
427 std::vector<uint32_t> Parents;
428 std::vector<uint32_t> PrevSiblings;
429 bool IsCUDie = true;
430
432 ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&
433 "Dies array is not empty");
434
435
436 Parents.push_back(UINT32_MAX);
437 if (!AppendCUDie)
438 Parents.push_back(0);
439 PrevSiblings.push_back(0);
440
441
442 do {
443 assert(Parents.size() > 0 && "Empty parents stack");
444 assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&
445 "Wrong parent index");
446
447
448 if (.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
449 Parents.back()))
450 break;
451
452
453 if (PrevSiblings.back() > 0) {
454 assert(PrevSiblings.back() < Dies.size() &&
455 "Previous sibling index is out of Dies boundaries");
456 Dies[PrevSiblings.back()].setSiblingIdx(Dies.size());
457 }
458
459
460 if (IsCUDie) {
461 if (AppendCUDie)
462 Dies.push_back(DIE);
463 if (!AppendNonCUDies)
464 break;
465
466
467
469 } else {
470
471 PrevSiblings.back() = Dies.size();
472
473 Dies.push_back(DIE);
474 }
475
476
477 if (const DWARFAbbreviationDeclaration *AbbrDecl =
479 if (AbbrDecl->hasChildren()) {
480 if (AppendCUDie || !IsCUDie) {
481 assert(Dies.size() > 0 && "Dies does not contain any die");
482 Parents.push_back(Dies.size() - 1);
483 PrevSiblings.push_back(0);
484 }
485 } else if (IsCUDie)
486
487 break;
488 } else {
489
491 PrevSiblings.pop_back();
492 }
493
494 if (IsCUDie)
495 IsCUDie = false;
496
497
498 } while (Parents.size() > 1);
499}
500
501void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
503 Context.getRecoverableErrorHandler()(std::move(e));
504}
505
507 if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1)
509
510 bool HasCUDie = !DieArray.empty();
511 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
512
513 if (DieArray.empty())
515
516
517 if (HasCUDie)
519
520 DWARFDie UnitDie(this, &DieArray[0]);
521 if (std::optional<uint64_t> DWOId =
523 Header.setDWOId(*DWOId);
524 if (!IsDWO) {
525 assert(AddrOffsetSectionBase == std::nullopt);
526 assert(RangeSectionBase == 0);
527 assert(LocSectionBase == 0);
529 if (!AddrOffsetSectionBase)
530 AddrOffsetSectionBase =
532 RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
534 }
535
536
537
538
539
540
541
542
544 IsLittleEndian, 0);
546 auto StringOffsetOrError =
549 if (!StringOffsetOrError)
551 "invalid reference to or invalid content in "
552 ".debug_str_offsets[.dwo]: " +
553 toString(StringOffsetOrError.takeError()));
554
555 StringOffsetsTableContribution = *StringOffsetOrError;
556 }
557
558
559
561
562 if (IsDWO) {
563 uint64_t ContributionBaseOffset = 0;
564 if (auto *IndexEntry = Header.getIndexEntry())
565 if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
566 ContributionBaseOffset = Contrib->getOffset();
568 &Context.getDWARFObj().getRnglistsDWOSection(),
569 ContributionBaseOffset +
571 } else
572 setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
575 Header.getFormat())));
576 }
577
578 if (IsDWO) {
579
580
582 ? Context.getDWARFObj().getLoclistsDWOSection().Data
583 : Context.getDWARFObj().getLocDWOSection().Data;
584 if (auto *IndexEntry = Header.getIndexEntry())
585 if (const auto *C = IndexEntry->getContribution(
586 Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
587 Data = Data.substr(C->getOffset(), C->getLength());
588
590 LocTable =
591 std::make_unique(DWARFData, Header.getVersion());
594 LocTable = std::make_unique(
596 Context.getDWARFObj().getLoclistsSection(),
599 } else {
601 Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
603 }
604
605
606
608}
609
610bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
611 if (IsDWO)
612 return false;
613 if (DWO)
614 return false;
616 if (!UnitDie)
617 return false;
621 if (!DWOFileName)
622 return false;
626 *CompilationDir) {
628 }
631 if (!DWOId)
632 return false;
633 auto DWOContext = Context.getDWOContext(AbsolutePath);
634 if (!DWOContext) {
635
636 if (DWOAlternativeLocation.empty())
637 return false;
638
639
640
641 DWOContext = Context.getDWOContext(DWOAlternativeLocation);
642 if (!DWOContext)
643 return false;
644 }
645
646 DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
647 if (!DWOCU)
648 return false;
649 DWO = std::shared_ptr(std::move(DWOContext), DWOCU);
650 DWO->setSkeletonUnit(this);
651
652 if (AddrOffsetSectionBase)
653 DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
656 DWO->setRangesSection(RangeSection, DWORangesBase.value_or(0));
657 }
658
659 return true;
660}
661
662void DWARFUnit::clearDIEs(bool KeepCUDie) {
663
664
665
666
667
668 DieArray = (KeepCUDie && !DieArray.empty())
669 ? std::vector({DieArray[0]})
670 : std::vector();
671}
672
678 return std::move(E);
680 }
682 IsLittleEndian, Header.getAddressByteSize());
684 auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
685 if (RangeListOrError)
686 return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
687 return RangeListOrError.takeError();
688}
689
694
696 "invalid range list table index %d (possibly "
697 "missing the entire range list table)",
699}
700
703 if (!UnitDie)
705
706
708 if (!CUDIERangesOrError)
710 "decoding address ranges: %s",
711 toString(CUDIERangesOrError.takeError()).c_str());
712 return *CUDIERangesOrError;
713}
714
718
720
725 if (L)
726 Result.push_back(std::move(*L));
727 else
728 InterpretationError =
729 joinErrors(L.takeError(), std::move(InterpretationError));
730 return !InterpretationError;
731 });
732
733 if (ParseError || InterpretationError)
734 return joinErrors(std::move(ParseError), std::move(InterpretationError));
735
736 return Result;
737}
738
742 if (DIERangesOrError) {
743 for (const auto &R : DIERangesOrError.get()) {
744
745 if (R.LowPC == R.HighPC)
746 continue;
747 auto B = AddrDieMap.upper_bound(R.LowPC);
748 if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
749
750
751 if (R.HighPC < B->second.first)
752 AddrDieMap[R.HighPC] = B->second;
753 if (R.LowPC > B->first)
754 AddrDieMap[B->first].first = R.LowPC;
755 }
756 AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
757 }
758 } else
760 }
761
762
763
764
765
768}
769
771 extractDIEsIfNeeded(false);
772 if (AddrDieMap.empty())
774 auto R = AddrDieMap.upper_bound(Address);
775 if (R == AddrDieMap.begin())
777
778 --R;
779 if (Address >= R->second.first)
781 return R->second.second;
782}
783
786 if (isType(Child.getTag()))
787 continue;
789 }
790
791 if (Die.getTag() != DW_TAG_variable)
792 return;
793
796 if (!Locations) {
797
799 return;
800 }
801
803
808 auto It = Expr.begin();
809 if (It == Expr.end())
810 continue;
811
812
813
814
815
816
817
819 if (It->getCode() == dwarf::DW_OP_addr) {
820 LocationAddr = It->getRawOperand(0);
821 } else if (It->getCode() == dwarf::DW_OP_addrx) {
822 uint64_t DebugAddrOffset = It->getRawOperand(0);
824 LocationAddr = Pointer->Address;
825 }
826 } else {
827 continue;
828 }
829
830
831 if (++It != Expr.end()) {
832 if (It->getCode() != dwarf::DW_OP_plus_uconst)
833 continue;
834
835 LocationAddr += It->getRawOperand(0);
836
837
838 if (++It != Expr.end())
839 continue;
840 }
841
843 break;
844 }
845
846
847
848
852 GVSize = *Size;
853
856}
857
859 extractDIEsIfNeeded(false);
860
862
863 auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
864 if (RootLookup.second)
866
867 auto R = VariableDieMap.upper_bound(Address);
868 if (R == VariableDieMap.begin())
870
871
872 --R;
873 if (Address >= R->second.first)
875 return R->second.second;
876}
877
878void
882
883 parseDWO();
884
885
888
889 while (SubroutineDIE) {
891 InlinedChain.push_back(SubroutineDIE);
892 return;
893 }
894 if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
895 InlinedChain.push_back(SubroutineDIE);
896 SubroutineDIE = SubroutineDIE.getParent();
897 }
898}
899
902 if (Kind == DW_SECT_INFO)
903 return Context.getCUIndex();
905 return Context.getTUIndex();
906}
907
910 return DWARFDie(this, Entry);
911
913}
914
917 if (!Die)
918 return nullptr;
919 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
920
921 if (std::optional<uint32_t> ParentIdx = Die->getParentIdx()) {
922 assert(*ParentIdx < DieArray.size() &&
923 "ParentIdx is out of DieArray boundaries");
925 }
926
927 return nullptr;
928}
929
932 return DWARFDie(this, Sibling);
933
935}
936
939 if (!Die)
940 return nullptr;
941 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
942
943 if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
944 assert(*SiblingIdx < DieArray.size() &&
945 "SiblingIdx is out of DieArray boundaries");
946 return &DieArray[*SiblingIdx];
947 }
948
949 return nullptr;
950}
951
954 return DWARFDie(this, Sibling);
955
957}
958
961 if (!Die)
962 return nullptr;
963 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
964
965 std::optional<uint32_t> ParentIdx = Die->getParentIdx();
966 if (!ParentIdx)
967
968 return nullptr;
969
970 assert(*ParentIdx < DieArray.size() &&
971 "ParentIdx is out of DieArray boundaries");
973
975 if (PrevDieIdx == *ParentIdx)
976
977 return nullptr;
978
979 while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
980 PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
981
982 assert(PrevDieIdx < DieArray.size() &&
983 "PrevDieIdx is out of DieArray boundaries");
984 assert(PrevDieIdx >= *ParentIdx &&
985 "PrevDieIdx is not a child of parent of Die");
986 }
987
988 return &DieArray[PrevDieIdx];
989}
990
993 return DWARFDie(this, Child);
994
996}
997
1000 if (!Die)
1001 return nullptr;
1002 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
1003
1005 return nullptr;
1006
1007
1008
1009
1011 if (I >= DieArray.size())
1012 return nullptr;
1013 return &DieArray[I];
1014}
1015
1018 return DWARFDie(this, Child);
1019
1021}
1022
1025 if (!Die)
1026 return nullptr;
1027 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
1028
1030 return nullptr;
1031
1032 if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
1033 assert(*SiblingIdx < DieArray.size() &&
1034 "SiblingIdx is out of DieArray boundaries");
1035 assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&
1036 "Bad end of children marker");
1037 return &DieArray[*SiblingIdx - 1];
1038 }
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
1050 DieArray.back().getTag() == dwarf::DW_TAG_null) {
1051
1054 "Bad unit die");
1055 return &DieArray.back();
1056 }
1057
1058 return nullptr;
1059}
1060
1062 if (!Abbrevs) {
1065 if (!AbbrevsOrError) {
1066
1068 return nullptr;
1069 }
1070 Abbrevs = *AbbrevsOrError;
1071 }
1072 return Abbrevs;
1073}
1074
1076 if (BaseAddr)
1077 return BaseAddr;
1078
1080 std::optional PC =
1081 UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
1083 return BaseAddr;
1084}
1085
1090
1091
1093
1094 if (ValidationSize >= Size)
1095 if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
1096 return *this;
1098}
1099
1100
1101
1104 if (!DA.isValidOffsetForDataOfSize(Offset, 16))
1106
1109
1112 (void)DA.getU16(&Offset);
1113
1114
1116}
1117
1118
1119
1122 if (!DA.isValidOffsetForDataOfSize(Offset, 8))
1124
1128
1130 (void)DA.getU16(&Offset);
1131
1132
1135}
1136
1142 switch (Format) {
1147 if (!DescOrError)
1148 return DescOrError.takeError();
1149 Desc = *DescOrError;
1150 break;
1151 }
1156 if (!DescOrError)
1157 return DescOrError.takeError();
1158 Desc = *DescOrError;
1159 break;
1160 }
1161 }
1162 return Desc.validateContributionSize(DA);
1163}
1164
1169 if (!OptOffset)
1170 return std::nullopt;
1171 auto DescOrError =
1173 if (!DescOrError)
1174 return DescOrError.takeError();
1175 return *DescOrError;
1176}
1177
1182 auto IndexEntry = Header.getIndexEntry();
1183 const auto *C =
1184 IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;
1185 if (C)
1188 if (DA.getData().data() == nullptr)
1189 return std::nullopt;
1190
1191
1192
1196 Offset += 4;
1197
1199 if (!DescOrError)
1200 return DescOrError.takeError();
1201 return *DescOrError;
1202 }
1203
1204
1205
1207 if (C)
1209 Header.getFormat());
1210 else if (!IndexEntry && !StringOffsetSection.Data.empty())
1212 4, Header.getFormat());
1213 else
1214 return std::nullopt;
1215 auto DescOrError = Desc.validateContributionSize(DA);
1216 if (!DescOrError)
1217 return DescOrError.takeError();
1218 return *DescOrError;
1219}
1220
1222 DataExtractor RangesData(RangeSection->Data, IsLittleEndian,
1225 IsLittleEndian, 0);
1228 return *Off + RangeSectionBase;
1229 return std::nullopt;
1230}
1231
1234 LocTable->getData(), LocSectionBase, getFormat(), Index))
1235 return *Off + LocSectionBase;
1236 return std::nullopt;
1237}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Expected< StrOffsetsContributionDescriptor > parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset)
Definition DWARFUnit.cpp:1103
static Expected< StrOffsetsContributionDescriptor > parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset)
Definition DWARFUnit.cpp:1121
static Expected< StrOffsetsContributionDescriptor > parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, llvm::dwarf::DwarfFormat Format, uint64_t Offset)
Definition DWARFUnit.cpp:1138
This file contains constants used for implementing Dwarf debug support.
This file defines the SmallString class.
A structured debug information entry.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
static bool isSupportedVersion(unsigned version)
static Error checkAddressSizeSupported(unsigned AddressSize, std::error_code EC, char const *Fmt, const Ts &...Vals)
static unsigned getMaxSupportedVersion()
DWARFDebugInfoEntry - A DIE with only the minimum required data.
std::optional< uint32_t > getSiblingIdx() const
Returns index of the sibling die.
std::optional< uint32_t > getParentIdx() const
Returns index of the parent die.
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
LLVM_ABI Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)
LLVM_ABI DWARFAddressRangesVector getAbsoluteRanges(std::optional< object::SectionedAddress > BaseAddr) const
getAbsoluteRanges - Returns absolute address ranges defined by this range list.
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
LLVM_ABI Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
LLVM_ABI DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
LLVM_ABI DWARFDie getParent() const
Get the parent of this DIE object.
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
LLVM_ABI DWARFDie getSibling() const
Get the sibling of this DIE object.
LLVM_ABI bool isSubroutineDIE() const
Returns true if DIE represents a subprogram or an inlined subroutine.
LLVM_ABI bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
LLVM_ABI std::optional< uint64_t > getTypeSize(uint64_t PointerSize)
Gets the type size (in bytes) for this DIE.
LLVM_ABI DWARFDie getFirstChild() const
Get the first child of this DIE object.
dwarf::Tag getTag() const
LLVM_ABI Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
LLVM_ABI std::optional< uint64_t > getRangesBaseAttribute() const
Extract the range base attribute from this DIE as absolute section offset.
Expected< DWARFListType > findList(DWARFDataExtractor Data, uint64_t Offset) const
Look up a list based on a given offset.
LLVM_ABI Error visitAbsoluteLocationList(uint64_t Offset, std::optional< object::SectionedAddress > BaseAddr, std::function< std::optional< object::SectionedAddress >(uint32_t)> LookupAddr, function_ref< bool(Expected< DWARFLocationExpression >)> Callback) const
Describe a collection of units.
LLVM_ABI DWARFUnit * addUnit(std::unique_ptr< DWARFUnit > Unit)
Add an existing DWARFUnit to this UnitVector.
Definition DWARFUnit.cpp:143
unsigned getNumInfoUnits() const
Returns number of units from all .debug_info[.dwo] sections.
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.
Definition DWARFUnit.cpp:164
LLVM_ABI void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
Definition DWARFUnit.cpp:42
LLVM_ABI DWARFUnit * getUnitForOffset(uint64_t Offset) const
Definition DWARFUnit.cpp:152
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.
Definition DWARFUnit.cpp:53
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
Return DWARFDebugInfoEntry for the specified index Index.
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
Definition DWARFUnit.cpp:938
std::optional< uint64_t > getDWOId()
uint32_t getHeaderSize() const
Size in bytes of the parsed unit header.
DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die)
Definition DWARFUnit.cpp:952
Expected< std::optional< StrOffsetsContributionDescriptor > > determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA)
Find the unit's contribution to the string offsets table and determine its length and form.
Definition DWARFUnit.cpp:1179
const DWARFLocationTable & getLocationTable()
const DWARFDebugInfoEntry * getParentEntry(const DWARFDebugInfoEntry *Die) const
Definition DWARFUnit.cpp:916
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die)
Definition DWARFUnit.cpp:991
DWARFDataExtractor getDebugInfoExtractor() const
Definition DWARFUnit.cpp:217
DWARFDie getSibling(const DWARFDebugInfoEntry *Die)
Definition DWARFUnit.cpp:930
std::optional< uint64_t > getRnglistOffset(uint32_t Index)
Return a rangelist's offset based on an index.
Definition DWARFUnit.cpp:1221
Error tryExtractDIEsIfNeeded(bool CUDieOnly)
Definition DWARFUnit.cpp:506
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
uint8_t getAddressByteSize() const
DWARFDie getVariableForAddress(uint64_t Address)
Returns variable DIE for the address provided.
Definition DWARFUnit.cpp:858
void setRangesSection(const DWARFSection *RS, uint64_t Base)
uint8_t getDwarfStringOffsetsByteSize() const
const DWARFAbbreviationDeclarationSet * getAbbreviations() const
Definition DWARFUnit.cpp:1061
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
Definition DWARFUnit.cpp:908
void clear()
Definition DWARFUnit.cpp:395
std::optional< uint64_t > getLoclistOffset(uint32_t Index)
Definition DWARFUnit.cpp:1232
const char * getCompilationDir()
Definition DWARFUnit.cpp:409
uint64_t getStringOffsetsBase() const
dwarf::DwarfFormat getFormat() const
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, const DWARFUnitVector &UnitVector)
Definition DWARFUnit.cpp:202
Expected< std::optional< StrOffsetsContributionDescriptor > > determineStringOffsetsTableContribution(DWARFDataExtractor &DA)
Find the unit's contribution to the string offsets table and determine its length and form.
Definition DWARFUnit.cpp:1166
uint64_t getAbbreviationsOffset() const
uint16_t getVersion() const
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition DWARFUnit.cpp:879
Error extractRangeList(uint64_t RangeListOffset, DWARFDebugRangeList &RangeList) const
Extract the range list referenced by this compile unit from the .debug_ranges section.
Definition DWARFUnit.cpp:385
Expected< uint64_t > getStringOffsetSectionItem(uint32_t Index) const
Definition DWARFUnit.cpp:246
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
Return the index of a Die entry inside the unit's DIE vector.
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
Definition DWARFUnit.cpp:716
Expected< DWARFAddressRangesVector > findRnglistFromOffset(uint64_t Offset)
Return a vector of address ranges resulting from a (possibly encoded) range list starting at a given ...
Definition DWARFUnit.cpp:674
bool isLittleEndian() const
const DWARFDebugInfoEntry * getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const
Definition DWARFUnit.cpp:960
const DWARFDebugInfoEntry * getLastChildEntry(const DWARFDebugInfoEntry *Die) const
Definition DWARFUnit.cpp:1024
void updateVariableDieMap(DWARFDie Die)
Recursively update address to variable Die map.
Definition DWARFUnit.cpp:784
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
Definition DWARFUnit.cpp:770
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
Definition DWARFUnit.cpp:999
Expected< DWARFAddressRangesVector > findRnglistFromIndex(uint32_t Index)
Return a vector of address ranges retrieved from an encoded range list whose offset is found via a ta...
Definition DWARFUnit.cpp:691
uint64_t getNextUnitOffset() const
std::optional< object::SectionedAddress > getBaseAddress()
Definition DWARFUnit.cpp:1075
Expected< DWARFAddressRangesVector > collectAddressRanges()
Definition DWARFUnit.cpp:701
std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const
Definition DWARFUnit.cpp:223
uint64_t getOffset() const
DWARFDie getLastChild(const DWARFDebugInfoEntry *Die)
Definition DWARFUnit.cpp:1016
void updateAddressDieMap(DWARFDie Die)
Recursively update address to Die map.
Definition DWARFUnit.cpp:739
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.
SectionKind - This is a simple POD value that classifies the properties of a section.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, std::unique_ptr< DWARFUnit > &&Elt)
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI unsigned getTag(StringRef TagString)
@ C
The default llvm calling convention, compatible with C.
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.
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
@ DW_LENGTH_lo_reserved
Special values for an initial length field.
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI const DWARFUnitIndex & getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind)
Definition DWARFUnit.cpp:900
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
DWARFSectionKind
The enum of section identifiers to be used in internal interfaces.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
static uint64_t getDebugInfoSize(DWARFContext &Dwarf)
Compute the total size of the debug info.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
void consumeError(Error Err)
Consume a Error without doing anything.
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
Represents a single DWARF expression, whose value is location-dependent.
Represents base address of the CU.
LLVM_ABI Expected< StrOffsetsContributionDescriptor > validateContributionSize(DWARFDataExtractor &DA)
Determine whether a contribution to the string offsets table is consistent with the relevant section ...
Definition DWARFUnit.cpp:1087
uint64_t Size
The contribution size not including the header.
uint8_t getDwarfOffsetByteSize() const