35 return OS <<
"DW_ATOM_unknown_" <<
format(
"%x",
A.Value);
49 "Section too small: cannot read header.");
63 Hdr.BucketCount * 4 + Hdr.HashCount * 8 - 1))
66 "Section too small: cannot read buckets and hashes.");
71 for (
unsigned i = 0;
i < NumAtoms; ++
i) {
74 HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
85 return Hdr.HeaderDataLength;
103 FormValue.
getForm() == dwarf::DW_FORM_sdata)
113 std::pair<uint64_t, dwarf::Tag>
122 switch (Atom.first) {
133 return {DieOffset, DieTag};
138 W.printHex(
"Magic",
Magic);
140 W.printHex(
"Hash function", HashFunction);
141 W.printNumber(
"Bucket count", BucketCount);
142 W.printNumber(
"Hashes count", HashCount);
143 W.printNumber(
"HeaderData length", HeaderDataLength);
151 switch (
Value->getForm()) {
152 case dwarf::DW_FORM_ref1:
153 case dwarf::DW_FORM_ref2:
154 case dwarf::DW_FORM_ref4:
155 case dwarf::DW_FORM_ref8:
156 case dwarf::DW_FORM_ref_udata:
157 return Value->getRawUValue() + DIEOffsetBase;
159 return Value->getAsSectionOffset();
169 W.printString(
"Incorrectly terminated list.");
177 W.startLine() <<
format(
"String: 0x%08" PRIx64, StringOffset);
184 for (
auto &Atom : AtomForms) {
185 W.startLine() <<
format(
"Atom[%d]: ",
i);
187 Atom.dump(
W.getOStream());
191 W.getOStream() <<
" (" << Str <<
")";
194 W.getOStream() <<
"Error extracting the value";
195 W.getOStream() <<
"\n";
210 W.printNumber(
"DIE offset base", HdrData.DIEOffsetBase);
211 W.printNumber(
"Number of atoms",
uint64_t(HdrData.Atoms.size()));
216 for (
const auto &Atom : HdrData.Atoms) {
218 W.startLine() <<
"Type: " <<
formatAtom(Atom.first) <<
'\n';
219 W.startLine() <<
"Form: " <<
formatv(
"{0}", Atom.second) <<
'\n';
225 uint64_t Offset =
sizeof(Hdr) + Hdr.HeaderDataLength;
226 uint64_t HashesBase = Offset + Hdr.BucketCount * 4;
227 uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
229 for (
unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) {
233 if (
Index == UINT32_MAX) {
234 W.printString(
"EMPTY");
238 for (
unsigned HashIdx =
Index; HashIdx < Hdr.HashCount; ++HashIdx) {
239 uint64_t HashOffset = HashesBase + HashIdx*4;
240 uint64_t OffsetsOffset = OffsetsBase + HashIdx*4;
243 if (Hash % Hdr.BucketCount != Bucket)
249 W.printString(
"Invalid section offset");
252 while (dumpName(
W, AtomForms, &DataOffset))
258 AppleAcceleratorTable::Entry::Entry(
259 const AppleAcceleratorTable::HeaderData &HdrData)
260 : HdrData(&HdrData) {
261 Values.reserve(HdrData.Atoms.size());
262 for (
const auto &Atom : HdrData.Atoms)
266 void AppleAcceleratorTable::Entry::extract(
277 assert(HdrData &&
"Dereferencing end iterator?");
278 assert(HdrData->Atoms.size() == Values.size());
279 for (
auto Tuple :
zip_first(HdrData->Atoms, Values)) {
280 if (std::get<0>(Tuple).first == Atom)
281 return std::get<1>(Tuple);
306 if (!
AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
310 NumData =
AccelTable.AccelSection.getU32(&DataOffset);
314 void AppleAcceleratorTable::ValueIterator::Next() {
315 assert(NumData > 0 &&
"attempted to increment iterator past the end");
317 if (
Data >= NumData ||
334 unsigned Bucket = HashValue % Hdr.BucketCount;
335 uint64_t BucketBase =
sizeof(Hdr) + Hdr.HeaderDataLength;
336 uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4;
337 uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
339 uint64_t BucketOffset = BucketBase + Bucket * 4;
343 for (
unsigned HashIdx =
Index; HashIdx < Hdr.HashCount; ++HashIdx) {
344 uint64_t HashOffset = HashesBase + HashIdx * 4;
345 uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4;
348 if (Hash % Hdr.BucketCount != Bucket)
366 W.printHex(
"Length", UnitLength);
369 W.printNumber(
"CU count", CompUnitCount);
370 W.printNumber(
"Local TU count", LocalTypeUnitCount);
371 W.printNumber(
"Foreign TU count", ForeignTypeUnitCount);
372 W.printNumber(
"Bucket count", BucketCount);
373 W.printNumber(
"Name count", NameCount);
374 W.printHex(
"Abbreviations table size", AbbrevTableSize);
375 W.startLine() <<
"Augmentation: '" << AugmentationString <<
"'\n";
380 auto HeaderError = [Offset = *Offset](
Error E) {
382 "parsing .debug_names header at 0x%" PRIx64
": %s",
392 LocalTypeUnitCount = AS.
getU32(
C);
393 ForeignTypeUnitCount = AS.
getU32(
C);
396 AbbrevTableSize = AS.
getU32(
C);
400 return HeaderError(
C.takeError());
404 "cannot read header augmentation"));
405 AugmentationString.resize(AugmentationStringSize);
406 AS.
getU8(
C,
reinterpret_cast<uint8_t *
>(AugmentationString.data()),
407 AugmentationStringSize);
409 return C.takeError();
417 W.startLine() <<
formatv(
"{0}: {1}\n", Attr.Index, Attr.Form);
433 return Abbr.
Code == 0;
445 DWARFDebugNames::NameIndex::extractAttributeEncoding(
uint64_t *Offset) {
446 if (*Offset >= EntriesBase) {
448 "Incorrectly terminated abbreviation table.");
457 DWARFDebugNames::NameIndex::extractAttributeEncodings(
uint64_t *Offset) {
458 std::vector<AttributeEncoding>
Result;
460 auto AttrEncOr = extractAttributeEncoding(Offset);
462 return AttrEncOr.takeError();
466 Result.emplace_back(*AttrEncOr);
471 DWARFDebugNames::NameIndex::extractAbbrev(
uint64_t *Offset) {
472 if (*Offset >= EntriesBase) {
474 "Incorrectly terminated abbreviation table.");
482 auto AttrEncOr = extractAttributeEncodings(Offset);
484 return AttrEncOr.takeError();
491 if (
Error E = Hdr.extract(AS, &Offset))
496 Offset += Hdr.CompUnitCount * SectionOffsetSize;
497 Offset += Hdr.LocalTypeUnitCount * SectionOffsetSize;
498 Offset += Hdr.ForeignTypeUnitCount * 8;
499 BucketsBase = Offset;
500 Offset += Hdr.BucketCount * 4;
502 if (Hdr.BucketCount > 0)
503 Offset += Hdr.NameCount * 4;
504 StringOffsetsBase = Offset;
505 Offset += Hdr.NameCount * SectionOffsetSize;
506 EntryOffsetsBase = Offset;
507 Offset += Hdr.NameCount * SectionOffsetSize;
511 "Section too small: cannot read abbreviations.");
513 EntriesBase = Offset + Hdr.AbbrevTableSize;
516 auto AbbrevOr = extractAbbrev(&Offset);
518 return AbbrevOr.takeError();
522 if (!Abbrevs.insert(
std::move(*AbbrevOr)).second)
524 "Duplicate abbreviation code.");
529 : NameIdx(&NameIdx), Abbr(&Abbr) {
534 Values.emplace_back(Attr.Form);
542 return std::get<1>(Tuple);
549 return Off->getAsReferenceUVal();
555 return Off->getAsUnsignedConstant();
571 W.printHex(
"Abbrev", Abbr->
Code);
576 std::get<1>(Tuple).dump(
W.getOStream());
577 W.getOStream() <<
'\n';
589 uint64_t Offset = CUsBase + SectionOffsetSize *
CU;
590 return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
594 assert(TU < Hdr.LocalTypeUnitCount);
596 uint64_t Offset = CUsBase + SectionOffsetSize * (Hdr.CompUnitCount + TU);
597 return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
601 assert(TU < Hdr.ForeignTypeUnitCount);
605 SectionOffsetSize * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU;
606 return Section.AccelSection.getU64(&Offset);
614 "Incorrectly terminated entry list.");
618 return make_error<SentinelError>();
620 const auto AbbrevIt = Abbrevs.find_as(AbbrevCode);
621 if (AbbrevIt == Abbrevs.end())
624 Entry E(*
this, *AbbrevIt);
627 for (
auto &
Value :
E.Values) {
630 "Error extracting index attribute values.");
640 StringOffsetsBase + SectionOffsetSize * (
Index - 1);
642 EntryOffsetsBase + SectionOffsetSize * (
Index - 1);
646 AS.getRelocatedValue(SectionOffsetSize, &StringOffsetOffset);
647 uint64_t EntryOffset = AS.getUnsigned(&EntryOffsetOffset, SectionOffsetSize);
648 EntryOffset += EntriesBase;
649 return {Section.StringSection,
Index, StringOffset, EntryOffset};
654 assert(Bucket < Hdr.BucketCount);
655 uint64_t BucketOffset = BucketsBase + 4 * Bucket;
656 return Section.AccelSection.getU32(&BucketOffset);
662 return Section.AccelSection.getU32(&HashOffset);
672 auto EntryOr = getEntry(Offset);
685 const NameTableEntry &NTE,
689 W.printHex(
"Hash", *Hash);
691 W.startLine() <<
format(
"String: 0x%08" PRIx64, NTE.getStringOffset());
692 W.getOStream() <<
" \"" << NTE.getString() <<
"\"\n";
694 uint64_t EntryOffset = NTE.getEntryOffset();
695 while (dumpEntry(
W, &EntryOffset))
699 void DWARFDebugNames::NameIndex::dumpCUs(
ScopedPrinter &
W)
const {
700 ListScope CUScope(
W,
"Compilation Unit offsets");
702 W.startLine() <<
format(
"CU[%u]: 0x%08" PRIx64
"\n",
CU, getCUOffset(
CU));
705 void DWARFDebugNames::NameIndex::dumpLocalTUs(
ScopedPrinter &
W)
const {
706 if (Hdr.LocalTypeUnitCount == 0)
709 ListScope TUScope(
W,
"Local Type Unit offsets");
710 for (
uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU)
711 W.startLine() <<
format(
"LocalTU[%u]: 0x%08" PRIx64
"\n", TU,
712 getLocalTUOffset(TU));
715 void DWARFDebugNames::NameIndex::dumpForeignTUs(
ScopedPrinter &
W)
const {
716 if (Hdr.ForeignTypeUnitCount == 0)
719 ListScope TUScope(
W,
"Foreign Type Unit signatures");
720 for (
uint32_t TU = 0; TU < Hdr.ForeignTypeUnitCount; ++TU) {
721 W.startLine() <<
format(
"ForeignTU[%u]: 0x%016" PRIx64
"\n", TU,
722 getForeignTUSignature(TU));
726 void DWARFDebugNames::NameIndex::dumpAbbreviations(
ScopedPrinter &
W)
const {
728 for (
const auto &Abbr : Abbrevs)
737 W.printString(
"EMPTY");
740 if (
Index > Hdr.NameCount) {
741 W.printString(
"Name index is invalid");
747 if (Hash % Hdr.BucketCount != Bucket)
750 dumpName(
W, getNameTableEntry(
Index), Hash);
760 dumpAbbreviations(
W);
762 if (Hdr.BucketCount > 0) {
763 for (
uint32_t Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket)
764 dumpBucket(
W, Bucket);
768 W.startLine() <<
"Hash table not present\n";
770 dumpName(
W, NTE,
None);
797 DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() {
798 const Header &Hdr = CurrentIndex->Hdr;
799 if (Hdr.BucketCount == 0) {
801 for (
const NameTableEntry &NTE : *CurrentIndex) {
802 if (NTE.getString() ==
Key)
803 return NTE.getEntryOffset();
812 uint32_t Bucket = *Hash % Hdr.BucketCount;
819 if (Hash % Hdr.BucketCount != Bucket)
822 NameTableEntry NTE = CurrentIndex->getNameTableEntry(
Index);
823 if (NTE.getString() ==
Key)
824 return NTE.getEntryOffset();
829 bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() {
830 auto EntryOr = CurrentIndex->getEntry(&DataOffset);
839 bool DWARFDebugNames::ValueIterator::findInCurrentIndex() {
844 return getEntryAtCurrentOffset();
847 void DWARFDebugNames::ValueIterator::searchFromStartOfCurrentIndex() {
848 for (
const NameIndex *End = CurrentIndex->Section.NameIndices.end();
849 CurrentIndex != End; ++CurrentIndex) {
850 if (findInCurrentIndex())
856 void DWARFDebugNames::ValueIterator::next() {
857 assert(CurrentIndex &&
"Incrementing an end() iterator?");
860 if (getEntryAtCurrentOffset())
864 if (IsLocal || CurrentIndex == &CurrentIndex->Section.NameIndices.back()) {
871 searchFromStartOfCurrentIndex();
878 searchFromStartOfCurrentIndex();
884 if (!findInCurrentIndex())
890 if (NameIndices.empty())
897 if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
898 for (
const auto &NI : *
this) {
900 CUToNameIndex.try_emplace(NI.getCUOffset(
CU), &NI);
903 return CUToNameIndex.lookup(CUOffset);