40 using namespace dwarf;
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,
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,
65 void DWARFUnitVector::addUnitsImpl(
74 Parser = [=, &
Context, &Obj, &Section, &SOS,
78 -> std::unique_ptr<DWARFUnit> {
79 const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
81 if (!
Data.isValidOffset(Offset))
86 if (!IndexEntry && IsDWO) {
92 else if (
auto DWOId = Header.
getDWOId())
93 IndexEntry =
Index.getFromHash(*DWOId);
100 std::unique_ptr<DWARFUnit> U;
102 U = std::make_unique<DWARFTypeUnit>(
Context, InfoSection, Header,
DA,
103 RS, LocSection,
SS, SOS, AOS,
LS,
106 U = std::make_unique<DWARFCompileUnit>(
Context, InfoSection, Header,
107 DA, RS, LocSection,
SS, SOS,
108 AOS,
LS,
LE, IsDWO, *
this);
121 while (
Data.isValidOffset(Offset)) {
122 if (
I != this->
end() &&
123 (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
127 auto U = Parser(Offset,
SectionKind, &Section,
nullptr);
131 Offset = U->getNextUnitOffset();
138 [](
const std::unique_ptr<DWARFUnit> &
LHS,
139 const std::unique_ptr<DWARFUnit> &
RHS) {
140 return LHS->getOffset() <
RHS->getOffset();
142 return this->insert(
I,
std::move(Unit))->get();
146 auto end =
begin() + getNumInfoUnits();
150 return LHS <
RHS->getNextUnitOffset();
152 if (
CU !=
end && (*CU)->getOffset() <= Offset)
159 const auto *CUOff =
E.getContribution(DW_SECT_INFO);
163 auto Offset = CUOff->Offset;
164 auto end =
begin() + getNumInfoUnits();
169 return LHS < RHS->getNextUnitOffset();
171 if (
CU !=
end && (*CU)->getOffset() <= Offset)
177 auto U = Parser(Offset, DW_SECT_INFO,
nullptr, &
E);
181 auto *NewCU = U.get();
193 :
Context(
DC), InfoSection(Section), Header(Header), Abbrev(
DA),
194 RangeSection(RS), LineSection(
LS), StringSection(
SS),
195 StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(
LE),
196 IsDWO(IsDWO), UnitVector(UnitVector) {
209 if (!AddrOffsetSectionBase) {
210 auto R =
Context.info_section_units();
216 return (*R.begin())->getAddrOffsetSectionItem(
Index);
227 uint64_t Address =
DA.getRelocatedAddress(&Offset, &Section);
228 return {{Address, Section}};
232 if (!StringOffsetsTableContribution)
233 return make_error<StringError>(
234 "DW_FORM_strx used without a valid string offsets table",
238 if (StringOffsetSection.
Data.
size() < Offset + ItemSize)
239 return make_error<StringError>(
"DW_FORM_strx uses index " +
Twine(
Index) +
240 ", which is too large",
244 return DA.getRelocatedValue(ItemSize, &Offset);
251 Offset = *offset_ptr;
253 IndexEntry =
nullptr;
274 TypeHash = debug_info.
getU64(offset_ptr, &Err);
278 DWOId = debug_info.
getU64(offset_ptr, &Err);
284 "DWARF unit at 0x%8.8" PRIx64
" cannot be parsed:", Offset),
290 assert(*offset_ptr - Offset <= 255 &&
"unexpected header size");
291 Size = uint8_t(*offset_ptr - Offset);
297 "DWARF unit from offset 0x%8.8" PRIx64
" incl. "
298 "to offset 0x%8.8" PRIx64
" excl. "
299 "extends past section size 0x%8.8zx",
300 Offset, NextCUOffset, debug_info.
size()));
307 "DWARF unit at offset 0x%8.8" PRIx64
" "
308 "has unsupported version %" PRIu16
", supported are 2-%u",
318 "DWARF type unit at offset "
320 "has its relocated type_offset 0x%8.8" PRIx64
" "
321 "pointing inside the header",
322 Offset, Offset + TypeOffset));
329 "DWARF type unit from offset 0x%8.8" PRIx64
" incl. "
330 "to offset 0x%8.8" PRIx64
" excl. has its "
331 "relocated type_offset 0x%8.8" PRIx64
" pointing past the unit end",
332 Offset, NextCUOffset, Offset + TypeOffset));
338 "DWARF unit at offset 0x%8.8" PRIx64, Offset)) {
361 AbbrOffset = AbbrEntry->Offset;
368 assert(!DieArray.empty());
371 uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
372 return RangeList.
extract(RangesData, &ActualRangeListOffset);
378 RangeSectionBase = 0;
380 AddrOffsetSectionBase =
None;
393 void DWARFUnit::extractDIEsToVector(
394 bool AppendCUDie,
bool AppendNonCUDies,
395 std::vector<DWARFDebugInfoEntry> &Dies)
const {
396 if (!AppendCUDie && !AppendNonCUDies)
407 std::vector<uint32_t> Parents;
408 std::vector<uint32_t> PrevSiblings;
412 ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&
413 "Dies array is not empty");
416 Parents.push_back(UINT32_MAX);
418 Parents.push_back(0);
419 PrevSiblings.push_back(0);
423 assert(Parents.size() > 0 &&
"Empty parents stack");
424 assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&
425 "Wrong parent index");
428 if (!
DIE.extractFast(*
this, &DIEOffset, DebugInfoData, NextCUOffset,
433 if (PrevSiblings.back() > 0) {
434 assert(PrevSiblings.back() < Dies.size() &&
435 "Previous sibling index is out of Dies boundaries");
436 Dies[PrevSiblings.back()].setSiblingIdx(Dies.size());
443 if (!AppendNonCUDies)
448 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
451 PrevSiblings.back() = Dies.size();
458 DIE.getAbbreviationDeclarationPtr()) {
459 if (AbbrDecl->hasChildren()) {
460 if (AppendCUDie || !IsCUDie) {
461 assert(Dies.size() > 0 &&
"Dies does not contain any die");
462 Parents.push_back(Dies.size() - 1);
463 PrevSiblings.push_back(0);
471 PrevSiblings.pop_back();
478 }
while (Parents.size() > 1);
481 void DWARFUnit::extractDIEsIfNeeded(
bool CUDieOnly) {
487 if ((CUDieOnly && !DieArray.empty()) ||
491 bool HasCUDie = !DieArray.empty();
492 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
494 if (DieArray.empty())
501 DWARFDie UnitDie(
this, &DieArray[0]);
506 assert(RangeSectionBase == 0);
507 assert(LocSectionBase == 0);
509 if (!AddrOffsetSectionBase)
510 AddrOffsetSectionBase =
526 auto StringOffsetOrError =
529 if (!StringOffsetOrError)
531 "invalid reference to or invalid content in "
532 ".debug_str_offsets[.dwo]: " +
533 toString(StringOffsetOrError.takeError()));
535 StringOffsetsTableContribution = *StringOffsetOrError;
543 uint64_t ContributionBaseOffset = 0;
545 if (
auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
546 ContributionBaseOffset = Contrib->Offset;
548 &
Context.getDWARFObj().getRnglistsDWOSection(),
549 ContributionBaseOffset +
562 ?
Context.getDWARFObj().getLoclistsDWOSection().Data
563 :
Context.getDWARFObj().getLocDWOSection().Data;
565 if (
const auto *
C = IndexEntry->getContribution(
571 std::make_unique<DWARFDebugLoclists>(DWARFData, Header.
getVersion());
574 LocTable = std::make_unique<DWARFDebugLoclists>(
576 Context.getDWARFObj().getLoclistsSection(),
590 bool DWARFUnit::parseDWO() {
613 auto DWOContext =
Context.getDWOContext(AbsolutePath);
620 DWO = std::shared_ptr<DWARFCompileUnit>(
std::move(DWOContext), DWOCU);
621 DWO->setSkeletonUnit(
this);
623 if (AddrOffsetSectionBase)
624 DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
627 DWO->setRangesSection(RangeSection, DWORangesBase.value_or(0));
633 void DWARFUnit::clearDIEs(
bool KeepCUDie) {
639 DieArray = (KeepCUDie && !DieArray.empty())
640 ? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
641 : std::vector<DWARFDebugInfoEntry>();
655 auto RangeListOrError = RnglistTable.
findList(RangesData, Offset);
656 if (RangeListOrError)
657 return RangeListOrError.get().getAbsoluteRanges(
getBaseAddress(), *
this);
658 return RangeListOrError.takeError();
667 "invalid range list table index %d (possibly "
668 "missing the entire range list table)",
679 if (!CUDIERangesOrError)
681 "decoding address ranges: %s",
682 toString(CUDIERangesOrError.takeError()).c_str());
683 return *CUDIERangesOrError;
699 InterpretationError =
701 return !InterpretationError;
704 if (ParseError || InterpretationError)
713 if (DIERangesOrError) {
714 for (
const auto &R : DIERangesOrError.get()) {
716 if (R.LowPC == R.HighPC)
718 auto B = AddrDieMap.upper_bound(R.LowPC);
719 if (
B != AddrDieMap.begin() && R.LowPC < (--
B)->second.first) {
722 if (R.HighPC <
B->second.first)
723 AddrDieMap[R.HighPC] =
B->second;
724 if (R.LowPC >
B->first)
725 AddrDieMap[
B->first].first = R.LowPC;
727 AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
742 extractDIEsIfNeeded(
false);
743 if (AddrDieMap.empty())
745 auto R = AddrDieMap.upper_bound(Address);
746 if (R == AddrDieMap.begin())
750 if (Address >= R->second.first)
752 return R->second.second;
757 if (
isType(Child.getTag()))
762 if (Die.getTag() != DW_TAG_variable)
766 Die.getLocations(DW_AT_location);
779 auto It = Expr.
begin();
780 if (It == Expr.
end())
790 if (It->getCode() == dwarf::DW_OP_addr) {
791 LocationAddr = It->getRawOperand(0);
792 }
else if (It->getCode() == dwarf::DW_OP_addrx) {
793 uint64_t DebugAddrOffset = It->getRawOperand(0);
795 LocationAddr = Pointer->Address;
802 if (++It != Expr.
end()) {
803 if (It->getCode() != dwarf::DW_OP_plus_uconst)
806 LocationAddr += It->getRawOperand(0);
809 if (++It != Expr.
end())
813 Address = LocationAddr;
826 VariableDieMap[Address] = {Address + GVSize, Die};
830 extractDIEsIfNeeded(
false);
834 auto RootLookup = RootsParsedForVariables.
insert(RootDie.getOffset());
835 if (RootLookup.second)
838 auto R = VariableDieMap.upper_bound(Address);
839 if (R == VariableDieMap.begin())
844 if (Address >= R->second.first)
846 return R->second.second;
852 assert(InlinedChain.empty());
860 while (SubroutineDIE) {
862 InlinedChain.push_back(SubroutineDIE);
865 if (SubroutineDIE.
getTag() == DW_TAG_inlined_subroutine)
866 InlinedChain.push_back(SubroutineDIE);
867 SubroutineDIE = SubroutineDIE.
getParent();
873 if (
Kind == DW_SECT_INFO)
884 assert(*ParentIdx < DieArray.size() &&
885 "ParentIdx is out of DieArray boundaries");
886 return DWARFDie(
this, &DieArray[*ParentIdx]);
897 assert(*SiblingIdx < DieArray.size() &&
898 "SiblingIdx is out of DieArray boundaries");
899 return DWARFDie(
this, &DieArray[*SiblingIdx]);
914 assert(*ParentIdx < DieArray.size() &&
915 "ParentIdx is out of DieArray boundaries");
916 assert(getDIEIndex(Die) > 0 &&
"Die is a root die");
918 uint32_t PrevDieIdx = getDIEIndex(Die) - 1;
919 if (PrevDieIdx == *ParentIdx)
923 while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
924 PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
926 assert(PrevDieIdx < DieArray.size() &&
927 "PrevDieIdx is out of DieArray boundaries");
928 assert(PrevDieIdx >= *ParentIdx &&
929 "PrevDieIdx is not a child of parent of Die");
932 return DWARFDie(
this, &DieArray[PrevDieIdx]);
942 size_t I = getDIEIndex(Die) + 1;
943 if (
I >= DieArray.size())
953 assert(*SiblingIdx < DieArray.size() &&
954 "SiblingIdx is out of DieArray boundaries");
955 assert(DieArray[*SiblingIdx - 1].
getTag() == dwarf::DW_TAG_null &&
956 "Bad end of children marker");
957 return DWARFDie(
this, &DieArray[*SiblingIdx - 1]);
969 if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
970 DieArray.back().getTag() == dwarf::DW_TAG_null) {
973 return DWARFDie(
this, &DieArray.back());
1003 if (ValidationSize >=
Size)
1004 if (
DA.isValidOffsetForDataOfSize((
uint32_t)
Base, ValidationSize))
1013 if (!
DA.isValidOffsetForDataOfSize(Offset, 16))
1021 (void)
DA.getU16(&Offset);
1031 if (!
DA.isValidOffsetForDataOfSize(Offset, 8))
1034 uint32_t ContributionSize =
DA.getU32(&Offset);
1039 (void)
DA.getU16(&Offset);
1057 return DescOrError.takeError();
1058 Desc = *DescOrError;
1066 return DescOrError.takeError();
1067 Desc = *DescOrError;
1083 return DescOrError.takeError();
1084 return *DescOrError;
1093 IndexEntry ? IndexEntry->
getContribution(DW_SECT_STR_OFFSETS) :
nullptr;
1097 if (
DA.getData().data() ==
nullptr)
1103 return DescOrError.takeError();
1104 return *DescOrError;
1113 else if (!IndexEntry && !StringOffsetSection.
Data.
empty())
1120 return DescOrError.takeError();
1121 return *DescOrError;
1131 return *Off + RangeSectionBase;
1138 return *Off + LocSectionBase;