xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1 //===- DWARFVerifier.cpp --------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
9 #include "llvm/ADT/IntervalMap.h"
10 #include "llvm/ADT/SmallSet.h"
11 #include "llvm/BinaryFormat/Dwarf.h"
12 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
13 #include "llvm/DebugInfo/DWARF/DWARFAttribute.h"
14 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
15 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
16 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
17 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
21 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
22 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
23 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
24 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
25 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
26 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
27 #include "llvm/Object/Error.h"
28 #include "llvm/Support/DJB.h"
29 #include "llvm/Support/Error.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/FormatVariadic.h"
32 #include "llvm/Support/WithColor.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <map>
35 #include <set>
36 #include <vector>
37 
38 using namespace llvm;
39 using namespace dwarf;
40 using namespace object;
41 
42 namespace llvm {
43 class DWARFDebugInfoEntry;
44 }
45 
46 std::optional<DWARFAddressRange>
47 DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
48   auto Begin = Ranges.begin();
49   auto End = Ranges.end();
50   auto Pos = std::lower_bound(Begin, End, R);
51 
52   if (Pos != End) {
53     DWARFAddressRange Range(*Pos);
54     if (Pos->merge(R))
55       return Range;
56   }
57   if (Pos != Begin) {
58     auto Iter = Pos - 1;
59     DWARFAddressRange Range(*Iter);
60     if (Iter->merge(R))
61       return Range;
62   }
63 
64   Ranges.insert(Pos, R);
65   return std::nullopt;
66 }
67 
68 DWARFVerifier::DieRangeInfo::die_range_info_iterator
69 DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) {
70   if (RI.Ranges.empty())
71     return Children.end();
72 
73   auto End = Children.end();
74   auto Iter = Children.begin();
75   while (Iter != End) {
76     if (Iter->intersects(RI))
77       return Iter;
78     ++Iter;
79   }
80   Children.insert(RI);
81   return Children.end();
82 }
83 
84 bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const {
85   auto I1 = Ranges.begin(), E1 = Ranges.end();
86   auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
87   if (I2 == E2)
88     return true;
89 
90   DWARFAddressRange R = *I2;
91   while (I1 != E1) {
92     bool Covered = I1->LowPC <= R.LowPC;
93     if (R.LowPC == R.HighPC || (Covered && R.HighPC <= I1->HighPC)) {
94       if (++I2 == E2)
95         return true;
96       R = *I2;
97       continue;
98     }
99     if (!Covered)
100       return false;
101     if (R.LowPC < I1->HighPC)
102       R.LowPC = I1->HighPC;
103     ++I1;
104   }
105   return false;
106 }
107 
108 bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
109   auto I1 = Ranges.begin(), E1 = Ranges.end();
110   auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
111   while (I1 != E1 && I2 != E2) {
112     if (I1->intersects(*I2))
113       return true;
114     if (I1->LowPC < I2->LowPC)
115       ++I1;
116     else
117       ++I2;
118   }
119   return false;
120 }
121 
122 bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
123                                      uint64_t *Offset, unsigned UnitIndex,
124                                      uint8_t &UnitType, bool &isUnitDWARF64) {
125   uint64_t AbbrOffset, Length;
126   uint8_t AddrSize = 0;
127   uint16_t Version;
128   bool Success = true;
129 
130   bool ValidLength = false;
131   bool ValidVersion = false;
132   bool ValidAddrSize = false;
133   bool ValidType = true;
134   bool ValidAbbrevOffset = true;
135 
136   uint64_t OffsetStart = *Offset;
137   DwarfFormat Format;
138   std::tie(Length, Format) = DebugInfoData.getInitialLength(Offset);
139   isUnitDWARF64 = Format == DWARF64;
140   Version = DebugInfoData.getU16(Offset);
141 
142   if (Version >= 5) {
143     UnitType = DebugInfoData.getU8(Offset);
144     AddrSize = DebugInfoData.getU8(Offset);
145     AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
146     ValidType = dwarf::isUnitType(UnitType);
147   } else {
148     UnitType = 0;
149     AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
150     AddrSize = DebugInfoData.getU8(Offset);
151   }
152 
153   Expected<const DWARFAbbreviationDeclarationSet *> AbbrevSetOrErr =
154       DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset);
155   if (!AbbrevSetOrErr) {
156     ValidAbbrevOffset = false;
157     // FIXME: A problematic debug_abbrev section is reported below in the form
158     // of a `note:`. We should propagate this error there (or elsewhere) to
159     // avoid losing the specific problem with the debug_abbrev section.
160     consumeError(AbbrevSetOrErr.takeError());
161   }
162 
163   ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
164   ValidVersion = DWARFContext::isSupportedVersion(Version);
165   ValidAddrSize = DWARFContext::isAddressSizeSupported(AddrSize);
166   if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
167       !ValidType) {
168     Success = false;
169     error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex,
170                       OffsetStart);
171     if (!ValidLength)
172       note() << "The length for this unit is too "
173                 "large for the .debug_info provided.\n";
174     if (!ValidVersion)
175       note() << "The 16 bit unit header version is not valid.\n";
176     if (!ValidType)
177       note() << "The unit type encoding is not valid.\n";
178     if (!ValidAbbrevOffset)
179       note() << "The offset into the .debug_abbrev section is "
180                 "not valid.\n";
181     if (!ValidAddrSize)
182       note() << "The address size is unsupported.\n";
183   }
184   *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4);
185   return Success;
186 }
187 
188 bool DWARFVerifier::verifyName(const DWARFDie &Die) {
189   // FIXME Add some kind of record of which DIE names have already failed and
190   // don't bother checking a DIE that uses an already failed DIE.
191 
192   std::string ReconstructedName;
193   raw_string_ostream OS(ReconstructedName);
194   std::string OriginalFullName;
195   Die.getFullName(OS, &OriginalFullName);
196   OS.flush();
197   if (OriginalFullName.empty() || OriginalFullName == ReconstructedName)
198     return false;
199 
200   error() << "Simplified template DW_AT_name could not be reconstituted:\n"
201           << formatv("         original: {0}\n"
202                      "    reconstituted: {1}\n",
203                      OriginalFullName, ReconstructedName);
204   dump(Die) << '\n';
205   dump(Die.getDwarfUnit()->getUnitDIE()) << '\n';
206   return true;
207 }
208 
209 unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit,
210                                            ReferenceMap &UnitLocalReferences,
211                                            ReferenceMap &CrossUnitReferences) {
212   unsigned NumUnitErrors = 0;
213   unsigned NumDies = Unit.getNumDIEs();
214   for (unsigned I = 0; I < NumDies; ++I) {
215     auto Die = Unit.getDIEAtIndex(I);
216 
217     if (Die.getTag() == DW_TAG_null)
218       continue;
219 
220     for (auto AttrValue : Die.attributes()) {
221       NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
222       NumUnitErrors += verifyDebugInfoForm(Die, AttrValue, UnitLocalReferences,
223                                            CrossUnitReferences);
224     }
225 
226     NumUnitErrors += verifyName(Die);
227 
228     if (Die.hasChildren()) {
229       if (Die.getFirstChild().isValid() &&
230           Die.getFirstChild().getTag() == DW_TAG_null) {
231         warn() << dwarf::TagString(Die.getTag())
232                << " has DW_CHILDREN_yes but DIE has no children: ";
233         Die.dump(OS);
234       }
235     }
236 
237     NumUnitErrors += verifyDebugInfoCallSite(Die);
238   }
239 
240   DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
241   if (!Die) {
242     error() << "Compilation unit without DIE.\n";
243     NumUnitErrors++;
244     return NumUnitErrors;
245   }
246 
247   if (!dwarf::isUnitType(Die.getTag())) {
248     error() << "Compilation unit root DIE is not a unit DIE: "
249             << dwarf::TagString(Die.getTag()) << ".\n";
250     NumUnitErrors++;
251   }
252 
253   uint8_t UnitType = Unit.getUnitType();
254   if (!DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
255     error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
256             << ") and root DIE (" << dwarf::TagString(Die.getTag())
257             << ") do not match.\n";
258     NumUnitErrors++;
259   }
260 
261   //  According to DWARF Debugging Information Format Version 5,
262   //  3.1.2 Skeleton Compilation Unit Entries:
263   //  "A skeleton compilation unit has no children."
264   if (Die.getTag() == dwarf::DW_TAG_skeleton_unit && Die.hasChildren()) {
265     error() << "Skeleton compilation unit has children.\n";
266     NumUnitErrors++;
267   }
268 
269   DieRangeInfo RI;
270   NumUnitErrors += verifyDieRanges(Die, RI);
271 
272   return NumUnitErrors;
273 }
274 
275 unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
276   if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site)
277     return 0;
278 
279   DWARFDie Curr = Die.getParent();
280   for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Die.getParent()) {
281     if (Curr.getTag() == DW_TAG_inlined_subroutine) {
282       error() << "Call site entry nested within inlined subroutine:";
283       Curr.dump(OS);
284       return 1;
285     }
286   }
287 
288   if (!Curr.isValid()) {
289     error() << "Call site entry not nested within a valid subprogram:";
290     Die.dump(OS);
291     return 1;
292   }
293 
294   std::optional<DWARFFormValue> CallAttr = Curr.find(
295       {DW_AT_call_all_calls, DW_AT_call_all_source_calls,
296        DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites,
297        DW_AT_GNU_all_source_call_sites, DW_AT_GNU_all_tail_call_sites});
298   if (!CallAttr) {
299     error() << "Subprogram with call site entry has no DW_AT_call attribute:";
300     Curr.dump(OS);
301     Die.dump(OS, /*indent*/ 1);
302     return 1;
303   }
304 
305   return 0;
306 }
307 
308 unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
309   if (!Abbrev)
310     return 0;
311 
312   Expected<const DWARFAbbreviationDeclarationSet *> AbbrDeclsOrErr =
313       Abbrev->getAbbreviationDeclarationSet(0);
314   if (!AbbrDeclsOrErr) {
315     error() << toString(AbbrDeclsOrErr.takeError()) << "\n";
316     return 1;
317   }
318 
319   const auto *AbbrDecls = *AbbrDeclsOrErr;
320   unsigned NumErrors = 0;
321   for (auto AbbrDecl : *AbbrDecls) {
322     SmallDenseSet<uint16_t> AttributeSet;
323     for (auto Attribute : AbbrDecl.attributes()) {
324       auto Result = AttributeSet.insert(Attribute.Attr);
325       if (!Result.second) {
326         error() << "Abbreviation declaration contains multiple "
327                 << AttributeString(Attribute.Attr) << " attributes.\n";
328         AbbrDecl.dump(OS);
329         ++NumErrors;
330       }
331     }
332   }
333   return NumErrors;
334 }
335 
336 bool DWARFVerifier::handleDebugAbbrev() {
337   OS << "Verifying .debug_abbrev...\n";
338 
339   const DWARFObject &DObj = DCtx.getDWARFObj();
340   unsigned NumErrors = 0;
341   if (!DObj.getAbbrevSection().empty())
342     NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev());
343   if (!DObj.getAbbrevDWOSection().empty())
344     NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO());
345 
346   return NumErrors == 0;
347 }
348 
349 unsigned DWARFVerifier::verifyUnits(const DWARFUnitVector &Units) {
350   unsigned NumDebugInfoErrors = 0;
351   ReferenceMap CrossUnitReferences;
352 
353   unsigned Index = 1;
354   for (const auto &Unit : Units) {
355     OS << "Verifying unit: " << Index << " / " << Units.getNumUnits();
356     if (const char* Name = Unit->getUnitDIE(true).getShortName())
357       OS << ", \"" << Name << '\"';
358     OS << '\n';
359     OS.flush();
360     ReferenceMap UnitLocalReferences;
361     NumDebugInfoErrors +=
362         verifyUnitContents(*Unit, UnitLocalReferences, CrossUnitReferences);
363     NumDebugInfoErrors += verifyDebugInfoReferences(
364         UnitLocalReferences, [&](uint64_t Offset) { return Unit.get(); });
365     ++Index;
366   }
367 
368   NumDebugInfoErrors += verifyDebugInfoReferences(
369       CrossUnitReferences, [&](uint64_t Offset) -> DWARFUnit * {
370         if (DWARFUnit *U = Units.getUnitForOffset(Offset))
371           return U;
372         return nullptr;
373       });
374 
375   return NumDebugInfoErrors;
376 }
377 
378 unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S) {
379   const DWARFObject &DObj = DCtx.getDWARFObj();
380   DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
381   unsigned NumDebugInfoErrors = 0;
382   uint64_t Offset = 0, UnitIdx = 0;
383   uint8_t UnitType = 0;
384   bool isUnitDWARF64 = false;
385   bool isHeaderChainValid = true;
386   bool hasDIE = DebugInfoData.isValidOffset(Offset);
387   DWARFUnitVector TypeUnitVector;
388   DWARFUnitVector CompileUnitVector;
389   /// A map that tracks all references (converted absolute references) so we
390   /// can verify each reference points to a valid DIE and not an offset that
391   /// lies between to valid DIEs.
392   ReferenceMap CrossUnitReferences;
393   while (hasDIE) {
394     if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
395                           isUnitDWARF64)) {
396       isHeaderChainValid = false;
397       if (isUnitDWARF64)
398         break;
399     }
400     hasDIE = DebugInfoData.isValidOffset(Offset);
401     ++UnitIdx;
402   }
403   if (UnitIdx == 0 && !hasDIE) {
404     warn() << "Section is empty.\n";
405     isHeaderChainValid = true;
406   }
407   if (!isHeaderChainValid)
408     ++NumDebugInfoErrors;
409   return NumDebugInfoErrors;
410 }
411 
412 unsigned DWARFVerifier::verifyIndex(StringRef Name,
413                                     DWARFSectionKind InfoColumnKind,
414                                     StringRef IndexStr) {
415   if (IndexStr.empty())
416     return 0;
417   OS << "Verifying " << Name << "...\n";
418   DWARFUnitIndex Index(InfoColumnKind);
419   DataExtractor D(IndexStr, DCtx.isLittleEndian(), 0);
420   if (!Index.parse(D))
421     return 1;
422   using MapType = IntervalMap<uint64_t, uint64_t>;
423   MapType::Allocator Alloc;
424   std::vector<std::unique_ptr<MapType>> Sections(Index.getColumnKinds().size());
425   for (const DWARFUnitIndex::Entry &E : Index.getRows()) {
426     uint64_t Sig = E.getSignature();
427     if (!E.getContributions())
428       continue;
429     for (auto E : enumerate(
430              InfoColumnKind == DW_SECT_INFO
431                  ? ArrayRef(E.getContributions(), Index.getColumnKinds().size())
432                  : ArrayRef(E.getContribution(), 1))) {
433       const DWARFUnitIndex::Entry::SectionContribution &SC = E.value();
434       int Col = E.index();
435       if (SC.getLength() == 0)
436         continue;
437       if (!Sections[Col])
438         Sections[Col] = std::make_unique<MapType>(Alloc);
439       auto &M = *Sections[Col];
440       auto I = M.find(SC.getOffset());
441       if (I != M.end() && I.start() < (SC.getOffset() + SC.getLength())) {
442         error() << llvm::formatv(
443             "overlapping index entries for entries {0:x16} "
444             "and {1:x16} for column {2}\n",
445             *I, Sig, toString(Index.getColumnKinds()[Col]));
446         return 1;
447       }
448       M.insert(SC.getOffset(), SC.getOffset() + SC.getLength() - 1, Sig);
449     }
450   }
451 
452   return 0;
453 }
454 
455 bool DWARFVerifier::handleDebugCUIndex() {
456   return verifyIndex(".debug_cu_index", DWARFSectionKind::DW_SECT_INFO,
457                      DCtx.getDWARFObj().getCUIndexSection()) == 0;
458 }
459 
460 bool DWARFVerifier::handleDebugTUIndex() {
461   return verifyIndex(".debug_tu_index", DWARFSectionKind::DW_SECT_EXT_TYPES,
462                      DCtx.getDWARFObj().getTUIndexSection()) == 0;
463 }
464 
465 bool DWARFVerifier::handleDebugInfo() {
466   const DWARFObject &DObj = DCtx.getDWARFObj();
467   unsigned NumErrors = 0;
468 
469   OS << "Verifying .debug_info Unit Header Chain...\n";
470   DObj.forEachInfoSections([&](const DWARFSection &S) {
471     NumErrors += verifyUnitSection(S);
472   });
473 
474   OS << "Verifying .debug_types Unit Header Chain...\n";
475   DObj.forEachTypesSections([&](const DWARFSection &S) {
476     NumErrors += verifyUnitSection(S);
477   });
478 
479   OS << "Verifying non-dwo Units...\n";
480   NumErrors += verifyUnits(DCtx.getNormalUnitsVector());
481 
482   OS << "Verifying dwo Units...\n";
483   NumErrors += verifyUnits(DCtx.getDWOUnitsVector());
484   return NumErrors == 0;
485 }
486 
487 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
488                                         DieRangeInfo &ParentRI) {
489   unsigned NumErrors = 0;
490 
491   if (!Die.isValid())
492     return NumErrors;
493 
494   DWARFUnit *Unit = Die.getDwarfUnit();
495 
496   auto RangesOrError = Die.getAddressRanges();
497   if (!RangesOrError) {
498     // FIXME: Report the error.
499     if (!Unit->isDWOUnit())
500       ++NumErrors;
501     llvm::consumeError(RangesOrError.takeError());
502     return NumErrors;
503   }
504 
505   const DWARFAddressRangesVector &Ranges = RangesOrError.get();
506   // Build RI for this DIE and check that ranges within this DIE do not
507   // overlap.
508   DieRangeInfo RI(Die);
509 
510   // TODO support object files better
511   //
512   // Some object file formats (i.e. non-MachO) support COMDAT.  ELF in
513   // particular does so by placing each function into a section.  The DWARF data
514   // for the function at that point uses a section relative DW_FORM_addrp for
515   // the DW_AT_low_pc and a DW_FORM_data4 for the offset as the DW_AT_high_pc.
516   // In such a case, when the Die is the CU, the ranges will overlap, and we
517   // will flag valid conflicting ranges as invalid.
518   //
519   // For such targets, we should read the ranges from the CU and partition them
520   // by the section id.  The ranges within a particular section should be
521   // disjoint, although the ranges across sections may overlap.  We would map
522   // the child die to the entity that it references and the section with which
523   // it is associated.  The child would then be checked against the range
524   // information for the associated section.
525   //
526   // For now, simply elide the range verification for the CU DIEs if we are
527   // processing an object file.
528 
529   if (!IsObjectFile || IsMachOObject || Die.getTag() != DW_TAG_compile_unit) {
530     bool DumpDieAfterError = false;
531     for (const auto &Range : Ranges) {
532       if (!Range.valid()) {
533         ++NumErrors;
534         error() << "Invalid address range " << Range << "\n";
535         DumpDieAfterError = true;
536         continue;
537       }
538 
539       // Verify that ranges don't intersect and also build up the DieRangeInfo
540       // address ranges. Don't break out of the loop below early, or we will
541       // think this DIE doesn't have all of the address ranges it is supposed
542       // to have. Compile units often have DW_AT_ranges that can contain one or
543       // more dead stripped address ranges which tend to all be at the same
544       // address: 0 or -1.
545       if (auto PrevRange = RI.insert(Range)) {
546         ++NumErrors;
547         error() << "DIE has overlapping ranges in DW_AT_ranges attribute: "
548                 << *PrevRange << " and " << Range << '\n';
549         DumpDieAfterError = true;
550       }
551     }
552     if (DumpDieAfterError)
553       dump(Die, 2) << '\n';
554   }
555 
556   // Verify that children don't intersect.
557   const auto IntersectingChild = ParentRI.insert(RI);
558   if (IntersectingChild != ParentRI.Children.end()) {
559     ++NumErrors;
560     error() << "DIEs have overlapping address ranges:";
561     dump(Die);
562     dump(IntersectingChild->Die) << '\n';
563   }
564 
565   // Verify that ranges are contained within their parent.
566   bool ShouldBeContained = !RI.Ranges.empty() && !ParentRI.Ranges.empty() &&
567                            !(Die.getTag() == DW_TAG_subprogram &&
568                              ParentRI.Die.getTag() == DW_TAG_subprogram);
569   if (ShouldBeContained && !ParentRI.contains(RI)) {
570     ++NumErrors;
571     error() << "DIE address ranges are not contained in its parent's ranges:";
572     dump(ParentRI.Die);
573     dump(Die, 2) << '\n';
574   }
575 
576   // Recursively check children.
577   for (DWARFDie Child : Die)
578     NumErrors += verifyDieRanges(Child, RI);
579 
580   return NumErrors;
581 }
582 
583 unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
584                                                  DWARFAttribute &AttrValue) {
585   unsigned NumErrors = 0;
586   auto ReportError = [&](const Twine &TitleMsg) {
587     ++NumErrors;
588     error() << TitleMsg << '\n';
589     dump(Die) << '\n';
590   };
591 
592   const DWARFObject &DObj = DCtx.getDWARFObj();
593   DWARFUnit *U = Die.getDwarfUnit();
594   const auto Attr = AttrValue.Attr;
595   switch (Attr) {
596   case DW_AT_ranges:
597     // Make sure the offset in the DW_AT_ranges attribute is valid.
598     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
599       unsigned DwarfVersion = U->getVersion();
600       const DWARFSection &RangeSection = DwarfVersion < 5
601                                              ? DObj.getRangesSection()
602                                              : DObj.getRnglistsSection();
603       if (U->isDWOUnit() && RangeSection.Data.empty())
604         break;
605       if (*SectionOffset >= RangeSection.Data.size())
606         ReportError(
607             "DW_AT_ranges offset is beyond " +
608             StringRef(DwarfVersion < 5 ? ".debug_ranges" : ".debug_rnglists") +
609             " bounds: " + llvm::formatv("{0:x8}", *SectionOffset));
610       break;
611     }
612     ReportError("DIE has invalid DW_AT_ranges encoding:");
613     break;
614   case DW_AT_stmt_list:
615     // Make sure the offset in the DW_AT_stmt_list attribute is valid.
616     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
617       if (*SectionOffset >= U->getLineSection().Data.size())
618         ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
619                     llvm::formatv("{0:x8}", *SectionOffset));
620       break;
621     }
622     ReportError("DIE has invalid DW_AT_stmt_list encoding:");
623     break;
624   case DW_AT_location: {
625     // FIXME: It might be nice if there's a way to walk location expressions
626     // without trying to resolve the address ranges - it'd be a more efficient
627     // API (since the API is currently unnecessarily resolving addresses for
628     // this use case which only wants to validate the expressions themselves) &
629     // then the expressions could be validated even if the addresses can't be
630     // resolved.
631     // That sort of API would probably look like a callback "for each
632     // expression" with some way to lazily resolve the address ranges when
633     // needed (& then the existing API used here could be built on top of that -
634     // using the callback API to build the data structure and return it).
635     if (Expected<std::vector<DWARFLocationExpression>> Loc =
636             Die.getLocations(DW_AT_location)) {
637       for (const auto &Entry : *Loc) {
638         DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
639         DWARFExpression Expression(Data, U->getAddressByteSize(),
640                                    U->getFormParams().Format);
641         bool Error =
642             any_of(Expression, [](const DWARFExpression::Operation &Op) {
643               return Op.isError();
644             });
645         if (Error || !Expression.verify(U))
646           ReportError("DIE contains invalid DWARF expression:");
647       }
648     } else if (Error Err = handleErrors(
649                    Loc.takeError(), [&](std::unique_ptr<ResolverError> E) {
650                      return U->isDWOUnit() ? Error::success()
651                                            : Error(std::move(E));
652                    }))
653       ReportError(toString(std::move(Err)));
654     break;
655   }
656   case DW_AT_specification:
657   case DW_AT_abstract_origin: {
658     if (auto ReferencedDie = Die.getAttributeValueAsReferencedDie(Attr)) {
659       auto DieTag = Die.getTag();
660       auto RefTag = ReferencedDie.getTag();
661       if (DieTag == RefTag)
662         break;
663       if (DieTag == DW_TAG_inlined_subroutine && RefTag == DW_TAG_subprogram)
664         break;
665       if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
666         break;
667       // This might be reference to a function declaration.
668       if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram)
669         break;
670       ReportError("DIE with tag " + TagString(DieTag) + " has " +
671                   AttributeString(Attr) +
672                   " that points to DIE with "
673                   "incompatible tag " +
674                   TagString(RefTag));
675     }
676     break;
677   }
678   case DW_AT_type: {
679     DWARFDie TypeDie = Die.getAttributeValueAsReferencedDie(DW_AT_type);
680     if (TypeDie && !isType(TypeDie.getTag())) {
681       ReportError("DIE has " + AttributeString(Attr) +
682                   " with incompatible tag " + TagString(TypeDie.getTag()));
683     }
684     break;
685   }
686   case DW_AT_call_file:
687   case DW_AT_decl_file: {
688     if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) {
689       if (U->isDWOUnit() && !U->isTypeUnit())
690         break;
691       const auto *LT = U->getContext().getLineTableForUnit(U);
692       if (LT) {
693         if (!LT->hasFileAtIndex(*FileIdx)) {
694           bool IsZeroIndexed = LT->Prologue.getVersion() >= 5;
695           if (std::optional<uint64_t> LastFileIdx =
696                   LT->getLastValidFileIndex()) {
697             ReportError("DIE has " + AttributeString(Attr) +
698                         " with an invalid file index " +
699                         llvm::formatv("{0}", *FileIdx) +
700                         " (valid values are [" + (IsZeroIndexed ? "0-" : "1-") +
701                         llvm::formatv("{0}", *LastFileIdx) + "])");
702           } else {
703             ReportError("DIE has " + AttributeString(Attr) +
704                         " with an invalid file index " +
705                         llvm::formatv("{0}", *FileIdx) +
706                         " (the file table in the prologue is empty)");
707           }
708         }
709       } else {
710         ReportError("DIE has " + AttributeString(Attr) +
711                     " that references a file with index " +
712                     llvm::formatv("{0}", *FileIdx) +
713                     " and the compile unit has no line table");
714       }
715     } else {
716       ReportError("DIE has " + AttributeString(Attr) +
717                   " with invalid encoding");
718     }
719     break;
720   }
721   case DW_AT_call_line:
722   case DW_AT_decl_line: {
723     if (!AttrValue.Value.getAsUnsignedConstant()) {
724       ReportError("DIE has " + AttributeString(Attr) +
725                   " with invalid encoding");
726     }
727     break;
728   }
729   default:
730     break;
731   }
732   return NumErrors;
733 }
734 
735 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
736                                             DWARFAttribute &AttrValue,
737                                             ReferenceMap &LocalReferences,
738                                             ReferenceMap &CrossUnitReferences) {
739   auto DieCU = Die.getDwarfUnit();
740   unsigned NumErrors = 0;
741   const auto Form = AttrValue.Value.getForm();
742   switch (Form) {
743   case DW_FORM_ref1:
744   case DW_FORM_ref2:
745   case DW_FORM_ref4:
746   case DW_FORM_ref8:
747   case DW_FORM_ref_udata: {
748     // Verify all CU relative references are valid CU offsets.
749     std::optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
750     assert(RefVal);
751     if (RefVal) {
752       auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
753       auto CUOffset = AttrValue.Value.getRawUValue();
754       if (CUOffset >= CUSize) {
755         ++NumErrors;
756         error() << FormEncodingString(Form) << " CU offset "
757                 << format("0x%08" PRIx64, CUOffset)
758                 << " is invalid (must be less than CU size of "
759                 << format("0x%08" PRIx64, CUSize) << "):\n";
760         Die.dump(OS, 0, DumpOpts);
761         dump(Die) << '\n';
762       } else {
763         // Valid reference, but we will verify it points to an actual
764         // DIE later.
765         LocalReferences[*RefVal].insert(Die.getOffset());
766       }
767     }
768     break;
769   }
770   case DW_FORM_ref_addr: {
771     // Verify all absolute DIE references have valid offsets in the
772     // .debug_info section.
773     std::optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
774     assert(RefVal);
775     if (RefVal) {
776       if (*RefVal >= DieCU->getInfoSection().Data.size()) {
777         ++NumErrors;
778         error() << "DW_FORM_ref_addr offset beyond .debug_info "
779                    "bounds:\n";
780         dump(Die) << '\n';
781       } else {
782         // Valid reference, but we will verify it points to an actual
783         // DIE later.
784         CrossUnitReferences[*RefVal].insert(Die.getOffset());
785       }
786     }
787     break;
788   }
789   case DW_FORM_strp:
790   case DW_FORM_strx:
791   case DW_FORM_strx1:
792   case DW_FORM_strx2:
793   case DW_FORM_strx3:
794   case DW_FORM_strx4:
795   case DW_FORM_line_strp: {
796     if (Error E = AttrValue.Value.getAsCString().takeError()) {
797       ++NumErrors;
798       error() << toString(std::move(E)) << ":\n";
799       dump(Die) << '\n';
800     }
801     break;
802   }
803   default:
804     break;
805   }
806   return NumErrors;
807 }
808 
809 unsigned DWARFVerifier::verifyDebugInfoReferences(
810     const ReferenceMap &References,
811     llvm::function_ref<DWARFUnit *(uint64_t)> GetUnitForOffset) {
812   auto GetDIEForOffset = [&](uint64_t Offset) {
813     if (DWARFUnit *U = GetUnitForOffset(Offset))
814       return U->getDIEForOffset(Offset);
815     return DWARFDie();
816   };
817   unsigned NumErrors = 0;
818   for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
819        References) {
820     if (GetDIEForOffset(Pair.first))
821       continue;
822     ++NumErrors;
823     error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
824             << ". Offset is in between DIEs:\n";
825     for (auto Offset : Pair.second)
826       dump(GetDIEForOffset(Offset)) << '\n';
827     OS << "\n";
828   }
829   return NumErrors;
830 }
831 
832 void DWARFVerifier::verifyDebugLineStmtOffsets() {
833   std::map<uint64_t, DWARFDie> StmtListToDie;
834   for (const auto &CU : DCtx.compile_units()) {
835     auto Die = CU->getUnitDIE();
836     // Get the attribute value as a section offset. No need to produce an
837     // error here if the encoding isn't correct because we validate this in
838     // the .debug_info verifier.
839     auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
840     if (!StmtSectionOffset)
841       continue;
842     const uint64_t LineTableOffset = *StmtSectionOffset;
843     auto LineTable = DCtx.getLineTableForUnit(CU.get());
844     if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
845       if (!LineTable) {
846         ++NumDebugLineErrors;
847         error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
848                 << "] was not able to be parsed for CU:\n";
849         dump(Die) << '\n';
850         continue;
851       }
852     } else {
853       // Make sure we don't get a valid line table back if the offset is wrong.
854       assert(LineTable == nullptr);
855       // Skip this line table as it isn't valid. No need to create an error
856       // here because we validate this in the .debug_info verifier.
857       continue;
858     }
859     auto Iter = StmtListToDie.find(LineTableOffset);
860     if (Iter != StmtListToDie.end()) {
861       ++NumDebugLineErrors;
862       error() << "two compile unit DIEs, "
863               << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
864               << format("0x%08" PRIx64, Die.getOffset())
865               << ", have the same DW_AT_stmt_list section offset:\n";
866       dump(Iter->second);
867       dump(Die) << '\n';
868       // Already verified this line table before, no need to do it again.
869       continue;
870     }
871     StmtListToDie[LineTableOffset] = Die;
872   }
873 }
874 
875 void DWARFVerifier::verifyDebugLineRows() {
876   for (const auto &CU : DCtx.compile_units()) {
877     auto Die = CU->getUnitDIE();
878     auto LineTable = DCtx.getLineTableForUnit(CU.get());
879     // If there is no line table we will have created an error in the
880     // .debug_info verifier or in verifyDebugLineStmtOffsets().
881     if (!LineTable)
882       continue;
883 
884     // Verify prologue.
885     bool isDWARF5 = LineTable->Prologue.getVersion() >= 5;
886     uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
887     uint32_t MinFileIndex = isDWARF5 ? 0 : 1;
888     uint32_t FileIndex = MinFileIndex;
889     StringMap<uint16_t> FullPathMap;
890     for (const auto &FileName : LineTable->Prologue.FileNames) {
891       // Verify directory index.
892       if (FileName.DirIdx > MaxDirIndex) {
893         ++NumDebugLineErrors;
894         error() << ".debug_line["
895                 << format("0x%08" PRIx64,
896                           *toSectionOffset(Die.find(DW_AT_stmt_list)))
897                 << "].prologue.file_names[" << FileIndex
898                 << "].dir_idx contains an invalid index: " << FileName.DirIdx
899                 << "\n";
900       }
901 
902       // Check file paths for duplicates.
903       std::string FullPath;
904       const bool HasFullPath = LineTable->getFileNameByIndex(
905           FileIndex, CU->getCompilationDir(),
906           DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FullPath);
907       assert(HasFullPath && "Invalid index?");
908       (void)HasFullPath;
909       auto It = FullPathMap.find(FullPath);
910       if (It == FullPathMap.end())
911         FullPathMap[FullPath] = FileIndex;
912       else if (It->second != FileIndex) {
913         warn() << ".debug_line["
914                << format("0x%08" PRIx64,
915                          *toSectionOffset(Die.find(DW_AT_stmt_list)))
916                << "].prologue.file_names[" << FileIndex
917                << "] is a duplicate of file_names[" << It->second << "]\n";
918       }
919 
920       FileIndex++;
921     }
922 
923     // Verify rows.
924     uint64_t PrevAddress = 0;
925     uint32_t RowIndex = 0;
926     for (const auto &Row : LineTable->Rows) {
927       // Verify row address.
928       if (Row.Address.Address < PrevAddress) {
929         ++NumDebugLineErrors;
930         error() << ".debug_line["
931                 << format("0x%08" PRIx64,
932                           *toSectionOffset(Die.find(DW_AT_stmt_list)))
933                 << "] row[" << RowIndex
934                 << "] decreases in address from previous row:\n";
935 
936         DWARFDebugLine::Row::dumpTableHeader(OS, 0);
937         if (RowIndex > 0)
938           LineTable->Rows[RowIndex - 1].dump(OS);
939         Row.dump(OS);
940         OS << '\n';
941       }
942 
943       // If the prologue contains no file names and the line table has only one
944       // row, do not verify the file index, this is a line table of an empty
945       // file with an end_sequence, but the DWARF standard sets the file number
946       // to 1 by default, otherwise verify file index.
947       if ((LineTable->Prologue.FileNames.size() ||
948            LineTable->Rows.size() != 1) &&
949           !LineTable->hasFileAtIndex(Row.File)) {
950         ++NumDebugLineErrors;
951         error() << ".debug_line["
952                 << format("0x%08" PRIx64,
953                           *toSectionOffset(Die.find(DW_AT_stmt_list)))
954                 << "][" << RowIndex << "] has invalid file index " << Row.File
955                 << " (valid values are [" << MinFileIndex << ','
956                 << LineTable->Prologue.FileNames.size()
957                 << (isDWARF5 ? ")" : "]") << "):\n";
958         DWARFDebugLine::Row::dumpTableHeader(OS, 0);
959         Row.dump(OS);
960         OS << '\n';
961       }
962       if (Row.EndSequence)
963         PrevAddress = 0;
964       else
965         PrevAddress = Row.Address.Address;
966       ++RowIndex;
967     }
968   }
969 }
970 
971 DWARFVerifier::DWARFVerifier(raw_ostream &S, DWARFContext &D,
972                              DIDumpOptions DumpOpts)
973     : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
974       IsMachOObject(false) {
975   if (const auto *F = DCtx.getDWARFObj().getFile()) {
976     IsObjectFile = F->isRelocatableObject();
977     IsMachOObject = F->isMachO();
978   }
979 }
980 
981 bool DWARFVerifier::handleDebugLine() {
982   NumDebugLineErrors = 0;
983   OS << "Verifying .debug_line...\n";
984   verifyDebugLineStmtOffsets();
985   verifyDebugLineRows();
986   return NumDebugLineErrors == 0;
987 }
988 
989 unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
990                                               DataExtractor *StrData,
991                                               const char *SectionName) {
992   unsigned NumErrors = 0;
993   DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
994                                       DCtx.isLittleEndian(), 0);
995   AppleAcceleratorTable AccelTable(AccelSectionData, *StrData);
996 
997   OS << "Verifying " << SectionName << "...\n";
998 
999   // Verify that the fixed part of the header is not too short.
1000   if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
1001     error() << "Section is too small to fit a section header.\n";
1002     return 1;
1003   }
1004 
1005   // Verify that the section is not too short.
1006   if (Error E = AccelTable.extract()) {
1007     error() << toString(std::move(E)) << '\n';
1008     return 1;
1009   }
1010 
1011   // Verify that all buckets have a valid hash index or are empty.
1012   uint32_t NumBuckets = AccelTable.getNumBuckets();
1013   uint32_t NumHashes = AccelTable.getNumHashes();
1014 
1015   uint64_t BucketsOffset =
1016       AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
1017   uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
1018   uint64_t OffsetsBase = HashesBase + NumHashes * 4;
1019   for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
1020     uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
1021     if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
1022       error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
1023                         HashIdx);
1024       ++NumErrors;
1025     }
1026   }
1027   uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
1028   if (NumAtoms == 0) {
1029     error() << "No atoms: failed to read HashData.\n";
1030     return 1;
1031   }
1032   if (!AccelTable.validateForms()) {
1033     error() << "Unsupported form: failed to read HashData.\n";
1034     return 1;
1035   }
1036 
1037   for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
1038     uint64_t HashOffset = HashesBase + 4 * HashIdx;
1039     uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
1040     uint32_t Hash = AccelSectionData.getU32(&HashOffset);
1041     uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
1042     if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
1043                                                      sizeof(uint64_t))) {
1044       error() << format("Hash[%d] has invalid HashData offset: "
1045                         "0x%08" PRIx64 ".\n",
1046                         HashIdx, HashDataOffset);
1047       ++NumErrors;
1048     }
1049 
1050     uint64_t StrpOffset;
1051     uint64_t StringOffset;
1052     uint32_t StringCount = 0;
1053     uint64_t Offset;
1054     unsigned Tag;
1055     while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
1056       const uint32_t NumHashDataObjects =
1057           AccelSectionData.getU32(&HashDataOffset);
1058       for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
1059            ++HashDataIdx) {
1060         std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
1061         auto Die = DCtx.getDIEForOffset(Offset);
1062         if (!Die) {
1063           const uint32_t BucketIdx =
1064               NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
1065           StringOffset = StrpOffset;
1066           const char *Name = StrData->getCStr(&StringOffset);
1067           if (!Name)
1068             Name = "<NULL>";
1069 
1070           error() << format(
1071               "%s Bucket[%d] Hash[%d] = 0x%08x "
1072               "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
1073               "is not a valid DIE offset for \"%s\".\n",
1074               SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
1075               HashDataIdx, Offset, Name);
1076 
1077           ++NumErrors;
1078           continue;
1079         }
1080         if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
1081           error() << "Tag " << dwarf::TagString(Tag)
1082                   << " in accelerator table does not match Tag "
1083                   << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
1084                   << "].\n";
1085           ++NumErrors;
1086         }
1087       }
1088       ++StringCount;
1089     }
1090   }
1091   return NumErrors;
1092 }
1093 
1094 unsigned
1095 DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
1096   // A map from CU offset to the (first) Name Index offset which claims to index
1097   // this CU.
1098   DenseMap<uint64_t, uint64_t> CUMap;
1099   const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
1100 
1101   CUMap.reserve(DCtx.getNumCompileUnits());
1102   for (const auto &CU : DCtx.compile_units())
1103     CUMap[CU->getOffset()] = NotIndexed;
1104 
1105   unsigned NumErrors = 0;
1106   for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
1107     if (NI.getCUCount() == 0) {
1108       error() << formatv("Name Index @ {0:x} does not index any CU\n",
1109                          NI.getUnitOffset());
1110       ++NumErrors;
1111       continue;
1112     }
1113     for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
1114       uint64_t Offset = NI.getCUOffset(CU);
1115       auto Iter = CUMap.find(Offset);
1116 
1117       if (Iter == CUMap.end()) {
1118         error() << formatv(
1119             "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
1120             NI.getUnitOffset(), Offset);
1121         ++NumErrors;
1122         continue;
1123       }
1124 
1125       if (Iter->second != NotIndexed) {
1126         error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
1127                            "this CU is already indexed by Name Index @ {2:x}\n",
1128                            NI.getUnitOffset(), Offset, Iter->second);
1129         continue;
1130       }
1131       Iter->second = NI.getUnitOffset();
1132     }
1133   }
1134 
1135   for (const auto &KV : CUMap) {
1136     if (KV.second == NotIndexed)
1137       warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
1138   }
1139 
1140   return NumErrors;
1141 }
1142 
1143 unsigned
1144 DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
1145                                       const DataExtractor &StrData) {
1146   struct BucketInfo {
1147     uint32_t Bucket;
1148     uint32_t Index;
1149 
1150     constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
1151         : Bucket(Bucket), Index(Index) {}
1152     bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
1153   };
1154 
1155   uint32_t NumErrors = 0;
1156   if (NI.getBucketCount() == 0) {
1157     warn() << formatv("Name Index @ {0:x} does not contain a hash table.\n",
1158                       NI.getUnitOffset());
1159     return NumErrors;
1160   }
1161 
1162   // Build up a list of (Bucket, Index) pairs. We use this later to verify that
1163   // each Name is reachable from the appropriate bucket.
1164   std::vector<BucketInfo> BucketStarts;
1165   BucketStarts.reserve(NI.getBucketCount() + 1);
1166   for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End; ++Bucket) {
1167     uint32_t Index = NI.getBucketArrayEntry(Bucket);
1168     if (Index > NI.getNameCount()) {
1169       error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
1170                          "value {2}. Valid range is [0, {3}].\n",
1171                          Bucket, NI.getUnitOffset(), Index, NI.getNameCount());
1172       ++NumErrors;
1173       continue;
1174     }
1175     if (Index > 0)
1176       BucketStarts.emplace_back(Bucket, Index);
1177   }
1178 
1179   // If there were any buckets with invalid values, skip further checks as they
1180   // will likely produce many errors which will only confuse the actual root
1181   // problem.
1182   if (NumErrors > 0)
1183     return NumErrors;
1184 
1185   // Sort the list in the order of increasing "Index" entries.
1186   array_pod_sort(BucketStarts.begin(), BucketStarts.end());
1187 
1188   // Insert a sentinel entry at the end, so we can check that the end of the
1189   // table is covered in the loop below.
1190   BucketStarts.emplace_back(NI.getBucketCount(), NI.getNameCount() + 1);
1191 
1192   // Loop invariant: NextUncovered is the (1-based) index of the first Name
1193   // which is not reachable by any of the buckets we processed so far (and
1194   // hasn't been reported as uncovered).
1195   uint32_t NextUncovered = 1;
1196   for (const BucketInfo &B : BucketStarts) {
1197     // Under normal circumstances B.Index be equal to NextUncovered, but it can
1198     // be less if a bucket points to names which are already known to be in some
1199     // bucket we processed earlier. In that case, we won't trigger this error,
1200     // but report the mismatched hash value error instead. (We know the hash
1201     // will not match because we have already verified that the name's hash
1202     // puts it into the previous bucket.)
1203     if (B.Index > NextUncovered) {
1204       error() << formatv("Name Index @ {0:x}: Name table entries [{1}, {2}] "
1205                          "are not covered by the hash table.\n",
1206                          NI.getUnitOffset(), NextUncovered, B.Index - 1);
1207       ++NumErrors;
1208     }
1209     uint32_t Idx = B.Index;
1210 
1211     // The rest of the checks apply only to non-sentinel entries.
1212     if (B.Bucket == NI.getBucketCount())
1213       break;
1214 
1215     // This triggers if a non-empty bucket points to a name with a mismatched
1216     // hash. Clients are likely to interpret this as an empty bucket, because a
1217     // mismatched hash signals the end of a bucket, but if this is indeed an
1218     // empty bucket, the producer should have signalled this by marking the
1219     // bucket as empty.
1220     uint32_t FirstHash = NI.getHashArrayEntry(Idx);
1221     if (FirstHash % NI.getBucketCount() != B.Bucket) {
1222       error() << formatv(
1223           "Name Index @ {0:x}: Bucket {1} is not empty but points to a "
1224           "mismatched hash value {2:x} (belonging to bucket {3}).\n",
1225           NI.getUnitOffset(), B.Bucket, FirstHash,
1226           FirstHash % NI.getBucketCount());
1227       ++NumErrors;
1228     }
1229 
1230     // This find the end of this bucket and also verifies that all the hashes in
1231     // this bucket are correct by comparing the stored hashes to the ones we
1232     // compute ourselves.
1233     while (Idx <= NI.getNameCount()) {
1234       uint32_t Hash = NI.getHashArrayEntry(Idx);
1235       if (Hash % NI.getBucketCount() != B.Bucket)
1236         break;
1237 
1238       const char *Str = NI.getNameTableEntry(Idx).getString();
1239       if (caseFoldingDjbHash(Str) != Hash) {
1240         error() << formatv("Name Index @ {0:x}: String ({1}) at index {2} "
1241                            "hashes to {3:x}, but "
1242                            "the Name Index hash is {4:x}\n",
1243                            NI.getUnitOffset(), Str, Idx,
1244                            caseFoldingDjbHash(Str), Hash);
1245         ++NumErrors;
1246       }
1247 
1248       ++Idx;
1249     }
1250     NextUncovered = std::max(NextUncovered, Idx);
1251   }
1252   return NumErrors;
1253 }
1254 
1255 unsigned DWARFVerifier::verifyNameIndexAttribute(
1256     const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr,
1257     DWARFDebugNames::AttributeEncoding AttrEnc) {
1258   StringRef FormName = dwarf::FormEncodingString(AttrEnc.Form);
1259   if (FormName.empty()) {
1260     error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
1261                        "unknown form: {3}.\n",
1262                        NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
1263                        AttrEnc.Form);
1264     return 1;
1265   }
1266 
1267   if (AttrEnc.Index == DW_IDX_type_hash) {
1268     if (AttrEnc.Form != dwarf::DW_FORM_data8) {
1269       error() << formatv(
1270           "NameIndex @ {0:x}: Abbreviation {1:x}: DW_IDX_type_hash "
1271           "uses an unexpected form {2} (should be {3}).\n",
1272           NI.getUnitOffset(), Abbr.Code, AttrEnc.Form, dwarf::DW_FORM_data8);
1273       return 1;
1274     }
1275   }
1276 
1277   // A list of known index attributes and their expected form classes.
1278   // DW_IDX_type_hash is handled specially in the check above, as it has a
1279   // specific form (not just a form class) we should expect.
1280   struct FormClassTable {
1281     dwarf::Index Index;
1282     DWARFFormValue::FormClass Class;
1283     StringLiteral ClassName;
1284   };
1285   static constexpr FormClassTable Table[] = {
1286       {dwarf::DW_IDX_compile_unit, DWARFFormValue::FC_Constant, {"constant"}},
1287       {dwarf::DW_IDX_type_unit, DWARFFormValue::FC_Constant, {"constant"}},
1288       {dwarf::DW_IDX_die_offset, DWARFFormValue::FC_Reference, {"reference"}},
1289       {dwarf::DW_IDX_parent, DWARFFormValue::FC_Constant, {"constant"}},
1290   };
1291 
1292   ArrayRef<FormClassTable> TableRef(Table);
1293   auto Iter = find_if(TableRef, [AttrEnc](const FormClassTable &T) {
1294     return T.Index == AttrEnc.Index;
1295   });
1296   if (Iter == TableRef.end()) {
1297     warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains an "
1298                       "unknown index attribute: {2}.\n",
1299                       NI.getUnitOffset(), Abbr.Code, AttrEnc.Index);
1300     return 0;
1301   }
1302 
1303   if (!DWARFFormValue(AttrEnc.Form).isFormClass(Iter->Class)) {
1304     error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
1305                        "unexpected form {3} (expected form class {4}).\n",
1306                        NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
1307                        AttrEnc.Form, Iter->ClassName);
1308     return 1;
1309   }
1310   return 0;
1311 }
1312 
1313 unsigned
1314 DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
1315   if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
1316     warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
1317                       "not currently supported.\n",
1318                       NI.getUnitOffset());
1319     return 0;
1320   }
1321 
1322   unsigned NumErrors = 0;
1323   for (const auto &Abbrev : NI.getAbbrevs()) {
1324     StringRef TagName = dwarf::TagString(Abbrev.Tag);
1325     if (TagName.empty()) {
1326       warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} references an "
1327                         "unknown tag: {2}.\n",
1328                         NI.getUnitOffset(), Abbrev.Code, Abbrev.Tag);
1329     }
1330     SmallSet<unsigned, 5> Attributes;
1331     for (const auto &AttrEnc : Abbrev.Attributes) {
1332       if (!Attributes.insert(AttrEnc.Index).second) {
1333         error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains "
1334                            "multiple {2} attributes.\n",
1335                            NI.getUnitOffset(), Abbrev.Code, AttrEnc.Index);
1336         ++NumErrors;
1337         continue;
1338       }
1339       NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
1340     }
1341 
1342     if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
1343       error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
1344                          "and abbreviation {1:x} has no {2} attribute.\n",
1345                          NI.getUnitOffset(), Abbrev.Code,
1346                          dwarf::DW_IDX_compile_unit);
1347       ++NumErrors;
1348     }
1349     if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
1350       error() << formatv(
1351           "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
1352           NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
1353       ++NumErrors;
1354     }
1355   }
1356   return NumErrors;
1357 }
1358 
1359 static SmallVector<std::string, 3> getNames(const DWARFDie &DIE,
1360                                             bool IncludeStrippedTemplateNames,
1361                                             bool IncludeObjCNames = true,
1362                                             bool IncludeLinkageName = true) {
1363   SmallVector<std::string, 3> Result;
1364   if (const char *Str = DIE.getShortName()) {
1365     StringRef Name(Str);
1366     Result.emplace_back(Name);
1367     if (IncludeStrippedTemplateNames) {
1368       if (std::optional<StringRef> StrippedName =
1369               StripTemplateParameters(Result.back()))
1370         // Convert to std::string and push; emplacing the StringRef may trigger
1371         // a vector resize which may destroy the StringRef memory.
1372         Result.push_back(StrippedName->str());
1373     }
1374 
1375     if (IncludeObjCNames) {
1376       if (std::optional<ObjCSelectorNames> ObjCNames =
1377               getObjCNamesIfSelector(Name)) {
1378         Result.emplace_back(ObjCNames->ClassName);
1379         Result.emplace_back(ObjCNames->Selector);
1380         if (ObjCNames->ClassNameNoCategory)
1381           Result.emplace_back(*ObjCNames->ClassNameNoCategory);
1382         if (ObjCNames->MethodNameNoCategory)
1383           Result.push_back(std::move(*ObjCNames->MethodNameNoCategory));
1384       }
1385     }
1386   } else if (DIE.getTag() == dwarf::DW_TAG_namespace)
1387     Result.emplace_back("(anonymous namespace)");
1388 
1389   if (IncludeLinkageName) {
1390     if (const char *Str = DIE.getLinkageName())
1391       Result.emplace_back(Str);
1392   }
1393 
1394   return Result;
1395 }
1396 
1397 unsigned DWARFVerifier::verifyNameIndexEntries(
1398     const DWARFDebugNames::NameIndex &NI,
1399     const DWARFDebugNames::NameTableEntry &NTE) {
1400   // Verifying type unit indexes not supported.
1401   if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
1402     return 0;
1403 
1404   const char *CStr = NTE.getString();
1405   if (!CStr) {
1406     error() << formatv(
1407         "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
1408         NI.getUnitOffset(), NTE.getIndex());
1409     return 1;
1410   }
1411   StringRef Str(CStr);
1412 
1413   unsigned NumErrors = 0;
1414   unsigned NumEntries = 0;
1415   uint64_t EntryID = NTE.getEntryOffset();
1416   uint64_t NextEntryID = EntryID;
1417   Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
1418   for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
1419                                 EntryOr = NI.getEntry(&NextEntryID)) {
1420     uint32_t CUIndex = *EntryOr->getCUIndex();
1421     if (CUIndex > NI.getCUCount()) {
1422       error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
1423                          "invalid CU index ({2}).\n",
1424                          NI.getUnitOffset(), EntryID, CUIndex);
1425       ++NumErrors;
1426       continue;
1427     }
1428     uint64_t CUOffset = NI.getCUOffset(CUIndex);
1429     uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
1430     DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
1431     if (!DIE) {
1432       error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
1433                          "non-existing DIE @ {2:x}.\n",
1434                          NI.getUnitOffset(), EntryID, DIEOffset);
1435       ++NumErrors;
1436       continue;
1437     }
1438     if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
1439       error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
1440                          "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
1441                          NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
1442                          DIE.getDwarfUnit()->getOffset());
1443       ++NumErrors;
1444     }
1445     if (DIE.getTag() != EntryOr->tag()) {
1446       error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
1447                          "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1448                          NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
1449                          DIE.getTag());
1450       ++NumErrors;
1451     }
1452 
1453     // We allow an extra name for functions: their name without any template
1454     // parameters.
1455     auto IncludeStrippedTemplateNames =
1456         DIE.getTag() == DW_TAG_subprogram ||
1457         DIE.getTag() == DW_TAG_inlined_subroutine;
1458     auto EntryNames = getNames(DIE, IncludeStrippedTemplateNames);
1459     if (!is_contained(EntryNames, Str)) {
1460       error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
1461                          "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1462                          NI.getUnitOffset(), EntryID, DIEOffset, Str,
1463                          make_range(EntryNames.begin(), EntryNames.end()));
1464       ++NumErrors;
1465     }
1466   }
1467   handleAllErrors(EntryOr.takeError(),
1468                   [&](const DWARFDebugNames::SentinelError &) {
1469                     if (NumEntries > 0)
1470                       return;
1471                     error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
1472                                        "not associated with any entries.\n",
1473                                        NI.getUnitOffset(), NTE.getIndex(), Str);
1474                     ++NumErrors;
1475                   },
1476                   [&](const ErrorInfoBase &Info) {
1477                     error()
1478                         << formatv("Name Index @ {0:x}: Name {1} ({2}): {3}\n",
1479                                    NI.getUnitOffset(), NTE.getIndex(), Str,
1480                                    Info.message());
1481                     ++NumErrors;
1482                   });
1483   return NumErrors;
1484 }
1485 
1486 static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
1487   Expected<std::vector<DWARFLocationExpression>> Loc =
1488       Die.getLocations(DW_AT_location);
1489   if (!Loc) {
1490     consumeError(Loc.takeError());
1491     return false;
1492   }
1493   DWARFUnit *U = Die.getDwarfUnit();
1494   for (const auto &Entry : *Loc) {
1495     DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
1496                        U->getAddressByteSize());
1497     DWARFExpression Expression(Data, U->getAddressByteSize(),
1498                                U->getFormParams().Format);
1499     bool IsInteresting =
1500         any_of(Expression, [](const DWARFExpression::Operation &Op) {
1501           return !Op.isError() && (Op.getCode() == DW_OP_addr ||
1502                                    Op.getCode() == DW_OP_form_tls_address ||
1503                                    Op.getCode() == DW_OP_GNU_push_tls_address);
1504         });
1505     if (IsInteresting)
1506       return true;
1507   }
1508   return false;
1509 }
1510 
1511 unsigned DWARFVerifier::verifyNameIndexCompleteness(
1512     const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI) {
1513 
1514   // First check, if the Die should be indexed. The code follows the DWARF v5
1515   // wording as closely as possible.
1516 
1517   // "All non-defining declarations (that is, debugging information entries
1518   // with a DW_AT_declaration attribute) are excluded."
1519   if (Die.find(DW_AT_declaration))
1520     return 0;
1521 
1522   // "DW_TAG_namespace debugging information entries without a DW_AT_name
1523   // attribute are included with the name “(anonymous namespace)”.
1524   // All other debugging information entries without a DW_AT_name attribute
1525   // are excluded."
1526   // "If a subprogram or inlined subroutine is included, and has a
1527   // DW_AT_linkage_name attribute, there will be an additional index entry for
1528   // the linkage name."
1529   auto IncludeLinkageName = Die.getTag() == DW_TAG_subprogram ||
1530                             Die.getTag() == DW_TAG_inlined_subroutine;
1531   // We *allow* stripped template names / ObjectiveC names as extra entries into
1532   // the table, but we don't *require* them to pass the completeness test.
1533   auto IncludeStrippedTemplateNames = false;
1534   auto IncludeObjCNames = false;
1535   auto EntryNames = getNames(Die, IncludeStrippedTemplateNames,
1536                              IncludeObjCNames, IncludeLinkageName);
1537   if (EntryNames.empty())
1538     return 0;
1539 
1540   // We deviate from the specification here, which says:
1541   // "The name index must contain an entry for each debugging information entry
1542   // that defines a named subprogram, label, variable, type, or namespace,
1543   // subject to ..."
1544   // Explicitly exclude all TAGs that we know shouldn't be indexed.
1545   switch (Die.getTag()) {
1546   // Compile units and modules have names but shouldn't be indexed.
1547   case DW_TAG_compile_unit:
1548   case DW_TAG_module:
1549     return 0;
1550 
1551   // Function and template parameters are not globally visible, so we shouldn't
1552   // index them.
1553   case DW_TAG_formal_parameter:
1554   case DW_TAG_template_value_parameter:
1555   case DW_TAG_template_type_parameter:
1556   case DW_TAG_GNU_template_parameter_pack:
1557   case DW_TAG_GNU_template_template_param:
1558     return 0;
1559 
1560   // Object members aren't globally visible.
1561   case DW_TAG_member:
1562     return 0;
1563 
1564   // According to a strict reading of the specification, enumerators should not
1565   // be indexed (and LLVM currently does not do that). However, this causes
1566   // problems for the debuggers, so we may need to reconsider this.
1567   case DW_TAG_enumerator:
1568     return 0;
1569 
1570   // Imported declarations should not be indexed according to the specification
1571   // and LLVM currently does not do that.
1572   case DW_TAG_imported_declaration:
1573     return 0;
1574 
1575   // "DW_TAG_subprogram, DW_TAG_inlined_subroutine, and DW_TAG_label debugging
1576   // information entries without an address attribute (DW_AT_low_pc,
1577   // DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded."
1578   case DW_TAG_subprogram:
1579   case DW_TAG_inlined_subroutine:
1580   case DW_TAG_label:
1581     if (Die.findRecursively(
1582             {DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_entry_pc}))
1583       break;
1584     return 0;
1585 
1586   // "DW_TAG_variable debugging information entries with a DW_AT_location
1587   // attribute that includes a DW_OP_addr or DW_OP_form_tls_address operator are
1588   // included; otherwise, they are excluded."
1589   //
1590   // LLVM extension: We also add DW_OP_GNU_push_tls_address to this list.
1591   case DW_TAG_variable:
1592     if (isVariableIndexable(Die, DCtx))
1593       break;
1594     return 0;
1595 
1596   default:
1597     break;
1598   }
1599 
1600   // Now we know that our Die should be present in the Index. Let's check if
1601   // that's the case.
1602   unsigned NumErrors = 0;
1603   uint64_t DieUnitOffset = Die.getOffset() - Die.getDwarfUnit()->getOffset();
1604   for (StringRef Name : EntryNames) {
1605     if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) {
1606           return E.getDIEUnitOffset() == DieUnitOffset;
1607         })) {
1608       error() << formatv("Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with "
1609                          "name {3} missing.\n",
1610                          NI.getUnitOffset(), Die.getOffset(), Die.getTag(),
1611                          Name);
1612       ++NumErrors;
1613     }
1614   }
1615   return NumErrors;
1616 }
1617 
1618 unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
1619                                          const DataExtractor &StrData) {
1620   unsigned NumErrors = 0;
1621   DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
1622                                       DCtx.isLittleEndian(), 0);
1623   DWARFDebugNames AccelTable(AccelSectionData, StrData);
1624 
1625   OS << "Verifying .debug_names...\n";
1626 
1627   // This verifies that we can read individual name indices and their
1628   // abbreviation tables.
1629   if (Error E = AccelTable.extract()) {
1630     error() << toString(std::move(E)) << '\n';
1631     return 1;
1632   }
1633 
1634   NumErrors += verifyDebugNamesCULists(AccelTable);
1635   for (const auto &NI : AccelTable)
1636     NumErrors += verifyNameIndexBuckets(NI, StrData);
1637   for (const auto &NI : AccelTable)
1638     NumErrors += verifyNameIndexAbbrevs(NI);
1639 
1640   // Don't attempt Entry validation if any of the previous checks found errors
1641   if (NumErrors > 0)
1642     return NumErrors;
1643   for (const auto &NI : AccelTable)
1644     for (const DWARFDebugNames::NameTableEntry &NTE : NI)
1645       NumErrors += verifyNameIndexEntries(NI, NTE);
1646 
1647   if (NumErrors > 0)
1648     return NumErrors;
1649 
1650   for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
1651     if (const DWARFDebugNames::NameIndex *NI =
1652             AccelTable.getCUNameIndex(U->getOffset())) {
1653       auto *CU = cast<DWARFCompileUnit>(U.get());
1654       for (const DWARFDebugInfoEntry &Die : CU->dies())
1655         NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
1656     }
1657   }
1658   return NumErrors;
1659 }
1660 
1661 bool DWARFVerifier::handleAccelTables() {
1662   const DWARFObject &D = DCtx.getDWARFObj();
1663   DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
1664   unsigned NumErrors = 0;
1665   if (!D.getAppleNamesSection().Data.empty())
1666     NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
1667                                        ".apple_names");
1668   if (!D.getAppleTypesSection().Data.empty())
1669     NumErrors += verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData,
1670                                        ".apple_types");
1671   if (!D.getAppleNamespacesSection().Data.empty())
1672     NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
1673                                        ".apple_namespaces");
1674   if (!D.getAppleObjCSection().Data.empty())
1675     NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
1676                                        ".apple_objc");
1677 
1678   if (!D.getNamesSection().Data.empty())
1679     NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
1680   return NumErrors == 0;
1681 }
1682 
1683 bool DWARFVerifier::handleDebugStrOffsets() {
1684   OS << "Verifying .debug_str_offsets...\n";
1685   const DWARFObject &DObj = DCtx.getDWARFObj();
1686   bool Success = true;
1687   Success &= verifyDebugStrOffsets(
1688       ".debug_str_offsets.dwo", DObj.getStrOffsetsDWOSection(),
1689       DObj.getStrDWOSection(), &DWARFObject::forEachInfoDWOSections);
1690   Success &= verifyDebugStrOffsets(
1691       ".debug_str_offsets", DObj.getStrOffsetsSection(), DObj.getStrSection(),
1692       &DWARFObject::forEachInfoSections);
1693   return Success;
1694 }
1695 
1696 bool DWARFVerifier::verifyDebugStrOffsets(
1697     StringRef SectionName, const DWARFSection &Section, StringRef StrData,
1698     void (DWARFObject::*VisitInfoSections)(
1699         function_ref<void(const DWARFSection &)>) const) {
1700   const DWARFObject &DObj = DCtx.getDWARFObj();
1701   uint16_t InfoVersion = 0;
1702   DwarfFormat InfoFormat = DwarfFormat::DWARF32;
1703   (DObj.*VisitInfoSections)([&](const DWARFSection &S) {
1704     if (InfoVersion)
1705       return;
1706     DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
1707     uint64_t Offset = 0;
1708     InfoFormat = DebugInfoData.getInitialLength(&Offset).second;
1709     InfoVersion = DebugInfoData.getU16(&Offset);
1710   });
1711 
1712   DWARFDataExtractor DA(DObj, Section, DCtx.isLittleEndian(), 0);
1713 
1714   DataExtractor::Cursor C(0);
1715   uint64_t NextUnit = 0;
1716   bool Success = true;
1717   while (C.seek(NextUnit), C.tell() < DA.getData().size()) {
1718     DwarfFormat Format;
1719     uint64_t Length;
1720     uint64_t StartOffset = C.tell();
1721     if (InfoVersion == 4) {
1722       Format = InfoFormat;
1723       Length = DA.getData().size();
1724       NextUnit = C.tell() + Length;
1725     } else {
1726       std::tie(Length, Format) = DA.getInitialLength(C);
1727       if (!C)
1728         break;
1729       if (C.tell() + Length > DA.getData().size()) {
1730         error() << formatv(
1731             "{0}: contribution {1:X}: length exceeds available space "
1732             "(contribution "
1733             "offset ({1:X}) + length field space ({2:X}) + length ({3:X}) == "
1734             "{4:X} > section size {5:X})\n",
1735             SectionName, StartOffset, C.tell() - StartOffset, Length,
1736             C.tell() + Length, DA.getData().size());
1737         Success = false;
1738         // Nothing more to do - no other contributions to try.
1739         break;
1740       }
1741       NextUnit = C.tell() + Length;
1742       uint8_t Version = DA.getU16(C);
1743       if (C && Version != 5) {
1744         error() << formatv("{0}: contribution {1:X}: invalid version {2}\n",
1745                            SectionName, StartOffset, Version);
1746         Success = false;
1747         // Can't parse the rest of this contribution, since we don't know the
1748         // version, but we can pick up with the next contribution.
1749         continue;
1750       }
1751       (void)DA.getU16(C); // padding
1752     }
1753     uint64_t OffsetByteSize = getDwarfOffsetByteSize(Format);
1754     DA.setAddressSize(OffsetByteSize);
1755     uint64_t Remainder = (Length - 4) % OffsetByteSize;
1756     if (Remainder != 0) {
1757       error() << formatv(
1758           "{0}: contribution {1:X}: invalid length ((length ({2:X}) "
1759           "- header (0x4)) % offset size {3:X} == {4:X} != 0)\n",
1760           SectionName, StartOffset, Length, OffsetByteSize, Remainder);
1761       Success = false;
1762     }
1763     for (uint64_t Index = 0; C && C.tell() + OffsetByteSize <= NextUnit; ++Index) {
1764       uint64_t OffOff = C.tell();
1765       uint64_t StrOff = DA.getAddress(C);
1766       // check StrOff refers to the start of a string
1767       if (StrOff == 0)
1768         continue;
1769       if (StrData.size() <= StrOff) {
1770         error() << formatv(
1771             "{0}: contribution {1:X}: index {2:X}: invalid string "
1772             "offset *{3:X} == {4:X}, is beyond the bounds of the string section of length {5:X}\n",
1773             SectionName, StartOffset, Index, OffOff, StrOff, StrData.size());
1774         continue;
1775       }
1776       if (StrData[StrOff - 1] == '\0')
1777         continue;
1778       error() << formatv("{0}: contribution {1:X}: index {2:X}: invalid string "
1779                          "offset *{3:X} == {4:X}, is neither zero nor "
1780                          "immediately following a null character\n",
1781                          SectionName, StartOffset, Index, OffOff, StrOff);
1782       Success = false;
1783     }
1784   }
1785 
1786   if (Error E = C.takeError()) {
1787     error() << SectionName << ": " << toString(std::move(E)) << '\n';
1788     return false;
1789   }
1790   return Success;
1791 }
1792 
1793 raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
1794 
1795 raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
1796 
1797 raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
1798 
1799 raw_ostream &DWARFVerifier::dump(const DWARFDie &Die, unsigned indent) const {
1800   Die.dump(OS, indent, DumpOpts);
1801   return OS;
1802 }
1803