1 //===- DWARFVerifier.cpp --------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
11 #include "llvm/ADT/SmallSet.h"
12 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
13 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
15 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
16 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
17 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
18 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
19 #include "llvm/Support/DJB.h"
20 #include "llvm/Support/FormatVariadic.h"
21 #include "llvm/Support/WithColor.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <map>
24 #include <set>
25 #include <vector>
26 
27 using namespace llvm;
28 using namespace dwarf;
29 using namespace object;
30 
31 DWARFVerifier::DieRangeInfo::address_range_iterator
32 DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
33   auto Begin = Ranges.begin();
34   auto End = Ranges.end();
35   auto Pos = std::lower_bound(Begin, End, R);
36 
37   if (Pos != End) {
38     if (Pos->intersects(R))
39       return Pos;
40     if (Pos != Begin) {
41       auto Iter = Pos - 1;
42       if (Iter->intersects(R))
43         return Iter;
44     }
45   }
46 
47   Ranges.insert(Pos, R);
48   return Ranges.end();
49 }
50 
51 DWARFVerifier::DieRangeInfo::die_range_info_iterator
52 DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) {
53   auto End = Children.end();
54   auto Iter = Children.begin();
55   while (Iter != End) {
56     if (Iter->intersects(RI))
57       return Iter;
58     ++Iter;
59   }
60   Children.insert(RI);
61   return Children.end();
62 }
63 
64 bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const {
65   // Both list of ranges are sorted so we can make this fast.
66 
67   if (Ranges.empty() || RHS.Ranges.empty())
68     return false;
69 
70   // Since the ranges are sorted we can advance where we start searching with
71   // this object's ranges as we traverse RHS.Ranges.
72   auto End = Ranges.end();
73   auto Iter = findRange(RHS.Ranges.front());
74 
75   // Now linearly walk the ranges in this object and see if they contain each
76   // ranges from RHS.Ranges.
77   for (const auto &R : RHS.Ranges) {
78     while (Iter != End) {
79       if (Iter->contains(R))
80         break;
81       ++Iter;
82     }
83     if (Iter == End)
84       return false;
85   }
86   return true;
87 }
88 
89 bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
90   if (Ranges.empty() || RHS.Ranges.empty())
91     return false;
92 
93   auto End = Ranges.end();
94   auto Iter = findRange(RHS.Ranges.front());
95   for (const auto &R : RHS.Ranges) {
96     if(Iter == End)
97       return false;
98     if (R.HighPC <= Iter->LowPC)
99       continue;
100     while (Iter != End) {
101       if (Iter->intersects(R))
102         return true;
103       ++Iter;
104     }
105   }
106 
107   return false;
108 }
109 
110 bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
111                                      uint32_t *Offset, unsigned UnitIndex,
112                                      uint8_t &UnitType, bool &isUnitDWARF64) {
113   uint32_t AbbrOffset, Length;
114   uint8_t AddrSize = 0;
115   uint16_t Version;
116   bool Success = true;
117 
118   bool ValidLength = false;
119   bool ValidVersion = false;
120   bool ValidAddrSize = false;
121   bool ValidType = true;
122   bool ValidAbbrevOffset = true;
123 
124   uint32_t OffsetStart = *Offset;
125   Length = DebugInfoData.getU32(Offset);
126   if (Length == UINT32_MAX) {
127     isUnitDWARF64 = true;
128     OS << format(
129         "Unit[%d] is in 64-bit DWARF format; cannot verify from this point.\n",
130         UnitIndex);
131     return false;
132   }
133   Version = DebugInfoData.getU16(Offset);
134 
135   if (Version >= 5) {
136     UnitType = DebugInfoData.getU8(Offset);
137     AddrSize = DebugInfoData.getU8(Offset);
138     AbbrOffset = DebugInfoData.getU32(Offset);
139     ValidType = dwarf::isUnitType(UnitType);
140   } else {
141     UnitType = 0;
142     AbbrOffset = DebugInfoData.getU32(Offset);
143     AddrSize = DebugInfoData.getU8(Offset);
144   }
145 
146   if (!DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset))
147     ValidAbbrevOffset = false;
148 
149   ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
150   ValidVersion = DWARFContext::isSupportedVersion(Version);
151   ValidAddrSize = AddrSize == 4 || AddrSize == 8;
152   if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
153       !ValidType) {
154     Success = false;
155     error() << format("Units[%d] - start offset: 0x%08x \n", UnitIndex,
156                       OffsetStart);
157     if (!ValidLength)
158       note() << "The length for this unit is too "
159             "large for the .debug_info provided.\n";
160     if (!ValidVersion)
161       note() << "The 16 bit unit header version is not valid.\n";
162     if (!ValidType)
163       note() << "The unit type encoding is not valid.\n";
164     if (!ValidAbbrevOffset)
165       note() << "The offset into the .debug_abbrev section is "
166             "not valid.\n";
167     if (!ValidAddrSize)
168       note() << "The address size is unsupported.\n";
169   }
170   *Offset = OffsetStart + Length + 4;
171   return Success;
172 }
173 
174 bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit, uint8_t UnitType) {
175   uint32_t NumUnitErrors = 0;
176   unsigned NumDies = Unit.getNumDIEs();
177   for (unsigned I = 0; I < NumDies; ++I) {
178     auto Die = Unit.getDIEAtIndex(I);
179     if (Die.getTag() == DW_TAG_null)
180       continue;
181     for (auto AttrValue : Die.attributes()) {
182       NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
183       NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
184     }
185   }
186 
187   DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
188   if (!Die) {
189     error() << "Compilation unit without DIE.\n";
190     NumUnitErrors++;
191     return NumUnitErrors == 0;
192   }
193 
194   if (!dwarf::isUnitType(Die.getTag())) {
195     error() << "Compilation unit root DIE is not a unit DIE: "
196             << dwarf::TagString(Die.getTag()) << ".\n";
197     NumUnitErrors++;
198   }
199 
200   if (UnitType != 0 &&
201       !DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
202     error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
203             << ") and root DIE (" << dwarf::TagString(Die.getTag())
204             << ") do not match.\n";
205     NumUnitErrors++;
206   }
207 
208   DieRangeInfo RI;
209   NumUnitErrors += verifyDieRanges(Die, RI);
210 
211   return NumUnitErrors == 0;
212 }
213 
214 unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
215   unsigned NumErrors = 0;
216   if (Abbrev) {
217     const DWARFAbbreviationDeclarationSet *AbbrDecls =
218         Abbrev->getAbbreviationDeclarationSet(0);
219     for (auto AbbrDecl : *AbbrDecls) {
220       SmallDenseSet<uint16_t> AttributeSet;
221       for (auto Attribute : AbbrDecl.attributes()) {
222         auto Result = AttributeSet.insert(Attribute.Attr);
223         if (!Result.second) {
224           error() << "Abbreviation declaration contains multiple "
225                   << AttributeString(Attribute.Attr) << " attributes.\n";
226           AbbrDecl.dump(OS);
227           ++NumErrors;
228         }
229       }
230     }
231   }
232   return NumErrors;
233 }
234 
235 bool DWARFVerifier::handleDebugAbbrev() {
236   OS << "Verifying .debug_abbrev...\n";
237 
238   const DWARFObject &DObj = DCtx.getDWARFObj();
239   bool noDebugAbbrev = DObj.getAbbrevSection().empty();
240   bool noDebugAbbrevDWO = DObj.getAbbrevDWOSection().empty();
241 
242   if (noDebugAbbrev && noDebugAbbrevDWO) {
243     return true;
244   }
245 
246   unsigned NumErrors = 0;
247   if (!noDebugAbbrev)
248     NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev());
249 
250   if (!noDebugAbbrevDWO)
251     NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO());
252   return NumErrors == 0;
253 }
254 
255 bool DWARFVerifier::handleDebugInfo() {
256   OS << "Verifying .debug_info Unit Header Chain...\n";
257 
258   const DWARFObject &DObj = DCtx.getDWARFObj();
259   DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(),
260                                    DCtx.isLittleEndian(), 0);
261   uint32_t NumDebugInfoErrors = 0;
262   uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
263   uint8_t UnitType = 0;
264   bool isUnitDWARF64 = false;
265   bool isHeaderChainValid = true;
266   bool hasDIE = DebugInfoData.isValidOffset(Offset);
267   DWARFUnitSection<DWARFTypeUnit> TUSection{};
268   DWARFUnitSection<DWARFCompileUnit> CUSection{};
269   while (hasDIE) {
270     OffsetStart = Offset;
271     if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
272                           isUnitDWARF64)) {
273       isHeaderChainValid = false;
274       if (isUnitDWARF64)
275         break;
276     } else {
277       std::unique_ptr<DWARFUnit> Unit;
278       switch (UnitType) {
279       case dwarf::DW_UT_type:
280       case dwarf::DW_UT_split_type: {
281         Unit.reset(new DWARFTypeUnit(
282             DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
283             &DObj.getRangeSection(), DObj.getStringSection(),
284             DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
285             DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
286             nullptr));
287         break;
288       }
289       case dwarf::DW_UT_skeleton:
290       case dwarf::DW_UT_split_compile:
291       case dwarf::DW_UT_compile:
292       case dwarf::DW_UT_partial:
293       // UnitType = 0 means that we are
294       // verifying a compile unit in DWARF v4.
295       case 0: {
296         Unit.reset(new DWARFCompileUnit(
297             DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
298             &DObj.getRangeSection(), DObj.getStringSection(),
299             DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
300             DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
301             nullptr));
302         break;
303       }
304       default: { llvm_unreachable("Invalid UnitType."); }
305       }
306       Unit->extract(DebugInfoData, &OffsetStart);
307       if (!verifyUnitContents(*Unit, UnitType))
308         ++NumDebugInfoErrors;
309     }
310     hasDIE = DebugInfoData.isValidOffset(Offset);
311     ++UnitIdx;
312   }
313   if (UnitIdx == 0 && !hasDIE) {
314     warn() << ".debug_info is empty.\n";
315     isHeaderChainValid = true;
316   }
317   NumDebugInfoErrors += verifyDebugInfoReferences();
318   return (isHeaderChainValid && NumDebugInfoErrors == 0);
319 }
320 
321 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
322                                         DieRangeInfo &ParentRI) {
323   unsigned NumErrors = 0;
324 
325   if (!Die.isValid())
326     return NumErrors;
327 
328   DWARFAddressRangesVector Ranges = Die.getAddressRanges();
329 
330   // Build RI for this DIE and check that ranges within this DIE do not
331   // overlap.
332   DieRangeInfo RI(Die);
333   for (auto Range : Ranges) {
334     if (!Range.valid()) {
335       ++NumErrors;
336       error() << "Invalid address range " << Range << "\n";
337       continue;
338     }
339 
340     // Verify that ranges don't intersect.
341     const auto IntersectingRange = RI.insert(Range);
342     if (IntersectingRange != RI.Ranges.end()) {
343       ++NumErrors;
344       error() << "DIE has overlapping address ranges: " << Range << " and "
345               << *IntersectingRange << "\n";
346       break;
347     }
348   }
349 
350   // Verify that children don't intersect.
351   const auto IntersectingChild = ParentRI.insert(RI);
352   if (IntersectingChild != ParentRI.Children.end()) {
353     ++NumErrors;
354     error() << "DIEs have overlapping address ranges:";
355     Die.dump(OS, 0);
356     IntersectingChild->Die.dump(OS, 0);
357     OS << "\n";
358   }
359 
360   // Verify that ranges are contained within their parent.
361   bool ShouldBeContained = !Ranges.empty() && !ParentRI.Ranges.empty() &&
362                            !(Die.getTag() == DW_TAG_subprogram &&
363                              ParentRI.Die.getTag() == DW_TAG_subprogram);
364   if (ShouldBeContained && !ParentRI.contains(RI)) {
365     ++NumErrors;
366     error() << "DIE address ranges are not "
367                "contained in its parent's ranges:";
368     Die.dump(OS, 0);
369     ParentRI.Die.dump(OS, 0);
370     OS << "\n";
371   }
372 
373   // Recursively check children.
374   for (DWARFDie Child : Die)
375     NumErrors += verifyDieRanges(Child, RI);
376 
377   return NumErrors;
378 }
379 
380 unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
381                                                  DWARFAttribute &AttrValue) {
382   unsigned NumErrors = 0;
383   auto ReportError = [&](const Twine &TitleMsg) {
384     ++NumErrors;
385     error() << TitleMsg << '\n';
386     Die.dump(OS, 0, DumpOpts);
387     OS << "\n";
388   };
389 
390   const DWARFObject &DObj = DCtx.getDWARFObj();
391   const auto Attr = AttrValue.Attr;
392   switch (Attr) {
393   case DW_AT_ranges:
394     // Make sure the offset in the DW_AT_ranges attribute is valid.
395     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
396       if (*SectionOffset >= DObj.getRangeSection().Data.size())
397         ReportError("DW_AT_ranges offset is beyond .debug_ranges bounds:");
398       break;
399     }
400     ReportError("DIE has invalid DW_AT_ranges encoding:");
401     break;
402   case DW_AT_stmt_list:
403     // Make sure the offset in the DW_AT_stmt_list attribute is valid.
404     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
405       if (*SectionOffset >= DObj.getLineSection().Data.size())
406         ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
407                     llvm::formatv("{0:x8}", *SectionOffset));
408       break;
409     }
410     ReportError("DIE has invalid DW_AT_stmt_list encoding:");
411     break;
412   case DW_AT_location: {
413     auto VerifyLocation = [&](StringRef D) {
414       DWARFUnit *U = Die.getDwarfUnit();
415       DataExtractor Data(D, DCtx.isLittleEndian(), 0);
416       DWARFExpression Expression(Data, U->getVersion(),
417                                  U->getAddressByteSize());
418       bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
419         return Op.isError();
420       });
421       if (Error)
422         ReportError("DIE contains invalid DWARF expression:");
423     };
424     if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) {
425       // Verify inlined location.
426       VerifyLocation(llvm::toStringRef(*Expr));
427     } else if (auto LocOffset = AttrValue.Value.getAsUnsignedConstant()) {
428       // Verify location list.
429       if (auto DebugLoc = DCtx.getDebugLoc())
430         if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset))
431           for (const auto &Entry : LocList->Entries)
432             VerifyLocation({Entry.Loc.data(), Entry.Loc.size()});
433     }
434     break;
435   }
436 
437   default:
438     break;
439   }
440   return NumErrors;
441 }
442 
443 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
444                                             DWARFAttribute &AttrValue) {
445   const DWARFObject &DObj = DCtx.getDWARFObj();
446   unsigned NumErrors = 0;
447   const auto Form = AttrValue.Value.getForm();
448   switch (Form) {
449   case DW_FORM_ref1:
450   case DW_FORM_ref2:
451   case DW_FORM_ref4:
452   case DW_FORM_ref8:
453   case DW_FORM_ref_udata: {
454     // Verify all CU relative references are valid CU offsets.
455     Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
456     assert(RefVal);
457     if (RefVal) {
458       auto DieCU = Die.getDwarfUnit();
459       auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
460       auto CUOffset = AttrValue.Value.getRawUValue();
461       if (CUOffset >= CUSize) {
462         ++NumErrors;
463         error() << FormEncodingString(Form) << " CU offset "
464                 << format("0x%08" PRIx64, CUOffset)
465                 << " is invalid (must be less than CU size of "
466                 << format("0x%08" PRIx32, CUSize) << "):\n";
467         Die.dump(OS, 0, DumpOpts);
468         OS << "\n";
469       } else {
470         // Valid reference, but we will verify it points to an actual
471         // DIE later.
472         ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
473       }
474     }
475     break;
476   }
477   case DW_FORM_ref_addr: {
478     // Verify all absolute DIE references have valid offsets in the
479     // .debug_info section.
480     Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
481     assert(RefVal);
482     if (RefVal) {
483       if (*RefVal >= DObj.getInfoSection().Data.size()) {
484         ++NumErrors;
485         error() << "DW_FORM_ref_addr offset beyond .debug_info "
486                    "bounds:\n";
487         Die.dump(OS, 0, DumpOpts);
488         OS << "\n";
489       } else {
490         // Valid reference, but we will verify it points to an actual
491         // DIE later.
492         ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
493       }
494     }
495     break;
496   }
497   case DW_FORM_strp: {
498     auto SecOffset = AttrValue.Value.getAsSectionOffset();
499     assert(SecOffset); // DW_FORM_strp is a section offset.
500     if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
501       ++NumErrors;
502       error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
503       Die.dump(OS, 0, DumpOpts);
504       OS << "\n";
505     }
506     break;
507   }
508   default:
509     break;
510   }
511   return NumErrors;
512 }
513 
514 unsigned DWARFVerifier::verifyDebugInfoReferences() {
515   // Take all references and make sure they point to an actual DIE by
516   // getting the DIE by offset and emitting an error
517   OS << "Verifying .debug_info references...\n";
518   unsigned NumErrors = 0;
519   for (auto Pair : ReferenceToDIEOffsets) {
520     auto Die = DCtx.getDIEForOffset(Pair.first);
521     if (Die)
522       continue;
523     ++NumErrors;
524     error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
525             << ". Offset is in between DIEs:\n";
526     for (auto Offset : Pair.second) {
527       auto ReferencingDie = DCtx.getDIEForOffset(Offset);
528       ReferencingDie.dump(OS, 0, DumpOpts);
529       OS << "\n";
530     }
531     OS << "\n";
532   }
533   return NumErrors;
534 }
535 
536 void DWARFVerifier::verifyDebugLineStmtOffsets() {
537   std::map<uint64_t, DWARFDie> StmtListToDie;
538   for (const auto &CU : DCtx.compile_units()) {
539     auto Die = CU->getUnitDIE();
540     // Get the attribute value as a section offset. No need to produce an
541     // error here if the encoding isn't correct because we validate this in
542     // the .debug_info verifier.
543     auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
544     if (!StmtSectionOffset)
545       continue;
546     const uint32_t LineTableOffset = *StmtSectionOffset;
547     auto LineTable = DCtx.getLineTableForUnit(CU.get());
548     if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
549       if (!LineTable) {
550         ++NumDebugLineErrors;
551         error() << ".debug_line[" << format("0x%08" PRIx32, LineTableOffset)
552                 << "] was not able to be parsed for CU:\n";
553         Die.dump(OS, 0, DumpOpts);
554         OS << '\n';
555         continue;
556       }
557     } else {
558       // Make sure we don't get a valid line table back if the offset is wrong.
559       assert(LineTable == nullptr);
560       // Skip this line table as it isn't valid. No need to create an error
561       // here because we validate this in the .debug_info verifier.
562       continue;
563     }
564     auto Iter = StmtListToDie.find(LineTableOffset);
565     if (Iter != StmtListToDie.end()) {
566       ++NumDebugLineErrors;
567       error() << "two compile unit DIEs, "
568               << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
569               << format("0x%08" PRIx32, Die.getOffset())
570               << ", have the same DW_AT_stmt_list section offset:\n";
571       Iter->second.dump(OS, 0, DumpOpts);
572       Die.dump(OS, 0, DumpOpts);
573       OS << '\n';
574       // Already verified this line table before, no need to do it again.
575       continue;
576     }
577     StmtListToDie[LineTableOffset] = Die;
578   }
579 }
580 
581 void DWARFVerifier::verifyDebugLineRows() {
582   for (const auto &CU : DCtx.compile_units()) {
583     auto Die = CU->getUnitDIE();
584     auto LineTable = DCtx.getLineTableForUnit(CU.get());
585     // If there is no line table we will have created an error in the
586     // .debug_info verifier or in verifyDebugLineStmtOffsets().
587     if (!LineTable)
588       continue;
589 
590     // Verify prologue.
591     uint32_t MaxFileIndex = LineTable->Prologue.FileNames.size();
592     uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
593     uint32_t FileIndex = 1;
594     StringMap<uint16_t> FullPathMap;
595     for (const auto &FileName : LineTable->Prologue.FileNames) {
596       // Verify directory index.
597       if (FileName.DirIdx > MaxDirIndex) {
598         ++NumDebugLineErrors;
599         error() << ".debug_line["
600                 << format("0x%08" PRIx64,
601                           *toSectionOffset(Die.find(DW_AT_stmt_list)))
602                 << "].prologue.file_names[" << FileIndex
603                 << "].dir_idx contains an invalid index: " << FileName.DirIdx
604                 << "\n";
605       }
606 
607       // Check file paths for duplicates.
608       std::string FullPath;
609       const bool HasFullPath = LineTable->getFileNameByIndex(
610           FileIndex, CU->getCompilationDir(),
611           DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FullPath);
612       assert(HasFullPath && "Invalid index?");
613       (void)HasFullPath;
614       auto It = FullPathMap.find(FullPath);
615       if (It == FullPathMap.end())
616         FullPathMap[FullPath] = FileIndex;
617       else if (It->second != FileIndex) {
618         warn() << ".debug_line["
619                << format("0x%08" PRIx64,
620                          *toSectionOffset(Die.find(DW_AT_stmt_list)))
621                << "].prologue.file_names[" << FileIndex
622                << "] is a duplicate of file_names[" << It->second << "]\n";
623       }
624 
625       FileIndex++;
626     }
627 
628     // Verify rows.
629     uint64_t PrevAddress = 0;
630     uint32_t RowIndex = 0;
631     for (const auto &Row : LineTable->Rows) {
632       // Verify row address.
633       if (Row.Address < PrevAddress) {
634         ++NumDebugLineErrors;
635         error() << ".debug_line["
636                 << format("0x%08" PRIx64,
637                           *toSectionOffset(Die.find(DW_AT_stmt_list)))
638                 << "] row[" << RowIndex
639                 << "] decreases in address from previous row:\n";
640 
641         DWARFDebugLine::Row::dumpTableHeader(OS);
642         if (RowIndex > 0)
643           LineTable->Rows[RowIndex - 1].dump(OS);
644         Row.dump(OS);
645         OS << '\n';
646       }
647 
648       // Verify file index.
649       if (Row.File > MaxFileIndex) {
650         ++NumDebugLineErrors;
651         error() << ".debug_line["
652                 << format("0x%08" PRIx64,
653                           *toSectionOffset(Die.find(DW_AT_stmt_list)))
654                 << "][" << RowIndex << "] has invalid file index " << Row.File
655                 << " (valid values are [1," << MaxFileIndex << "]):\n";
656         DWARFDebugLine::Row::dumpTableHeader(OS);
657         Row.dump(OS);
658         OS << '\n';
659       }
660       if (Row.EndSequence)
661         PrevAddress = 0;
662       else
663         PrevAddress = Row.Address;
664       ++RowIndex;
665     }
666   }
667 }
668 
669 bool DWARFVerifier::handleDebugLine() {
670   NumDebugLineErrors = 0;
671   OS << "Verifying .debug_line...\n";
672   verifyDebugLineStmtOffsets();
673   verifyDebugLineRows();
674   return NumDebugLineErrors == 0;
675 }
676 
677 unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
678                                               DataExtractor *StrData,
679                                               const char *SectionName) {
680   unsigned NumErrors = 0;
681   DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
682                                       DCtx.isLittleEndian(), 0);
683   AppleAcceleratorTable AccelTable(AccelSectionData, *StrData);
684 
685   OS << "Verifying " << SectionName << "...\n";
686 
687   // Verify that the fixed part of the header is not too short.
688   if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
689     error() << "Section is too small to fit a section header.\n";
690     return 1;
691   }
692 
693   // Verify that the section is not too short.
694   if (Error E = AccelTable.extract()) {
695     error() << toString(std::move(E)) << '\n';
696     return 1;
697   }
698 
699   // Verify that all buckets have a valid hash index or are empty.
700   uint32_t NumBuckets = AccelTable.getNumBuckets();
701   uint32_t NumHashes = AccelTable.getNumHashes();
702 
703   uint32_t BucketsOffset =
704       AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
705   uint32_t HashesBase = BucketsOffset + NumBuckets * 4;
706   uint32_t OffsetsBase = HashesBase + NumHashes * 4;
707   for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
708     uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
709     if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
710       error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
711                         HashIdx);
712       ++NumErrors;
713     }
714   }
715   uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
716   if (NumAtoms == 0) {
717     error() << "No atoms: failed to read HashData.\n";
718     return 1;
719   }
720   if (!AccelTable.validateForms()) {
721     error() << "Unsupported form: failed to read HashData.\n";
722     return 1;
723   }
724 
725   for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
726     uint32_t HashOffset = HashesBase + 4 * HashIdx;
727     uint32_t DataOffset = OffsetsBase + 4 * HashIdx;
728     uint32_t Hash = AccelSectionData.getU32(&HashOffset);
729     uint32_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
730     if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
731                                                      sizeof(uint64_t))) {
732       error() << format("Hash[%d] has invalid HashData offset: 0x%08x.\n",
733                         HashIdx, HashDataOffset);
734       ++NumErrors;
735     }
736 
737     uint32_t StrpOffset;
738     uint32_t StringOffset;
739     uint32_t StringCount = 0;
740     unsigned Offset;
741     unsigned Tag;
742     while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
743       const uint32_t NumHashDataObjects =
744           AccelSectionData.getU32(&HashDataOffset);
745       for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
746            ++HashDataIdx) {
747         std::tie(Offset, Tag) = AccelTable.readAtoms(HashDataOffset);
748         auto Die = DCtx.getDIEForOffset(Offset);
749         if (!Die) {
750           const uint32_t BucketIdx =
751               NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
752           StringOffset = StrpOffset;
753           const char *Name = StrData->getCStr(&StringOffset);
754           if (!Name)
755             Name = "<NULL>";
756 
757           error() << format(
758               "%s Bucket[%d] Hash[%d] = 0x%08x "
759               "Str[%u] = 0x%08x "
760               "DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n",
761               SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
762               HashDataIdx, Offset, Name);
763 
764           ++NumErrors;
765           continue;
766         }
767         if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
768           error() << "Tag " << dwarf::TagString(Tag)
769                   << " in accelerator table does not match Tag "
770                   << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
771                   << "].\n";
772           ++NumErrors;
773         }
774       }
775       ++StringCount;
776     }
777   }
778   return NumErrors;
779 }
780 
781 unsigned
782 DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
783   // A map from CU offset to the (first) Name Index offset which claims to index
784   // this CU.
785   DenseMap<uint32_t, uint32_t> CUMap;
786   const uint32_t NotIndexed = std::numeric_limits<uint32_t>::max();
787 
788   CUMap.reserve(DCtx.getNumCompileUnits());
789   for (const auto &CU : DCtx.compile_units())
790     CUMap[CU->getOffset()] = NotIndexed;
791 
792   unsigned NumErrors = 0;
793   for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
794     if (NI.getCUCount() == 0) {
795       error() << formatv("Name Index @ {0:x} does not index any CU\n",
796                          NI.getUnitOffset());
797       ++NumErrors;
798       continue;
799     }
800     for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
801       uint32_t Offset = NI.getCUOffset(CU);
802       auto Iter = CUMap.find(Offset);
803 
804       if (Iter == CUMap.end()) {
805         error() << formatv(
806             "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
807             NI.getUnitOffset(), Offset);
808         ++NumErrors;
809         continue;
810       }
811 
812       if (Iter->second != NotIndexed) {
813         error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
814                           "this CU is already indexed by Name Index @ {2:x}\n",
815                           NI.getUnitOffset(), Offset, Iter->second);
816         continue;
817       }
818       Iter->second = NI.getUnitOffset();
819     }
820   }
821 
822   for (const auto &KV : CUMap) {
823     if (KV.second == NotIndexed)
824       warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
825   }
826 
827   return NumErrors;
828 }
829 
830 unsigned
831 DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
832                                       const DataExtractor &StrData) {
833   struct BucketInfo {
834     uint32_t Bucket;
835     uint32_t Index;
836 
837     constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
838         : Bucket(Bucket), Index(Index) {}
839     bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; };
840   };
841 
842   uint32_t NumErrors = 0;
843   if (NI.getBucketCount() == 0) {
844     warn() << formatv("Name Index @ {0:x} does not contain a hash table.\n",
845                       NI.getUnitOffset());
846     return NumErrors;
847   }
848 
849   // Build up a list of (Bucket, Index) pairs. We use this later to verify that
850   // each Name is reachable from the appropriate bucket.
851   std::vector<BucketInfo> BucketStarts;
852   BucketStarts.reserve(NI.getBucketCount() + 1);
853   for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End; ++Bucket) {
854     uint32_t Index = NI.getBucketArrayEntry(Bucket);
855     if (Index > NI.getNameCount()) {
856       error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
857                          "value {2}. Valid range is [0, {3}].\n",
858                          Bucket, NI.getUnitOffset(), Index, NI.getNameCount());
859       ++NumErrors;
860       continue;
861     }
862     if (Index > 0)
863       BucketStarts.emplace_back(Bucket, Index);
864   }
865 
866   // If there were any buckets with invalid values, skip further checks as they
867   // will likely produce many errors which will only confuse the actual root
868   // problem.
869   if (NumErrors > 0)
870     return NumErrors;
871 
872   // Sort the list in the order of increasing "Index" entries.
873   array_pod_sort(BucketStarts.begin(), BucketStarts.end());
874 
875   // Insert a sentinel entry at the end, so we can check that the end of the
876   // table is covered in the loop below.
877   BucketStarts.emplace_back(NI.getBucketCount(), NI.getNameCount() + 1);
878 
879   // Loop invariant: NextUncovered is the (1-based) index of the first Name
880   // which is not reachable by any of the buckets we processed so far (and
881   // hasn't been reported as uncovered).
882   uint32_t NextUncovered = 1;
883   for (const BucketInfo &B : BucketStarts) {
884     // Under normal circumstances B.Index be equal to NextUncovered, but it can
885     // be less if a bucket points to names which are already known to be in some
886     // bucket we processed earlier. In that case, we won't trigger this error,
887     // but report the mismatched hash value error instead. (We know the hash
888     // will not match because we have already verified that the name's hash
889     // puts it into the previous bucket.)
890     if (B.Index > NextUncovered) {
891       error() << formatv("Name Index @ {0:x}: Name table entries [{1}, {2}] "
892                          "are not covered by the hash table.\n",
893                          NI.getUnitOffset(), NextUncovered, B.Index - 1);
894       ++NumErrors;
895     }
896     uint32_t Idx = B.Index;
897 
898     // The rest of the checks apply only to non-sentinel entries.
899     if (B.Bucket == NI.getBucketCount())
900       break;
901 
902     // This triggers if a non-empty bucket points to a name with a mismatched
903     // hash. Clients are likely to interpret this as an empty bucket, because a
904     // mismatched hash signals the end of a bucket, but if this is indeed an
905     // empty bucket, the producer should have signalled this by marking the
906     // bucket as empty.
907     uint32_t FirstHash = NI.getHashArrayEntry(Idx);
908     if (FirstHash % NI.getBucketCount() != B.Bucket) {
909       error() << formatv(
910           "Name Index @ {0:x}: Bucket {1} is not empty but points to a "
911           "mismatched hash value {2:x} (belonging to bucket {3}).\n",
912           NI.getUnitOffset(), B.Bucket, FirstHash,
913           FirstHash % NI.getBucketCount());
914       ++NumErrors;
915     }
916 
917     // This find the end of this bucket and also verifies that all the hashes in
918     // this bucket are correct by comparing the stored hashes to the ones we
919     // compute ourselves.
920     while (Idx <= NI.getNameCount()) {
921       uint32_t Hash = NI.getHashArrayEntry(Idx);
922       if (Hash % NI.getBucketCount() != B.Bucket)
923         break;
924 
925       auto NTE = NI.getNameTableEntry(Idx);
926       const char *Str = StrData.getCStr(&NTE.StringOffset);
927       if (caseFoldingDjbHash(Str) != Hash) {
928         error() << formatv("Name Index @ {0:x}: String ({1}) at index {2} "
929                            "hashes to {3:x}, but "
930                            "the Name Index hash is {4:x}\n",
931                            NI.getUnitOffset(), Str, Idx,
932                            caseFoldingDjbHash(Str), Hash);
933         ++NumErrors;
934       }
935 
936       ++Idx;
937     }
938     NextUncovered = std::max(NextUncovered, Idx);
939   }
940   return NumErrors;
941 }
942 
943 unsigned DWARFVerifier::verifyNameIndexAttribute(
944     const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr,
945     DWARFDebugNames::AttributeEncoding AttrEnc) {
946   StringRef FormName = dwarf::FormEncodingString(AttrEnc.Form);
947   if (FormName.empty()) {
948     error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
949                        "unknown form: {3}.\n",
950                        NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
951                        AttrEnc.Form);
952     return 1;
953   }
954 
955   if (AttrEnc.Index == DW_IDX_type_hash) {
956     if (AttrEnc.Form != dwarf::DW_FORM_data8) {
957       error() << formatv(
958           "NameIndex @ {0:x}: Abbreviation {1:x}: DW_IDX_type_hash "
959           "uses an unexpected form {2} (should be {3}).\n",
960           NI.getUnitOffset(), Abbr.Code, AttrEnc.Form, dwarf::DW_FORM_data8);
961       return 1;
962     }
963   }
964 
965   // A list of known index attributes and their expected form classes.
966   // DW_IDX_type_hash is handled specially in the check above, as it has a
967   // specific form (not just a form class) we should expect.
968   struct FormClassTable {
969     dwarf::Index Index;
970     DWARFFormValue::FormClass Class;
971     StringLiteral ClassName;
972   };
973   static constexpr FormClassTable Table[] = {
974       {dwarf::DW_IDX_compile_unit, DWARFFormValue::FC_Constant, {"constant"}},
975       {dwarf::DW_IDX_type_unit, DWARFFormValue::FC_Constant, {"constant"}},
976       {dwarf::DW_IDX_die_offset, DWARFFormValue::FC_Reference, {"reference"}},
977       {dwarf::DW_IDX_parent, DWARFFormValue::FC_Constant, {"constant"}},
978   };
979 
980   ArrayRef<FormClassTable> TableRef(Table);
981   auto Iter = find_if(TableRef, [AttrEnc](const FormClassTable &T) {
982     return T.Index == AttrEnc.Index;
983   });
984   if (Iter == TableRef.end()) {
985     warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains an "
986                       "unknown index attribute: {2}.\n",
987                       NI.getUnitOffset(), Abbr.Code, AttrEnc.Index);
988     return 0;
989   }
990 
991   if (!DWARFFormValue(AttrEnc.Form).isFormClass(Iter->Class)) {
992     error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
993                        "unexpected form {3} (expected form class {4}).\n",
994                        NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
995                        AttrEnc.Form, Iter->ClassName);
996     return 1;
997   }
998   return 0;
999 }
1000 
1001 unsigned
1002 DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
1003   if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
1004     warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
1005                       "not currently supported.\n",
1006                       NI.getUnitOffset());
1007     return 0;
1008   }
1009 
1010   unsigned NumErrors = 0;
1011   for (const auto &Abbrev : NI.getAbbrevs()) {
1012     StringRef TagName = dwarf::TagString(Abbrev.Tag);
1013     if (TagName.empty()) {
1014       warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} references an "
1015                         "unknown tag: {2}.\n",
1016                         NI.getUnitOffset(), Abbrev.Code, Abbrev.Tag);
1017     }
1018     SmallSet<unsigned, 5> Attributes;
1019     for (const auto &AttrEnc : Abbrev.Attributes) {
1020       if (!Attributes.insert(AttrEnc.Index).second) {
1021         error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains "
1022                            "multiple {2} attributes.\n",
1023                            NI.getUnitOffset(), Abbrev.Code, AttrEnc.Index);
1024         ++NumErrors;
1025         continue;
1026       }
1027       NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
1028     }
1029 
1030     if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
1031       error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
1032                          "and abbreviation {1:x} has no {2} attribute.\n",
1033                          NI.getUnitOffset(), Abbrev.Code,
1034                          dwarf::DW_IDX_compile_unit);
1035       ++NumErrors;
1036     }
1037     if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
1038       error() << formatv(
1039           "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
1040           NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
1041       ++NumErrors;
1042     }
1043   }
1044   return NumErrors;
1045 }
1046 
1047 static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE) {
1048   SmallVector<StringRef, 2> Result;
1049   if (const char *Str = DIE.getName(DINameKind::ShortName))
1050     Result.emplace_back(Str);
1051   else if (DIE.getTag() == dwarf::DW_TAG_namespace)
1052     Result.emplace_back("(anonymous namespace)");
1053 
1054   if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
1055     if (Result.empty() || Result[0] != Str)
1056       Result.emplace_back(Str);
1057   }
1058 
1059   return Result;
1060 }
1061 
1062 unsigned
1063 DWARFVerifier::verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
1064                                       uint32_t Name,
1065                                       const DataExtractor &StrData) {
1066   // Verifying type unit indexes not supported.
1067   if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
1068     return 0;
1069 
1070   DWARFDebugNames::NameTableEntry NTE = NI.getNameTableEntry(Name);
1071   const char *CStr = StrData.getCStr(&NTE.StringOffset);
1072   if (!CStr) {
1073     error() << formatv(
1074         "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
1075         NI.getUnitOffset(), Name);
1076     return 1;
1077   }
1078   StringRef Str(CStr);
1079 
1080   unsigned NumErrors = 0;
1081   unsigned NumEntries = 0;
1082   uint32_t EntryID = NTE.EntryOffset;
1083   Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NTE.EntryOffset);
1084   for (; EntryOr; ++NumEntries, EntryID = NTE.EntryOffset,
1085                                 EntryOr = NI.getEntry(&NTE.EntryOffset)) {
1086     uint32_t CUIndex = *EntryOr->getCUIndex();
1087     if (CUIndex > NI.getCUCount()) {
1088       error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
1089                          "invalid CU index ({2}).\n",
1090                          NI.getUnitOffset(), EntryID, CUIndex);
1091       ++NumErrors;
1092       continue;
1093     }
1094     uint32_t CUOffset = NI.getCUOffset(CUIndex);
1095     uint64_t DIEOffset = *EntryOr->getDIESectionOffset();
1096     DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
1097     if (!DIE) {
1098       error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
1099                          "non-existing DIE @ {2:x}.\n",
1100                          NI.getUnitOffset(), EntryID, DIEOffset);
1101       ++NumErrors;
1102       continue;
1103     }
1104     if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
1105       error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
1106                          "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
1107                          NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
1108                          DIE.getDwarfUnit()->getOffset());
1109       ++NumErrors;
1110     }
1111     if (DIE.getTag() != EntryOr->tag()) {
1112       error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
1113                          "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1114                          NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
1115                          DIE.getTag());
1116       ++NumErrors;
1117     }
1118 
1119     auto EntryNames = getNames(DIE);
1120     if (!is_contained(EntryNames, Str)) {
1121       error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
1122                          "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1123                          NI.getUnitOffset(), EntryID, DIEOffset, Str,
1124                          make_range(EntryNames.begin(), EntryNames.end()));
1125     }
1126   }
1127   handleAllErrors(EntryOr.takeError(),
1128                   [&](const DWARFDebugNames::SentinelError &) {
1129                     if (NumEntries > 0)
1130                       return;
1131                     error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
1132                                        "not associated with any entries.\n",
1133                                        NI.getUnitOffset(), Name, Str);
1134                     ++NumErrors;
1135                   },
1136                   [&](const ErrorInfoBase &Info) {
1137                     error() << formatv(
1138                         "Name Index @ {0:x}: Name {1} ({2}): {3}\n",
1139                         NI.getUnitOffset(), Name, Str, Info.message());
1140                     ++NumErrors;
1141                   });
1142   return NumErrors;
1143 }
1144 
1145 unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
1146                                          const DataExtractor &StrData) {
1147   unsigned NumErrors = 0;
1148   DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
1149                                       DCtx.isLittleEndian(), 0);
1150   DWARFDebugNames AccelTable(AccelSectionData, StrData);
1151 
1152   OS << "Verifying .debug_names...\n";
1153 
1154   // This verifies that we can read individual name indices and their
1155   // abbreviation tables.
1156   if (Error E = AccelTable.extract()) {
1157     error() << toString(std::move(E)) << '\n';
1158     return 1;
1159   }
1160 
1161   NumErrors += verifyDebugNamesCULists(AccelTable);
1162   for (const auto &NI : AccelTable)
1163     NumErrors += verifyNameIndexBuckets(NI, StrData);
1164   for (const auto &NI : AccelTable)
1165     NumErrors += verifyNameIndexAbbrevs(NI);
1166 
1167   // Don't attempt Entry validation if any of the previous checks found errors
1168   if (NumErrors > 0)
1169     return NumErrors;
1170   for (const auto &NI : AccelTable)
1171     for (uint64_t Name = 1; Name <= NI.getNameCount(); ++Name)
1172       NumErrors += verifyNameIndexEntries(NI, Name, StrData);
1173 
1174   return NumErrors;
1175 }
1176 
1177 bool DWARFVerifier::handleAccelTables() {
1178   const DWARFObject &D = DCtx.getDWARFObj();
1179   DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
1180   unsigned NumErrors = 0;
1181   if (!D.getAppleNamesSection().Data.empty())
1182     NumErrors +=
1183         verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData, ".apple_names");
1184   if (!D.getAppleTypesSection().Data.empty())
1185     NumErrors +=
1186         verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData, ".apple_types");
1187   if (!D.getAppleNamespacesSection().Data.empty())
1188     NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
1189                                   ".apple_namespaces");
1190   if (!D.getAppleObjCSection().Data.empty())
1191     NumErrors +=
1192         verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData, ".apple_objc");
1193 
1194   if (!D.getDebugNamesSection().Data.empty())
1195     NumErrors += verifyDebugNames(D.getDebugNamesSection(), StrData);
1196   return NumErrors == 0;
1197 }
1198 
1199 raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
1200 
1201 raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
1202 
1203 raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
1204