LLVM  14.0.0git
DWARFVerifier.cpp
Go to the documentation of this file.
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 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/SmallSet.h"
19 #include "llvm/Support/DJB.h"
21 #include "llvm/Support/WithColor.h"
23 #include <map>
24 #include <set>
25 #include <vector>
26 
27 using namespace llvm;
28 using namespace dwarf;
29 using namespace object;
30 
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  DWARFAddressRange Range(*Pos);
39  if (Pos->merge(R))
40  return Range;
41  }
42  if (Pos != Begin) {
43  auto Iter = Pos - 1;
44  DWARFAddressRange Range(*Iter);
45  if (Iter->merge(R))
46  return Range;
47  }
48 
49  Ranges.insert(Pos, R);
50  return None;
51 }
52 
55  if (RI.Ranges.empty())
56  return Children.end();
57 
58  auto End = Children.end();
59  auto Iter = Children.begin();
60  while (Iter != End) {
61  if (Iter->intersects(RI))
62  return Iter;
63  ++Iter;
64  }
65  Children.insert(RI);
66  return Children.end();
67 }
68 
70  auto I1 = Ranges.begin(), E1 = Ranges.end();
71  auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
72  if (I2 == E2)
73  return true;
74 
75  DWARFAddressRange R = *I2;
76  while (I1 != E1) {
77  bool Covered = I1->LowPC <= R.LowPC;
78  if (R.LowPC == R.HighPC || (Covered && R.HighPC <= I1->HighPC)) {
79  if (++I2 == E2)
80  return true;
81  R = *I2;
82  continue;
83  }
84  if (!Covered)
85  return false;
86  if (R.LowPC < I1->HighPC)
87  R.LowPC = I1->HighPC;
88  ++I1;
89  }
90  return false;
91 }
92 
94  auto I1 = Ranges.begin(), E1 = Ranges.end();
95  auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
96  while (I1 != E1 && I2 != E2) {
97  if (I1->intersects(*I2))
98  return true;
99  if (I1->LowPC < I2->LowPC)
100  ++I1;
101  else
102  ++I2;
103  }
104  return false;
105 }
106 
107 bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
108  uint64_t *Offset, unsigned UnitIndex,
109  uint8_t &UnitType, bool &isUnitDWARF64) {
110  uint64_t AbbrOffset, Length;
111  uint8_t AddrSize = 0;
113  bool Success = true;
114 
115  bool ValidLength = false;
116  bool ValidVersion = false;
117  bool ValidAddrSize = false;
118  bool ValidType = true;
119  bool ValidAbbrevOffset = true;
120 
121  uint64_t OffsetStart = *Offset;
122  DwarfFormat Format;
123  std::tie(Length, Format) = DebugInfoData.getInitialLength(Offset);
124  isUnitDWARF64 = Format == DWARF64;
125  Version = DebugInfoData.getU16(Offset);
126 
127  if (Version >= 5) {
128  UnitType = DebugInfoData.getU8(Offset);
129  AddrSize = DebugInfoData.getU8(Offset);
130  AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
131  ValidType = dwarf::isUnitType(UnitType);
132  } else {
133  UnitType = 0;
134  AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
135  AddrSize = DebugInfoData.getU8(Offset);
136  }
137 
138  if (!DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset))
139  ValidAbbrevOffset = false;
140 
141  ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
143  ValidAddrSize = DWARFContext::isAddressSizeSupported(AddrSize);
144  if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
145  !ValidType) {
146  Success = false;
147  error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex,
148  OffsetStart);
149  if (!ValidLength)
150  note() << "The length for this unit is too "
151  "large for the .debug_info provided.\n";
152  if (!ValidVersion)
153  note() << "The 16 bit unit header version is not valid.\n";
154  if (!ValidType)
155  note() << "The unit type encoding is not valid.\n";
156  if (!ValidAbbrevOffset)
157  note() << "The offset into the .debug_abbrev section is "
158  "not valid.\n";
159  if (!ValidAddrSize)
160  note() << "The address size is unsupported.\n";
161  }
162  *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4);
163  return Success;
164 }
165 
166 bool DWARFVerifier::verifyName(const DWARFDie &Die) {
167  // FIXME Add some kind of record of which DIE names have already failed and
168  // don't bother checking a DIE that uses an already failed DIE.
169 
170  std::string ReconstructedName;
171  raw_string_ostream OS(ReconstructedName);
172  std::string OriginalFullName;
173  Die.getFullName(OS, &OriginalFullName);
174  OS.flush();
175  if (OriginalFullName.empty() || OriginalFullName == ReconstructedName)
176  return false;
177 
178  error() << "Simplified template DW_AT_name could not be reconstituted:\n"
179  << formatv(" original: {0}\n"
180  " reconstituted: {1}\n",
181  OriginalFullName, ReconstructedName);
182  dump(Die) << '\n';
183  dump(Die.getDwarfUnit()->getUnitDIE()) << '\n';
184  return true;
185 }
186 
187 unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit,
188  ReferenceMap &UnitLocalReferences,
189  ReferenceMap &CrossUnitReferences) {
190  unsigned NumUnitErrors = 0;
191  unsigned NumDies = Unit.getNumDIEs();
192  for (unsigned I = 0; I < NumDies; ++I) {
193  auto Die = Unit.getDIEAtIndex(I);
194 
195  if (Die.getTag() == DW_TAG_null)
196  continue;
197 
198  for (auto AttrValue : Die.attributes()) {
199  NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
200  NumUnitErrors += verifyDebugInfoForm(Die, AttrValue, UnitLocalReferences,
201  CrossUnitReferences);
202  }
203 
204  NumUnitErrors += verifyName(Die);
205 
206  if (Die.hasChildren()) {
207  if (Die.getFirstChild().isValid() &&
208  Die.getFirstChild().getTag() == DW_TAG_null) {
209  warn() << dwarf::TagString(Die.getTag())
210  << " has DW_CHILDREN_yes but DIE has no children: ";
211  Die.dump(OS);
212  }
213  }
214 
215  NumUnitErrors += verifyDebugInfoCallSite(Die);
216  }
217 
218  DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
219  if (!Die) {
220  error() << "Compilation unit without DIE.\n";
221  NumUnitErrors++;
222  return NumUnitErrors;
223  }
224 
225  if (!dwarf::isUnitType(Die.getTag())) {
226  error() << "Compilation unit root DIE is not a unit DIE: "
227  << dwarf::TagString(Die.getTag()) << ".\n";
228  NumUnitErrors++;
229  }
230 
231  uint8_t UnitType = Unit.getUnitType();
233  error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
234  << ") and root DIE (" << dwarf::TagString(Die.getTag())
235  << ") do not match.\n";
236  NumUnitErrors++;
237  }
238 
239  // According to DWARF Debugging Information Format Version 5,
240  // 3.1.2 Skeleton Compilation Unit Entries:
241  // "A skeleton compilation unit has no children."
242  if (Die.getTag() == dwarf::DW_TAG_skeleton_unit && Die.hasChildren()) {
243  error() << "Skeleton compilation unit has children.\n";
244  NumUnitErrors++;
245  }
246 
247  DieRangeInfo RI;
248  NumUnitErrors += verifyDieRanges(Die, RI);
249 
250  return NumUnitErrors;
251 }
252 
253 unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
254  if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site)
255  return 0;
256 
257  DWARFDie Curr = Die.getParent();
258  for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Die.getParent()) {
259  if (Curr.getTag() == DW_TAG_inlined_subroutine) {
260  error() << "Call site entry nested within inlined subroutine:";
261  Curr.dump(OS);
262  return 1;
263  }
264  }
265 
266  if (!Curr.isValid()) {
267  error() << "Call site entry not nested within a valid subprogram:";
268  Die.dump(OS);
269  return 1;
270  }
271 
272  Optional<DWARFFormValue> CallAttr =
273  Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls,
274  DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites,
275  DW_AT_GNU_all_source_call_sites,
276  DW_AT_GNU_all_tail_call_sites});
277  if (!CallAttr) {
278  error() << "Subprogram with call site entry has no DW_AT_call attribute:";
279  Curr.dump(OS);
280  Die.dump(OS, /*indent*/ 1);
281  return 1;
282  }
283 
284  return 0;
285 }
286 
287 unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
288  unsigned NumErrors = 0;
289  if (Abbrev) {
290  const DWARFAbbreviationDeclarationSet *AbbrDecls =
292  for (auto AbbrDecl : *AbbrDecls) {
294  for (auto Attribute : AbbrDecl.attributes()) {
295  auto Result = AttributeSet.insert(Attribute.Attr);
296  if (!Result.second) {
297  error() << "Abbreviation declaration contains multiple "
298  << AttributeString(Attribute.Attr) << " attributes.\n";
299  AbbrDecl.dump(OS);
300  ++NumErrors;
301  }
302  }
303  }
304  }
305  return NumErrors;
306 }
307 
309  OS << "Verifying .debug_abbrev...\n";
310 
311  const DWARFObject &DObj = DCtx.getDWARFObj();
312  unsigned NumErrors = 0;
313  if (!DObj.getAbbrevSection().empty())
314  NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev());
315  if (!DObj.getAbbrevDWOSection().empty())
316  NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO());
317 
318  return NumErrors == 0;
319 }
320 
321 unsigned DWARFVerifier::verifyUnits(const DWARFUnitVector &Units) {
322  unsigned NumDebugInfoErrors = 0;
323  ReferenceMap CrossUnitReferences;
324 
325  unsigned Index = 1;
326  for (const auto &Unit : Units) {
327  OS << "Verifying unit: " << Index << " / " << Units.getNumUnits();
328  if (const char* Name = Unit->getUnitDIE(true).getShortName())
329  OS << ", \"" << Name << '\"';
330  OS << '\n';
331  OS.flush();
332  ReferenceMap UnitLocalReferences;
333  NumDebugInfoErrors +=
334  verifyUnitContents(*Unit, UnitLocalReferences, CrossUnitReferences);
335  NumDebugInfoErrors += verifyDebugInfoReferences(
336  UnitLocalReferences, [&](uint64_t Offset) { return Unit.get(); });
337  ++Index;
338  }
339 
340  NumDebugInfoErrors += verifyDebugInfoReferences(
341  CrossUnitReferences, [&](uint64_t Offset) -> DWARFUnit * {
342  if (DWARFUnit *U = Units.getUnitForOffset(Offset))
343  return U;
344  return nullptr;
345  });
346 
347  return NumDebugInfoErrors;
348 }
349 
350 unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S) {
351  const DWARFObject &DObj = DCtx.getDWARFObj();
352  DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
353  unsigned NumDebugInfoErrors = 0;
354  uint64_t Offset = 0, UnitIdx = 0;
355  uint8_t UnitType = 0;
356  bool isUnitDWARF64 = false;
357  bool isHeaderChainValid = true;
358  bool hasDIE = DebugInfoData.isValidOffset(Offset);
359  DWARFUnitVector TypeUnitVector;
360  DWARFUnitVector CompileUnitVector;
361  /// A map that tracks all references (converted absolute references) so we
362  /// can verify each reference points to a valid DIE and not an offset that
363  /// lies between to valid DIEs.
364  ReferenceMap CrossUnitReferences;
365  while (hasDIE) {
366  if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
367  isUnitDWARF64)) {
368  isHeaderChainValid = false;
369  if (isUnitDWARF64)
370  break;
371  }
372  hasDIE = DebugInfoData.isValidOffset(Offset);
373  ++UnitIdx;
374  }
375  if (UnitIdx == 0 && !hasDIE) {
376  warn() << "Section is empty.\n";
377  isHeaderChainValid = true;
378  }
379  if (!isHeaderChainValid)
380  ++NumDebugInfoErrors;
381  return NumDebugInfoErrors;
382 }
383 
385  const DWARFObject &DObj = DCtx.getDWARFObj();
386  unsigned NumErrors = 0;
387 
388  OS << "Verifying .debug_info Unit Header Chain...\n";
389  DObj.forEachInfoSections([&](const DWARFSection &S) {
390  NumErrors += verifyUnitSection(S);
391  });
392 
393  OS << "Verifying .debug_types Unit Header Chain...\n";
394  DObj.forEachTypesSections([&](const DWARFSection &S) {
395  NumErrors += verifyUnitSection(S);
396  });
397 
398  OS << "Verifying non-dwo Units...\n";
399  NumErrors += verifyUnits(DCtx.getNormalUnitsVector());
400 
401  OS << "Verifying dwo Units...\n";
402  NumErrors += verifyUnits(DCtx.getDWOUnitsVector());
403  return NumErrors == 0;
404 }
405 
406 unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
407  DieRangeInfo &ParentRI) {
408  unsigned NumErrors = 0;
409 
410  if (!Die.isValid())
411  return NumErrors;
412 
413  DWARFUnit *Unit = Die.getDwarfUnit();
414 
415  auto RangesOrError = Die.getAddressRanges();
416  if (!RangesOrError) {
417  // FIXME: Report the error.
418  if (!Unit->isDWOUnit())
419  ++NumErrors;
420  llvm::consumeError(RangesOrError.takeError());
421  return NumErrors;
422  }
423 
424  const DWARFAddressRangesVector &Ranges = RangesOrError.get();
425  // Build RI for this DIE and check that ranges within this DIE do not
426  // overlap.
427  DieRangeInfo RI(Die);
428 
429  // TODO support object files better
430  //
431  // Some object file formats (i.e. non-MachO) support COMDAT. ELF in
432  // particular does so by placing each function into a section. The DWARF data
433  // for the function at that point uses a section relative DW_FORM_addrp for
434  // the DW_AT_low_pc and a DW_FORM_data4 for the offset as the DW_AT_high_pc.
435  // In such a case, when the Die is the CU, the ranges will overlap, and we
436  // will flag valid conflicting ranges as invalid.
437  //
438  // For such targets, we should read the ranges from the CU and partition them
439  // by the section id. The ranges within a particular section should be
440  // disjoint, although the ranges across sections may overlap. We would map
441  // the child die to the entity that it references and the section with which
442  // it is associated. The child would then be checked against the range
443  // information for the associated section.
444  //
445  // For now, simply elide the range verification for the CU DIEs if we are
446  // processing an object file.
447 
448  if (!IsObjectFile || IsMachOObject || Die.getTag() != DW_TAG_compile_unit) {
449  bool DumpDieAfterError = false;
450  for (const auto &Range : Ranges) {
451  if (!Range.valid()) {
452  ++NumErrors;
453  error() << "Invalid address range " << Range << "\n";
454  DumpDieAfterError = true;
455  continue;
456  }
457 
458  // Verify that ranges don't intersect and also build up the DieRangeInfo
459  // address ranges. Don't break out of the loop below early, or we will
460  // think this DIE doesn't have all of the address ranges it is supposed
461  // to have. Compile units often have DW_AT_ranges that can contain one or
462  // more dead stripped address ranges which tend to all be at the same
463  // address: 0 or -1.
464  if (auto PrevRange = RI.insert(Range)) {
465  ++NumErrors;
466  error() << "DIE has overlapping ranges in DW_AT_ranges attribute: "
467  << *PrevRange << " and " << Range << '\n';
468  DumpDieAfterError = true;
469  }
470  }
471  if (DumpDieAfterError)
472  dump(Die, 2) << '\n';
473  }
474 
475  // Verify that children don't intersect.
476  const auto IntersectingChild = ParentRI.insert(RI);
477  if (IntersectingChild != ParentRI.Children.end()) {
478  ++NumErrors;
479  error() << "DIEs have overlapping address ranges:";
480  dump(Die);
481  dump(IntersectingChild->Die) << '\n';
482  }
483 
484  // Verify that ranges are contained within their parent.
485  bool ShouldBeContained = !RI.Ranges.empty() && !ParentRI.Ranges.empty() &&
486  !(Die.getTag() == DW_TAG_subprogram &&
487  ParentRI.Die.getTag() == DW_TAG_subprogram);
488  if (ShouldBeContained && !ParentRI.contains(RI)) {
489  ++NumErrors;
490  error() << "DIE address ranges are not contained in its parent's ranges:";
491  dump(ParentRI.Die);
492  dump(Die, 2) << '\n';
493  }
494 
495  // Recursively check children.
496  for (DWARFDie Child : Die)
497  NumErrors += verifyDieRanges(Child, RI);
498 
499  return NumErrors;
500 }
501 
502 unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
503  DWARFAttribute &AttrValue) {
504  unsigned NumErrors = 0;
505  auto ReportError = [&](const Twine &TitleMsg) {
506  ++NumErrors;
507  error() << TitleMsg << '\n';
508  dump(Die) << '\n';
509  };
510 
511  const DWARFObject &DObj = DCtx.getDWARFObj();
512  DWARFUnit *U = Die.getDwarfUnit();
513  const auto Attr = AttrValue.Attr;
514  switch (Attr) {
515  case DW_AT_ranges:
516  // Make sure the offset in the DW_AT_ranges attribute is valid.
517  if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
518  unsigned DwarfVersion = U->getVersion();
519  const DWARFSection &RangeSection = DwarfVersion < 5
520  ? DObj.getRangesSection()
521  : DObj.getRnglistsSection();
522  if (U->isDWOUnit() && RangeSection.Data.empty())
523  break;
524  if (*SectionOffset >= RangeSection.Data.size())
525  ReportError(
526  "DW_AT_ranges offset is beyond " +
527  StringRef(DwarfVersion < 5 ? ".debug_ranges" : ".debug_rnglists") +
528  " bounds: " + llvm::formatv("{0:x8}", *SectionOffset));
529  break;
530  }
531  ReportError("DIE has invalid DW_AT_ranges encoding:");
532  break;
533  case DW_AT_stmt_list:
534  // Make sure the offset in the DW_AT_stmt_list attribute is valid.
535  if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
536  if (*SectionOffset >= U->getLineSection().Data.size())
537  ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
538  llvm::formatv("{0:x8}", *SectionOffset));
539  break;
540  }
541  ReportError("DIE has invalid DW_AT_stmt_list encoding:");
542  break;
543  case DW_AT_location: {
544  // FIXME: It might be nice if there's a way to walk location expressions
545  // without trying to resolve the address ranges - it'd be a more efficient
546  // API (since the API is currently unnecessarily resolving addresses for
547  // this use case which only wants to validate the expressions themselves) &
548  // then the expressions could be validated even if the addresses can't be
549  // resolved.
550  // That sort of API would probably look like a callback "for each
551  // expression" with some way to lazily resolve the address ranges when
552  // needed (& then the existing API used here could be built on top of that -
553  // using the callback API to build the data structure and return it).
554  if (Expected<std::vector<DWARFLocationExpression>> Loc =
555  Die.getLocations(DW_AT_location)) {
556  for (const auto &Entry : *Loc) {
557  DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
559  U->getFormParams().Format);
560  bool Error =
562  return Op.isError();
563  });
564  if (Error || !Expression.verify(U))
565  ReportError("DIE contains invalid DWARF expression:");
566  }
567  } else if (Error Err = handleErrors(
568  Loc.takeError(), [&](std::unique_ptr<ResolverError> E) {
569  return U->isDWOUnit() ? Error::success()
570  : Error(std::move(E));
571  }))
572  ReportError(toString(std::move(Err)));
573  break;
574  }
575  case DW_AT_specification:
576  case DW_AT_abstract_origin: {
577  if (auto ReferencedDie = Die.getAttributeValueAsReferencedDie(Attr)) {
578  auto DieTag = Die.getTag();
579  auto RefTag = ReferencedDie.getTag();
580  if (DieTag == RefTag)
581  break;
582  if (DieTag == DW_TAG_inlined_subroutine && RefTag == DW_TAG_subprogram)
583  break;
584  if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
585  break;
586  // This might be reference to a function declaration.
587  if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram)
588  break;
589  ReportError("DIE with tag " + TagString(DieTag) + " has " +
590  AttributeString(Attr) +
591  " that points to DIE with "
592  "incompatible tag " +
593  TagString(RefTag));
594  }
595  break;
596  }
597  case DW_AT_type: {
598  DWARFDie TypeDie = Die.getAttributeValueAsReferencedDie(DW_AT_type);
599  if (TypeDie && !isType(TypeDie.getTag())) {
600  ReportError("DIE has " + AttributeString(Attr) +
601  " with incompatible tag " + TagString(TypeDie.getTag()));
602  }
603  break;
604  }
605  case DW_AT_call_file:
606  case DW_AT_decl_file: {
607  if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) {
608  if (U->isDWOUnit() && !U->isTypeUnit())
609  break;
610  const auto *LT = U->getContext().getLineTableForUnit(U);
611  if (LT) {
612  if (!LT->hasFileAtIndex(*FileIdx)) {
613  bool IsZeroIndexed = LT->Prologue.getVersion() >= 5;
614  if (Optional<uint64_t> LastFileIdx = LT->getLastValidFileIndex()) {
615  ReportError("DIE has " + AttributeString(Attr) +
616  " with an invalid file index " +
617  llvm::formatv("{0}", *FileIdx) +
618  " (valid values are [" + (IsZeroIndexed ? "0-" : "1-") +
619  llvm::formatv("{0}", *LastFileIdx) + "])");
620  } else {
621  ReportError("DIE has " + AttributeString(Attr) +
622  " with an invalid file index " +
623  llvm::formatv("{0}", *FileIdx) +
624  " (the file table in the prologue is empty)");
625  }
626  }
627  } else {
628  ReportError("DIE has " + AttributeString(Attr) +
629  " that references a file with index " +
630  llvm::formatv("{0}", *FileIdx) +
631  " and the compile unit has no line table");
632  }
633  } else {
634  ReportError("DIE has " + AttributeString(Attr) +
635  " with invalid encoding");
636  }
637  break;
638  }
639  default:
640  break;
641  }
642  return NumErrors;
643 }
644 
645 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
646  DWARFAttribute &AttrValue,
647  ReferenceMap &LocalReferences,
648  ReferenceMap &CrossUnitReferences) {
649  auto DieCU = Die.getDwarfUnit();
650  unsigned NumErrors = 0;
651  const auto Form = AttrValue.Value.getForm();
652  switch (Form) {
653  case DW_FORM_ref1:
654  case DW_FORM_ref2:
655  case DW_FORM_ref4:
656  case DW_FORM_ref8:
657  case DW_FORM_ref_udata: {
658  // Verify all CU relative references are valid CU offsets.
659  Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
660  assert(RefVal);
661  if (RefVal) {
662  auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
663  auto CUOffset = AttrValue.Value.getRawUValue();
664  if (CUOffset >= CUSize) {
665  ++NumErrors;
666  error() << FormEncodingString(Form) << " CU offset "
667  << format("0x%08" PRIx64, CUOffset)
668  << " is invalid (must be less than CU size of "
669  << format("0x%08" PRIx64, CUSize) << "):\n";
670  Die.dump(OS, 0, DumpOpts);
671  dump(Die) << '\n';
672  } else {
673  // Valid reference, but we will verify it points to an actual
674  // DIE later.
675  LocalReferences[*RefVal].insert(Die.getOffset());
676  }
677  }
678  break;
679  }
680  case DW_FORM_ref_addr: {
681  // Verify all absolute DIE references have valid offsets in the
682  // .debug_info section.
683  Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
684  assert(RefVal);
685  if (RefVal) {
686  if (*RefVal >= DieCU->getInfoSection().Data.size()) {
687  ++NumErrors;
688  error() << "DW_FORM_ref_addr offset beyond .debug_info "
689  "bounds:\n";
690  dump(Die) << '\n';
691  } else {
692  // Valid reference, but we will verify it points to an actual
693  // DIE later.
694  CrossUnitReferences[*RefVal].insert(Die.getOffset());
695  }
696  }
697  break;
698  }
699  case DW_FORM_strp:
700  case DW_FORM_strx:
701  case DW_FORM_strx1:
702  case DW_FORM_strx2:
703  case DW_FORM_strx3:
704  case DW_FORM_strx4: {
705  if (Error E = AttrValue.Value.getAsCString().takeError()) {
706  ++NumErrors;
707  error() << toString(std::move(E)) << ":\n";
708  dump(Die) << '\n';
709  }
710  break;
711  }
712  default:
713  break;
714  }
715  return NumErrors;
716 }
717 
718 unsigned DWARFVerifier::verifyDebugInfoReferences(
719  const ReferenceMap &References,
720  llvm::function_ref<DWARFUnit *(uint64_t)> GetUnitForOffset) {
721  auto GetDIEForOffset = [&](uint64_t Offset) {
722  if (DWARFUnit *U = GetUnitForOffset(Offset))
723  return U->getDIEForOffset(Offset);
724  return DWARFDie();
725  };
726  unsigned NumErrors = 0;
727  for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
728  References) {
729  if (GetDIEForOffset(Pair.first))
730  continue;
731  ++NumErrors;
732  error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
733  << ". Offset is in between DIEs:\n";
734  for (auto Offset : Pair.second)
735  dump(GetDIEForOffset(Offset)) << '\n';
736  OS << "\n";
737  }
738  return NumErrors;
739 }
740 
741 void DWARFVerifier::verifyDebugLineStmtOffsets() {
742  std::map<uint64_t, DWARFDie> StmtListToDie;
743  for (const auto &CU : DCtx.compile_units()) {
744  auto Die = CU->getUnitDIE();
745  // Get the attribute value as a section offset. No need to produce an
746  // error here if the encoding isn't correct because we validate this in
747  // the .debug_info verifier.
748  auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
749  if (!StmtSectionOffset)
750  continue;
751  const uint64_t LineTableOffset = *StmtSectionOffset;
752  auto LineTable = DCtx.getLineTableForUnit(CU.get());
753  if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
754  if (!LineTable) {
755  ++NumDebugLineErrors;
756  error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
757  << "] was not able to be parsed for CU:\n";
758  dump(Die) << '\n';
759  continue;
760  }
761  } else {
762  // Make sure we don't get a valid line table back if the offset is wrong.
763  assert(LineTable == nullptr);
764  // Skip this line table as it isn't valid. No need to create an error
765  // here because we validate this in the .debug_info verifier.
766  continue;
767  }
768  auto Iter = StmtListToDie.find(LineTableOffset);
769  if (Iter != StmtListToDie.end()) {
770  ++NumDebugLineErrors;
771  error() << "two compile unit DIEs, "
772  << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
773  << format("0x%08" PRIx64, Die.getOffset())
774  << ", have the same DW_AT_stmt_list section offset:\n";
775  dump(Iter->second);
776  dump(Die) << '\n';
777  // Already verified this line table before, no need to do it again.
778  continue;
779  }
780  StmtListToDie[LineTableOffset] = Die;
781  }
782 }
783 
784 void DWARFVerifier::verifyDebugLineRows() {
785  for (const auto &CU : DCtx.compile_units()) {
786  auto Die = CU->getUnitDIE();
787  auto LineTable = DCtx.getLineTableForUnit(CU.get());
788  // If there is no line table we will have created an error in the
789  // .debug_info verifier or in verifyDebugLineStmtOffsets().
790  if (!LineTable)
791  continue;
792 
793  // Verify prologue.
794  uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
795  uint32_t FileIndex = 1;
796  StringMap<uint16_t> FullPathMap;
797  for (const auto &FileName : LineTable->Prologue.FileNames) {
798  // Verify directory index.
799  if (FileName.DirIdx > MaxDirIndex) {
800  ++NumDebugLineErrors;
801  error() << ".debug_line["
802  << format("0x%08" PRIx64,
803  *toSectionOffset(Die.find(DW_AT_stmt_list)))
804  << "].prologue.file_names[" << FileIndex
805  << "].dir_idx contains an invalid index: " << FileName.DirIdx
806  << "\n";
807  }
808 
809  // Check file paths for duplicates.
810  std::string FullPath;
811  const bool HasFullPath = LineTable->getFileNameByIndex(
812  FileIndex, CU->getCompilationDir(),
814  assert(HasFullPath && "Invalid index?");
815  (void)HasFullPath;
816  auto It = FullPathMap.find(FullPath);
817  if (It == FullPathMap.end())
818  FullPathMap[FullPath] = FileIndex;
819  else if (It->second != FileIndex) {
820  warn() << ".debug_line["
821  << format("0x%08" PRIx64,
822  *toSectionOffset(Die.find(DW_AT_stmt_list)))
823  << "].prologue.file_names[" << FileIndex
824  << "] is a duplicate of file_names[" << It->second << "]\n";
825  }
826 
827  FileIndex++;
828  }
829 
830  // Verify rows.
831  uint64_t PrevAddress = 0;
832  uint32_t RowIndex = 0;
833  for (const auto &Row : LineTable->Rows) {
834  // Verify row address.
835  if (Row.Address.Address < PrevAddress) {
836  ++NumDebugLineErrors;
837  error() << ".debug_line["
838  << format("0x%08" PRIx64,
839  *toSectionOffset(Die.find(DW_AT_stmt_list)))
840  << "] row[" << RowIndex
841  << "] decreases in address from previous row:\n";
842 
844  if (RowIndex > 0)
845  LineTable->Rows[RowIndex - 1].dump(OS);
846  Row.dump(OS);
847  OS << '\n';
848  }
849 
850  // Verify file index.
851  if (!LineTable->hasFileAtIndex(Row.File)) {
852  ++NumDebugLineErrors;
853  bool isDWARF5 = LineTable->Prologue.getVersion() >= 5;
854  error() << ".debug_line["
855  << format("0x%08" PRIx64,
856  *toSectionOffset(Die.find(DW_AT_stmt_list)))
857  << "][" << RowIndex << "] has invalid file index " << Row.File
858  << " (valid values are [" << (isDWARF5 ? "0," : "1,")
859  << LineTable->Prologue.FileNames.size()
860  << (isDWARF5 ? ")" : "]") << "):\n";
862  Row.dump(OS);
863  OS << '\n';
864  }
865  if (Row.EndSequence)
866  PrevAddress = 0;
867  else
868  PrevAddress = Row.Address.Address;
869  ++RowIndex;
870  }
871  }
872 }
873 
875  DIDumpOptions DumpOpts)
876  : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
877  IsMachOObject(false) {
878  if (const auto *F = DCtx.getDWARFObj().getFile()) {
879  IsObjectFile = F->isRelocatableObject();
880  IsMachOObject = F->isMachO();
881  }
882 }
883 
885  NumDebugLineErrors = 0;
886  OS << "Verifying .debug_line...\n";
887  verifyDebugLineStmtOffsets();
888  verifyDebugLineRows();
889  return NumDebugLineErrors == 0;
890 }
891 
892 unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
893  DataExtractor *StrData,
894  const char *SectionName) {
895  unsigned NumErrors = 0;
896  DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
897  DCtx.isLittleEndian(), 0);
898  AppleAcceleratorTable AccelTable(AccelSectionData, *StrData);
899 
900  OS << "Verifying " << SectionName << "...\n";
901 
902  // Verify that the fixed part of the header is not too short.
903  if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
904  error() << "Section is too small to fit a section header.\n";
905  return 1;
906  }
907 
908  // Verify that the section is not too short.
909  if (Error E = AccelTable.extract()) {
910  error() << toString(std::move(E)) << '\n';
911  return 1;
912  }
913 
914  // Verify that all buckets have a valid hash index or are empty.
915  uint32_t NumBuckets = AccelTable.getNumBuckets();
916  uint32_t NumHashes = AccelTable.getNumHashes();
917 
918  uint64_t BucketsOffset =
919  AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
920  uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
921  uint64_t OffsetsBase = HashesBase + NumHashes * 4;
922  for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
923  uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
924  if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
925  error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
926  HashIdx);
927  ++NumErrors;
928  }
929  }
930  uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
931  if (NumAtoms == 0) {
932  error() << "No atoms: failed to read HashData.\n";
933  return 1;
934  }
935  if (!AccelTable.validateForms()) {
936  error() << "Unsupported form: failed to read HashData.\n";
937  return 1;
938  }
939 
940  for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
941  uint64_t HashOffset = HashesBase + 4 * HashIdx;
942  uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
943  uint32_t Hash = AccelSectionData.getU32(&HashOffset);
944  uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
945  if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
946  sizeof(uint64_t))) {
947  error() << format("Hash[%d] has invalid HashData offset: "
948  "0x%08" PRIx64 ".\n",
949  HashIdx, HashDataOffset);
950  ++NumErrors;
951  }
952 
953  uint64_t StrpOffset;
954  uint64_t StringOffset;
955  uint32_t StringCount = 0;
957  unsigned Tag;
958  while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
959  const uint32_t NumHashDataObjects =
960  AccelSectionData.getU32(&HashDataOffset);
961  for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
962  ++HashDataIdx) {
963  std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
964  auto Die = DCtx.getDIEForOffset(Offset);
965  if (!Die) {
966  const uint32_t BucketIdx =
967  NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
968  StringOffset = StrpOffset;
969  const char *Name = StrData->getCStr(&StringOffset);
970  if (!Name)
971  Name = "<NULL>";
972 
973  error() << format(
974  "%s Bucket[%d] Hash[%d] = 0x%08x "
975  "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
976  "is not a valid DIE offset for \"%s\".\n",
977  SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
978  HashDataIdx, Offset, Name);
979 
980  ++NumErrors;
981  continue;
982  }
983  if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
984  error() << "Tag " << dwarf::TagString(Tag)
985  << " in accelerator table does not match Tag "
986  << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
987  << "].\n";
988  ++NumErrors;
989  }
990  }
991  ++StringCount;
992  }
993  }
994  return NumErrors;
995 }
996 
997 unsigned
998 DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
999  // A map from CU offset to the (first) Name Index offset which claims to index
1000  // this CU.
1002  const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
1003 
1004  CUMap.reserve(DCtx.getNumCompileUnits());
1005  for (const auto &CU : DCtx.compile_units())
1006  CUMap[CU->getOffset()] = NotIndexed;
1007 
1008  unsigned NumErrors = 0;
1009  for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
1010  if (NI.getCUCount() == 0) {
1011  error() << formatv("Name Index @ {0:x} does not index any CU\n",
1012  NI.getUnitOffset());
1013  ++NumErrors;
1014  continue;
1015  }
1016  for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
1017  uint64_t Offset = NI.getCUOffset(CU);
1018  auto Iter = CUMap.find(Offset);
1019 
1020  if (Iter == CUMap.end()) {
1021  error() << formatv(
1022  "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
1023  NI.getUnitOffset(), Offset);
1024  ++NumErrors;
1025  continue;
1026  }
1027 
1028  if (Iter->second != NotIndexed) {
1029  error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
1030  "this CU is already indexed by Name Index @ {2:x}\n",
1031  NI.getUnitOffset(), Offset, Iter->second);
1032  continue;
1033  }
1034  Iter->second = NI.getUnitOffset();
1035  }
1036  }
1037 
1038  for (const auto &KV : CUMap) {
1039  if (KV.second == NotIndexed)
1040  warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
1041  }
1042 
1043  return NumErrors;
1044 }
1045 
1046 unsigned
1047 DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
1048  const DataExtractor &StrData) {
1049  struct BucketInfo {
1050  uint32_t Bucket;
1051  uint32_t Index;
1052 
1053  constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
1054  : Bucket(Bucket), Index(Index) {}
1055  bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
1056  };
1057 
1058  uint32_t NumErrors = 0;
1059  if (NI.getBucketCount() == 0) {
1060  warn() << formatv("Name Index @ {0:x} does not contain a hash table.\n",
1061  NI.getUnitOffset());
1062  return NumErrors;
1063  }
1064 
1065  // Build up a list of (Bucket, Index) pairs. We use this later to verify that
1066  // each Name is reachable from the appropriate bucket.
1067  std::vector<BucketInfo> BucketStarts;
1068  BucketStarts.reserve(NI.getBucketCount() + 1);
1069  for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End; ++Bucket) {
1070  uint32_t Index = NI.getBucketArrayEntry(Bucket);
1071  if (Index > NI.getNameCount()) {
1072  error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
1073  "value {2}. Valid range is [0, {3}].\n",
1074  Bucket, NI.getUnitOffset(), Index, NI.getNameCount());
1075  ++NumErrors;
1076  continue;
1077  }
1078  if (Index > 0)
1079  BucketStarts.emplace_back(Bucket, Index);
1080  }
1081 
1082  // If there were any buckets with invalid values, skip further checks as they
1083  // will likely produce many errors which will only confuse the actual root
1084  // problem.
1085  if (NumErrors > 0)
1086  return NumErrors;
1087 
1088  // Sort the list in the order of increasing "Index" entries.
1089  array_pod_sort(BucketStarts.begin(), BucketStarts.end());
1090 
1091  // Insert a sentinel entry at the end, so we can check that the end of the
1092  // table is covered in the loop below.
1093  BucketStarts.emplace_back(NI.getBucketCount(), NI.getNameCount() + 1);
1094 
1095  // Loop invariant: NextUncovered is the (1-based) index of the first Name
1096  // which is not reachable by any of the buckets we processed so far (and
1097  // hasn't been reported as uncovered).
1098  uint32_t NextUncovered = 1;
1099  for (const BucketInfo &B : BucketStarts) {
1100  // Under normal circumstances B.Index be equal to NextUncovered, but it can
1101  // be less if a bucket points to names which are already known to be in some
1102  // bucket we processed earlier. In that case, we won't trigger this error,
1103  // but report the mismatched hash value error instead. (We know the hash
1104  // will not match because we have already verified that the name's hash
1105  // puts it into the previous bucket.)
1106  if (B.Index > NextUncovered) {
1107  error() << formatv("Name Index @ {0:x}: Name table entries [{1}, {2}] "
1108  "are not covered by the hash table.\n",
1109  NI.getUnitOffset(), NextUncovered, B.Index - 1);
1110  ++NumErrors;
1111  }
1112  uint32_t Idx = B.Index;
1113 
1114  // The rest of the checks apply only to non-sentinel entries.
1115  if (B.Bucket == NI.getBucketCount())
1116  break;
1117 
1118  // This triggers if a non-empty bucket points to a name with a mismatched
1119  // hash. Clients are likely to interpret this as an empty bucket, because a
1120  // mismatched hash signals the end of a bucket, but if this is indeed an
1121  // empty bucket, the producer should have signalled this by marking the
1122  // bucket as empty.
1123  uint32_t FirstHash = NI.getHashArrayEntry(Idx);
1124  if (FirstHash % NI.getBucketCount() != B.Bucket) {
1125  error() << formatv(
1126  "Name Index @ {0:x}: Bucket {1} is not empty but points to a "
1127  "mismatched hash value {2:x} (belonging to bucket {3}).\n",
1128  NI.getUnitOffset(), B.Bucket, FirstHash,
1129  FirstHash % NI.getBucketCount());
1130  ++NumErrors;
1131  }
1132 
1133  // This find the end of this bucket and also verifies that all the hashes in
1134  // this bucket are correct by comparing the stored hashes to the ones we
1135  // compute ourselves.
1136  while (Idx <= NI.getNameCount()) {
1137  uint32_t Hash = NI.getHashArrayEntry(Idx);
1138  if (Hash % NI.getBucketCount() != B.Bucket)
1139  break;
1140 
1141  const char *Str = NI.getNameTableEntry(Idx).getString();
1142  if (caseFoldingDjbHash(Str) != Hash) {
1143  error() << formatv("Name Index @ {0:x}: String ({1}) at index {2} "
1144  "hashes to {3:x}, but "
1145  "the Name Index hash is {4:x}\n",
1146  NI.getUnitOffset(), Str, Idx,
1147  caseFoldingDjbHash(Str), Hash);
1148  ++NumErrors;
1149  }
1150 
1151  ++Idx;
1152  }
1153  NextUncovered = std::max(NextUncovered, Idx);
1154  }
1155  return NumErrors;
1156 }
1157 
1158 unsigned DWARFVerifier::verifyNameIndexAttribute(
1159  const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr,
1161  StringRef FormName = dwarf::FormEncodingString(AttrEnc.Form);
1162  if (FormName.empty()) {
1163  error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
1164  "unknown form: {3}.\n",
1165  NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
1166  AttrEnc.Form);
1167  return 1;
1168  }
1169 
1170  if (AttrEnc.Index == DW_IDX_type_hash) {
1171  if (AttrEnc.Form != dwarf::DW_FORM_data8) {
1172  error() << formatv(
1173  "NameIndex @ {0:x}: Abbreviation {1:x}: DW_IDX_type_hash "
1174  "uses an unexpected form {2} (should be {3}).\n",
1175  NI.getUnitOffset(), Abbr.Code, AttrEnc.Form, dwarf::DW_FORM_data8);
1176  return 1;
1177  }
1178  }
1179 
1180  // A list of known index attributes and their expected form classes.
1181  // DW_IDX_type_hash is handled specially in the check above, as it has a
1182  // specific form (not just a form class) we should expect.
1183  struct FormClassTable {
1186  StringLiteral ClassName;
1187  };
1188  static constexpr FormClassTable Table[] = {
1189  {dwarf::DW_IDX_compile_unit, DWARFFormValue::FC_Constant, {"constant"}},
1190  {dwarf::DW_IDX_type_unit, DWARFFormValue::FC_Constant, {"constant"}},
1191  {dwarf::DW_IDX_die_offset, DWARFFormValue::FC_Reference, {"reference"}},
1192  {dwarf::DW_IDX_parent, DWARFFormValue::FC_Constant, {"constant"}},
1193  };
1194 
1196  auto Iter = find_if(TableRef, [AttrEnc](const FormClassTable &T) {
1197  return T.Index == AttrEnc.Index;
1198  });
1199  if (Iter == TableRef.end()) {
1200  warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains an "
1201  "unknown index attribute: {2}.\n",
1202  NI.getUnitOffset(), Abbr.Code, AttrEnc.Index);
1203  return 0;
1204  }
1205 
1206  if (!DWARFFormValue(AttrEnc.Form).isFormClass(Iter->Class)) {
1207  error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
1208  "unexpected form {3} (expected form class {4}).\n",
1209  NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
1210  AttrEnc.Form, Iter->ClassName);
1211  return 1;
1212  }
1213  return 0;
1214 }
1215 
1216 unsigned
1217 DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
1218  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
1219  warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
1220  "not currently supported.\n",
1221  NI.getUnitOffset());
1222  return 0;
1223  }
1224 
1225  unsigned NumErrors = 0;
1226  for (const auto &Abbrev : NI.getAbbrevs()) {
1227  StringRef TagName = dwarf::TagString(Abbrev.Tag);
1228  if (TagName.empty()) {
1229  warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} references an "
1230  "unknown tag: {2}.\n",
1231  NI.getUnitOffset(), Abbrev.Code, Abbrev.Tag);
1232  }
1234  for (const auto &AttrEnc : Abbrev.Attributes) {
1235  if (!Attributes.insert(AttrEnc.Index).second) {
1236  error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains "
1237  "multiple {2} attributes.\n",
1238  NI.getUnitOffset(), Abbrev.Code, AttrEnc.Index);
1239  ++NumErrors;
1240  continue;
1241  }
1242  NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
1243  }
1244 
1245  if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
1246  error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
1247  "and abbreviation {1:x} has no {2} attribute.\n",
1248  NI.getUnitOffset(), Abbrev.Code,
1249  dwarf::DW_IDX_compile_unit);
1250  ++NumErrors;
1251  }
1252  if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
1253  error() << formatv(
1254  "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
1255  NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
1256  ++NumErrors;
1257  }
1258  }
1259  return NumErrors;
1260 }
1261 
1263  bool IncludeLinkageName = true) {
1265  if (const char *Str = DIE.getShortName())
1266  Result.emplace_back(Str);
1267  else if (DIE.getTag() == dwarf::DW_TAG_namespace)
1268  Result.emplace_back("(anonymous namespace)");
1269 
1270  if (IncludeLinkageName) {
1271  if (const char *Str = DIE.getLinkageName())
1272  Result.emplace_back(Str);
1273  }
1274 
1275  return Result;
1276 }
1277 
1278 unsigned DWARFVerifier::verifyNameIndexEntries(
1279  const DWARFDebugNames::NameIndex &NI,
1280  const DWARFDebugNames::NameTableEntry &NTE) {
1281  // Verifying type unit indexes not supported.
1282  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
1283  return 0;
1284 
1285  const char *CStr = NTE.getString();
1286  if (!CStr) {
1287  error() << formatv(
1288  "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
1289  NI.getUnitOffset(), NTE.getIndex());
1290  return 1;
1291  }
1292  StringRef Str(CStr);
1293 
1294  unsigned NumErrors = 0;
1295  unsigned NumEntries = 0;
1296  uint64_t EntryID = NTE.getEntryOffset();
1297  uint64_t NextEntryID = EntryID;
1298  Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
1299  for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
1300  EntryOr = NI.getEntry(&NextEntryID)) {
1301  uint32_t CUIndex = *EntryOr->getCUIndex();
1302  if (CUIndex > NI.getCUCount()) {
1303  error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
1304  "invalid CU index ({2}).\n",
1305  NI.getUnitOffset(), EntryID, CUIndex);
1306  ++NumErrors;
1307  continue;
1308  }
1309  uint64_t CUOffset = NI.getCUOffset(CUIndex);
1310  uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
1311  DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
1312  if (!DIE) {
1313  error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
1314  "non-existing DIE @ {2:x}.\n",
1315  NI.getUnitOffset(), EntryID, DIEOffset);
1316  ++NumErrors;
1317  continue;
1318  }
1319  if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
1320  error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
1321  "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
1322  NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
1323  DIE.getDwarfUnit()->getOffset());
1324  ++NumErrors;
1325  }
1326  if (DIE.getTag() != EntryOr->tag()) {
1327  error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
1328  "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1329  NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
1330  DIE.getTag());
1331  ++NumErrors;
1332  }
1333 
1334  auto EntryNames = getNames(DIE);
1335  if (!is_contained(EntryNames, Str)) {
1336  error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
1337  "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1338  NI.getUnitOffset(), EntryID, DIEOffset, Str,
1339  make_range(EntryNames.begin(), EntryNames.end()));
1340  ++NumErrors;
1341  }
1342  }
1343  handleAllErrors(EntryOr.takeError(),
1344  [&](const DWARFDebugNames::SentinelError &) {
1345  if (NumEntries > 0)
1346  return;
1347  error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
1348  "not associated with any entries.\n",
1349  NI.getUnitOffset(), NTE.getIndex(), Str);
1350  ++NumErrors;
1351  },
1352  [&](const ErrorInfoBase &Info) {
1353  error()
1354  << formatv("Name Index @ {0:x}: Name {1} ({2}): {3}\n",
1355  NI.getUnitOffset(), NTE.getIndex(), Str,
1356  Info.message());
1357  ++NumErrors;
1358  });
1359  return NumErrors;
1360 }
1361 
1362 static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
1364  Die.getLocations(DW_AT_location);
1365  if (!Loc) {
1366  consumeError(Loc.takeError());
1367  return false;
1368  }
1369  DWARFUnit *U = Die.getDwarfUnit();
1370  for (const auto &Entry : *Loc) {
1371  DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
1372  U->getAddressByteSize());
1374  U->getFormParams().Format);
1375  bool IsInteresting =
1377  return !Op.isError() && (Op.getCode() == DW_OP_addr ||
1378  Op.getCode() == DW_OP_form_tls_address ||
1379  Op.getCode() == DW_OP_GNU_push_tls_address);
1380  });
1381  if (IsInteresting)
1382  return true;
1383  }
1384  return false;
1385 }
1386 
1387 unsigned DWARFVerifier::verifyNameIndexCompleteness(
1388  const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI) {
1389 
1390  // First check, if the Die should be indexed. The code follows the DWARF v5
1391  // wording as closely as possible.
1392 
1393  // "All non-defining declarations (that is, debugging information entries
1394  // with a DW_AT_declaration attribute) are excluded."
1395  if (Die.find(DW_AT_declaration))
1396  return 0;
1397 
1398  // "DW_TAG_namespace debugging information entries without a DW_AT_name
1399  // attribute are included with the name “(anonymous namespace)”.
1400  // All other debugging information entries without a DW_AT_name attribute
1401  // are excluded."
1402  // "If a subprogram or inlined subroutine is included, and has a
1403  // DW_AT_linkage_name attribute, there will be an additional index entry for
1404  // the linkage name."
1405  auto IncludeLinkageName = Die.getTag() == DW_TAG_subprogram ||
1406  Die.getTag() == DW_TAG_inlined_subroutine;
1407  auto EntryNames = getNames(Die, IncludeLinkageName);
1408  if (EntryNames.empty())
1409  return 0;
1410 
1411  // We deviate from the specification here, which says:
1412  // "The name index must contain an entry for each debugging information entry
1413  // that defines a named subprogram, label, variable, type, or namespace,
1414  // subject to ..."
1415  // Explicitly exclude all TAGs that we know shouldn't be indexed.
1416  switch (Die.getTag()) {
1417  // Compile units and modules have names but shouldn't be indexed.
1418  case DW_TAG_compile_unit:
1419  case DW_TAG_module:
1420  return 0;
1421 
1422  // Function and template parameters are not globally visible, so we shouldn't
1423  // index them.
1424  case DW_TAG_formal_parameter:
1425  case DW_TAG_template_value_parameter:
1426  case DW_TAG_template_type_parameter:
1427  case DW_TAG_GNU_template_parameter_pack:
1428  case DW_TAG_GNU_template_template_param:
1429  return 0;
1430 
1431  // Object members aren't globally visible.
1432  case DW_TAG_member:
1433  return 0;
1434 
1435  // According to a strict reading of the specification, enumerators should not
1436  // be indexed (and LLVM currently does not do that). However, this causes
1437  // problems for the debuggers, so we may need to reconsider this.
1438  case DW_TAG_enumerator:
1439  return 0;
1440 
1441  // Imported declarations should not be indexed according to the specification
1442  // and LLVM currently does not do that.
1443  case DW_TAG_imported_declaration:
1444  return 0;
1445 
1446  // "DW_TAG_subprogram, DW_TAG_inlined_subroutine, and DW_TAG_label debugging
1447  // information entries without an address attribute (DW_AT_low_pc,
1448  // DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded."
1449  case DW_TAG_subprogram:
1450  case DW_TAG_inlined_subroutine:
1451  case DW_TAG_label:
1452  if (Die.findRecursively(
1453  {DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_entry_pc}))
1454  break;
1455  return 0;
1456 
1457  // "DW_TAG_variable debugging information entries with a DW_AT_location
1458  // attribute that includes a DW_OP_addr or DW_OP_form_tls_address operator are
1459  // included; otherwise, they are excluded."
1460  //
1461  // LLVM extension: We also add DW_OP_GNU_push_tls_address to this list.
1462  case DW_TAG_variable:
1463  if (isVariableIndexable(Die, DCtx))
1464  break;
1465  return 0;
1466 
1467  default:
1468  break;
1469  }
1470 
1471  // Now we know that our Die should be present in the Index. Let's check if
1472  // that's the case.
1473  unsigned NumErrors = 0;
1474  uint64_t DieUnitOffset = Die.getOffset() - Die.getDwarfUnit()->getOffset();
1475  for (StringRef Name : EntryNames) {
1476  if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) {
1477  return E.getDIEUnitOffset() == DieUnitOffset;
1478  })) {
1479  error() << formatv("Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with "
1480  "name {3} missing.\n",
1481  NI.getUnitOffset(), Die.getOffset(), Die.getTag(),
1482  Name);
1483  ++NumErrors;
1484  }
1485  }
1486  return NumErrors;
1487 }
1488 
1489 unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
1490  const DataExtractor &StrData) {
1491  unsigned NumErrors = 0;
1492  DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
1493  DCtx.isLittleEndian(), 0);
1494  DWARFDebugNames AccelTable(AccelSectionData, StrData);
1495 
1496  OS << "Verifying .debug_names...\n";
1497 
1498  // This verifies that we can read individual name indices and their
1499  // abbreviation tables.
1500  if (Error E = AccelTable.extract()) {
1501  error() << toString(std::move(E)) << '\n';
1502  return 1;
1503  }
1504 
1505  NumErrors += verifyDebugNamesCULists(AccelTable);
1506  for (const auto &NI : AccelTable)
1507  NumErrors += verifyNameIndexBuckets(NI, StrData);
1508  for (const auto &NI : AccelTable)
1509  NumErrors += verifyNameIndexAbbrevs(NI);
1510 
1511  // Don't attempt Entry validation if any of the previous checks found errors
1512  if (NumErrors > 0)
1513  return NumErrors;
1514  for (const auto &NI : AccelTable)
1515  for (const DWARFDebugNames::NameTableEntry &NTE : NI)
1516  NumErrors += verifyNameIndexEntries(NI, NTE);
1517 
1518  if (NumErrors > 0)
1519  return NumErrors;
1520 
1521  for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
1522  if (const DWARFDebugNames::NameIndex *NI =
1523  AccelTable.getCUNameIndex(U->getOffset())) {
1524  auto *CU = cast<DWARFCompileUnit>(U.get());
1525  for (const DWARFDebugInfoEntry &Die : CU->dies())
1526  NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
1527  }
1528  }
1529  return NumErrors;
1530 }
1531 
1533  const DWARFObject &D = DCtx.getDWARFObj();
1534  DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
1535  unsigned NumErrors = 0;
1536  if (!D.getAppleNamesSection().Data.empty())
1537  NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
1538  ".apple_names");
1539  if (!D.getAppleTypesSection().Data.empty())
1540  NumErrors += verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData,
1541  ".apple_types");
1542  if (!D.getAppleNamespacesSection().Data.empty())
1543  NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
1544  ".apple_namespaces");
1545  if (!D.getAppleObjCSection().Data.empty())
1546  NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
1547  ".apple_objc");
1548 
1549  if (!D.getNamesSection().Data.empty())
1550  NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
1551  return NumErrors == 0;
1552 }
1553 
1554 raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
1555 
1556 raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
1557 
1558 raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
1559 
1560 raw_ostream &DWARFVerifier::dump(const DWARFDie &Die, unsigned indent) const {
1561  Die.dump(OS, indent, DumpOpts);
1562  return OS;
1563 }
llvm::DWARFSection
Definition: DWARFSection.h:16
DWARFFormValue.h
llvm::array_pod_sort
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Definition: STLExtras.h:1548
llvm::DWARFContext::getLineTableForUnit
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
Definition: DWARFContext.cpp:957
llvm::DWARFDie::isValid
bool isValid() const
Definition: DWARFDie.h:51
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:945
llvm::DWARFVerifier::DieRangeInfo::Ranges
std::vector< DWARFAddressRange > Ranges
Sorted DWARFAddressRanges.
Definition: DWARFVerifier.h:41
DWARFCompileUnit.h
llvm::none_of
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1663
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::DWARFAttribute::Value
DWARFFormValue Value
The form and value for this attribute.
Definition: DWARFAttribute.h:32
DJB.h
T
llvm::Attribute
Definition: Attributes.h:53
llvm::DWARFAttribute::Attr
dwarf::Attribute Attr
The attribute enumeration of this attribute.
Definition: DWARFAttribute.h:30
llvm::lower_bound
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1759
llvm::DWARFDebugNames::NameTableEntry::getString
const char * getString() const
Return the string referenced by this name table entry or nullptr if the string offset is not valid.
Definition: DWARFAcceleratorTable.h:377
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:631
llvm::toString
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:1030
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1177
llvm::dwarf::Form
Form
Definition: Dwarf.h:131
llvm::SmallDenseSet
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition: DenseSet.h:286
llvm::DWARFFormValue::FC_Constant
@ FC_Constant
Definition: DWARFFormValue.h:32
DWARFDebugLine.h
DWARFContext.h
llvm::DWARFObject::getFile
virtual const object::ObjectFile * getFile() const
Definition: DWARFObject.h:31
llvm::DWARFVerifier::DWARFVerifier
DWARFVerifier(raw_ostream &S, DWARFContext &D, DIDumpOptions DumpOpts=DIDumpOptions::getForSingleDIE())
Definition: DWARFVerifier.cpp:874
llvm::DWARFFormValue::getAsUnsignedConstant
Optional< uint64_t > getAsUnsignedConstant() const
Definition: DWARFFormValue.cpp:724
llvm::StringMap::end
iterator end()
Definition: StringMap.h:203
llvm::DWARFContext
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:53
llvm::DWARFObject::forEachInfoSections
virtual void forEachInfoSections(function_ref< void(const DWARFSection &)> F) const
Definition: DWARFObject.h:36
llvm::DWARFDebugNames::NameIndex::getLocalTUCount
uint32_t getLocalTUCount() const
Definition: DWARFAcceleratorTable.h:429
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::DWARFDebugNames::NameTableEntry
A single entry in the Name Table (DWARF v5 sect.
Definition: DWARFAcceleratorTable.h:356
error
#define error(X)
Definition: SymbolRecordMapping.cpp:14
llvm::DWARFDebugNames::NameIndex::getBucketCount
uint32_t getBucketCount() const
Definition: DWARFAcceleratorTable.h:439
llvm::Optional
Definition: APInt.h:33
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:80
llvm::DWARFDebugNames::AttributeEncoding::Form
dwarf::Form Form
Definition: DWARFAcceleratorTable.h:258
llvm::DIE
A structured debug information entry.
Definition: DIE.h:739
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:876
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::DWARFDebugInfoEntry
DWARFDebugInfoEntry - A DIE with only the minimum required data.
Definition: DWARFDebugInfoEntry.h:22
llvm::AccelTable
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:197
llvm::DWARFFormValue::FC_Reference
@ FC_Reference
Definition: DWARFFormValue.h:35
RHS
Value * RHS
Definition: X86PartialReduction.cpp:74
llvm::DataExtractor::getU64
uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
Definition: DataExtractor.cpp:117
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:216
llvm::DWARFUnit::getFormParams
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:282
llvm::DIE::getTag
dwarf::Tag getTag() const
Definition: DIE.h:775
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:104
llvm::DWARFVerifier::handleDebugInfo
bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
Definition: DWARFVerifier.cpp:384
llvm::dwarf::FormParams::Format
DwarfFormat Format
Definition: Dwarf.h:651
llvm::dwarf::isUnitType
bool isUnitType(uint8_t UnitType)
Definition: Dwarf.h:474
llvm::DWARFUnit::isDWOUnit
bool isDWOUnit() const
Definition: DWARFUnit.h:278
llvm::DWARFDebugNames::Abbrev
Abbreviation describing the encoding of Name Index entries.
Definition: DWARFAcceleratorTable.h:270
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1045
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::DWARFDebugNames::AttributeEncoding
Index attribute and its encoding.
Definition: DWARFAcceleratorTable.h:256
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::WithColor::error
static raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition: WithColor.cpp:75
llvm::DWARFDebugNames::NameIndex::getBucketArrayEntry
uint32_t getBucketArrayEntry(uint32_t Bucket) const
Reads an entry in the Bucket Array for the given Bucket.
Definition: DWARFAcceleratorTable.cpp:654
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
llvm::DWARFObject::forEachTypesSections
virtual void forEachTypesSections(function_ref< void(const DWARFSection &)> F) const
Definition: DWARFObject.h:38
llvm::DWARFUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:390
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::DWARFAttribute
Encapsulates a DWARF attribute value and all of the data required to describe the attribute value.
Definition: DWARFAttribute.h:24
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:890
getNames
static SmallVector< StringRef, 2 > getNames(const DWARFDie &DIE, bool IncludeLinkageName=true)
Definition: DWARFVerifier.cpp:1262
DWARFVerifier.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition: DWARFExpression.h:35
llvm::DWARFDebugAbbrev
Definition: DWARFDebugAbbrev.h:56
llvm::DWARFDebugNames::NameIndex
Represents a single accelerator table within the DWARF v5 .debug_names section.
Definition: DWARFAcceleratorTable.h:388
llvm::DWARFDebugNames::NameIndex::getEntry
Expected< Entry > getEntry(uint64_t *Offset) const
Definition: DWARFAcceleratorTable.cpp:611
DWARFSection.h
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::DWARFDebugNames::NameIndex::getHashArrayEntry
uint32_t getHashArrayEntry(uint32_t Index) const
Reads an entry in the Hash Array for the given Index.
Definition: DWARFAcceleratorTable.cpp:660
llvm::DWARFDebugNames::NameIndex::equal_range
iterator_range< ValueIterator > equal_range(StringRef Key) const
Look up all entries in this Name Index matching Key.
Definition: DWARFAcceleratorTable.cpp:787
llvm::DWARFFormValue::getAsSectionOffset
Optional< uint64_t > getAsSectionOffset() const
Definition: DWARFFormValue.cpp:718
llvm::DWARFContext::getNumCompileUnits
unsigned getNumCompileUnits()
Get the number of compile units in this context.
Definition: DWARFContext.h:222
DWARFDie.h
false
Definition: StackSlotColoring.cpp:142
llvm::DWARFFormValue::getAsCString
Expected< const char * > getAsCString() const
Definition: DWARFFormValue.cpp:624
llvm::DWARFDebugNames::NameIndex::getForeignTUCount
uint32_t getForeignTUCount() const
Definition: DWARFAcceleratorTable.h:433
llvm::dwarf::Index
Index
Definition: Dwarf.h:467
llvm::dwarf::toStringRef
StringRef toStringRef(const Optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:191
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::dwarf::toSectionOffset
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Definition: DWARFFormValue.h:316
llvm::DWARFVerifier::handleDebugLine
bool handleDebugLine()
Verify the information in the .debug_line section.
Definition: DWARFVerifier.cpp:884
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::DWARFObject
Definition: DWARFObject.h:25
llvm::DWARFFormValue
Definition: DWARFFormValue.h:26
llvm::DWARFObject::getRangesSection
virtual const DWARFSection & getRangesSection() const
Definition: DWARFObject.h:48
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::DWARFUnit::getLineSection
const DWARFSection & getLineSection() const
Definition: DWARFUnit.h:299
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:92
FormatVariadic.h
llvm::None
const NoneType None
Definition: None.h:23
llvm::ErrorInfoBase
Base class for error info classes.
Definition: Error.h:48
llvm::dwarf::FormEncodingString
StringRef FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:105
llvm::DWARFContext::compile_units
compile_unit_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:174
llvm::DWARFVerifier::handleAccelTables
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
Definition: DWARFVerifier.cpp:1532
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:108
llvm::DWARFDebugNames::AttributeEncoding::Index
dwarf::Index Index
Definition: DWARFAcceleratorTable.h:257
llvm::DWARFDie::dump
void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const
Dump the DIE and all of its attributes to the supplied stream.
Definition: DWARFDie.cpp:1076
llvm::DWARFDebugNames::NameTableEntry::getIndex
uint32_t getIndex() const
Return the index of this name in the parent Name Index.
Definition: DWARFAcceleratorTable.h:370
llvm::DWARFVerifier::DieRangeInfo::die_range_info_iterator
std::set< DieRangeInfo >::const_iterator die_range_info_iterator
Definition: DWARFVerifier.h:53
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:223
llvm::DWARFAbbreviationDeclarationSet
Definition: DWARFDebugAbbrev.h:22
llvm::WithColor::warning
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition: WithColor.cpp:77
llvm::DWARFUnit::isMatchingUnitTypeAndTag
static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag)
Definition: DWARFUnit.h:371
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::DWARFObject::getAbbrevSection
virtual StringRef getAbbrevSection() const
Definition: DWARFObject.h:39
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:152
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
llvm::dwarf::isType
bool isType(Tag T)
Definition: Dwarf.h:112
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::DWARFVerifier::handleDebugAbbrev
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev,...
Definition: DWARFVerifier.cpp:308
llvm::DWARFUnit::isTypeUnit
bool isTypeUnit() const
Definition: DWARFUnit.h:296
llvm::caseFoldingDjbHash
uint32_t caseFoldingDjbHash(StringRef Buffer, uint32_t H=5381)
Computes the Bernstein hash after folding the input according to the Dwarf 5 standard case folding ru...
Definition: DJB.cpp:71
llvm::DWARFDie::getAddressRanges
Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
Definition: DWARFDie.cpp:949
llvm::DWARFVerifier::DieRangeInfo::intersects
bool intersects(const DieRangeInfo &RHS) const
Return true if any range in this object intersects with any range in RHS.
Definition: DWARFVerifier.cpp:93
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap
Definition: DenseMap.h:714
llvm::DWARFFormValue::FormClass
FormClass
Definition: DWARFFormValue.h:28
llvm::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:338
llvm::DWARFDebugLine::Row::dumpTableHeader
static void dumpTableHeader(raw_ostream &OS, unsigned Indent)
Definition: DWARFDebugLine.cpp:486
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::DWARFDie::find
Optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:821
Attributes
AMDGPU Kernel Attributes
Definition: AMDGPULowerKernelAttributes.cpp:254
llvm::DWARFDie::getOffset
uint64_t getOffset() const
Get the absolute offset into the debug info or types section.
Definition: DWARFDie.h:67
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1714
llvm::DWARFExpression
Definition: DWARFExpression.h:25
llvm::dwarf::UnitType
UnitType
Constants for unit types in DWARF v5.
Definition: Dwarf.h:460
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::DataExtractor::isValidOffset
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Definition: DataExtractor.h:665
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1707
llvm::DWARFDebugNames::SentinelError
Error returned by NameIndex::getEntry to report it has reached the end of the entry list.
Definition: DWARFAcceleratorTable.h:326
llvm::DWARFDataExtractor::getInitialLength
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(uint64_t *Off, Error *Err=nullptr) const
Extracts the DWARF "initial length" field, which can either be a 32-bit value smaller than 0xfffffff0...
Definition: DWARFDataExtractor.cpp:15
llvm::DWARFContext::isAddressSizeSupported
static bool isAddressSizeSupported(unsigned AddressSize)
Definition: DWARFContext.h:388
llvm::DWARFDie::findRecursively
Optional< DWARFFormValue > findRecursively(ArrayRef< dwarf::Attribute > Attrs) const
Extract the first value of any attribute in Attrs from this DIE and recurse into any DW_AT_specificat...
Definition: DWARFDie.cpp:845
llvm::DWARFDebugAbbrev::getAbbreviationDeclarationSet
const DWARFAbbreviationDeclarationSet * getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const
Definition: DWARFDebugAbbrev.cpp:143
llvm::dwarf::toString
Optional< const char * > toString(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:175
llvm::DataExtractor::getU32
uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:108
llvm::Expression
Class representing an expression and its matching format.
Definition: FileCheckImpl.h:237
llvm::DWARFDie::getLocations
Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition: DWARFDie.cpp:980
llvm::DataExtractor::getCStr
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
Definition: DataExtractor.h:129
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::DWARFContext::isLittleEndian
bool isLittleEndian() const
Definition: DWARFContext.h:379
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1656
llvm::DWARFDie::hasChildren
bool hasChildren() const
Definition: DWARFDie.h:79
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Dwarf.h
llvm::DWARFUnit::getContext
DWARFContext & getContext() const
Definition: DWARFUnit.h:279
llvm::DWARFDie::getDwarfUnit
DWARFUnit * getDwarfUnit() const
Definition: DWARFDie.h:54
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::AppleAcceleratorTable
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
Definition: DWARFAcceleratorTable.h:83
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::DWARFFormValue::getRawUValue
uint64_t getRawUValue() const
Definition: DWARFFormValue.h:78
llvm::DataExtractor::getU8
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
Definition: DataExtractor.cpp:80
llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
@ AbsoluteFilePath
llvm::DWARFContext::getDIEForOffset
DWARFDie getDIEForOffset(uint64_t Offset)
Get a DIE given an exact offset.
Definition: DWARFContext.cpp:754
llvm::DWARFObject::getAbbrevDWOSection
virtual StringRef getAbbrevDWOSection() const
Definition: DWARFObject.h:63
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1676
llvm::DWARFDebugNames::Entry
DWARF v5-specific implementation of an Accelerator Entry.
Definition: DWARFAcceleratorTable.h:283
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:156
WithColor.h
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::DWARFDie::getParent
DWARFDie getParent() const
Get the parent of this DIE object.
Definition: DWARFDie.cpp:1136
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:286
llvm::DWARFAddressRangesVector
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
Definition: DWARFAddressRange.h:85
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
uint16_t
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:83
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:325
llvm::DWARFDebugNames::NameTableEntry::getEntryOffset
uint64_t getEntryOffset() const
Returns the offset of the first Entry in the list.
Definition: DWARFAcceleratorTable.h:383
llvm::DWARFUnit
Definition: DWARFUnit.h:203
llvm::DWARFDebugNames::NameIndex::getUnitOffset
uint64_t getUnitOffset() const
Definition: DWARFAcceleratorTable.h:466
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
Success
#define Success
Definition: AArch64Disassembler.cpp:266
llvm::DWARFVerifier::DieRangeInfo
A class that keeps the address range information for a single DIE.
Definition: DWARFVerifier.h:37
llvm::DWARFUnit::getOffset
uint64_t getOffset() const
Definition: DWARFUnit.h:281
DWARFExpression.h
llvm::DWARFDie::getFullName
void getFullName(raw_string_ostream &, std::string *OriginalFullName=nullptr) const
Definition: DWARFDie.cpp:804
llvm::DWARFDebugNames::Abbrev::Code
uint32_t Code
Abbreviation code.
Definition: DWARFAcceleratorTable.h:271
DWARFUnitIndex.h
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:599
llvm::DWARFDie::getAttributeValueAsReferencedDie
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition: DWARFDie.cpp:878
llvm::DWARFDebugNames::NameIndex::getNameCount
uint32_t getNameCount() const
Definition: DWARFAcceleratorTable.h:451
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::AttributeSet
Definition: Attributes.h:271
llvm::DWARFDie::getTag
dwarf::Tag getTag() const
Definition: DWARFDie.h:72
Version
uint64_t Version
Definition: RawMemProfReader.cpp:25
llvm::DWARFDie::attributes
iterator_range< attribute_iterator > attributes() const
Get an iterator range to all attributes in the current DIE only.
Definition: DWARFDie.cpp:1166
llvm::DWARFObject::getRnglistsSection
virtual const DWARFSection & getRnglistsSection() const
Definition: DWARFObject.h:49
llvm::DWARFDebugNames::NameIndex::getNameTableEntry
NameTableEntry getNameTableEntry(uint32_t Index) const
Reads an entry in the Name Table for the given Index.
Definition: DWARFAcceleratorTable.cpp:637
llvm::DWARFFormValue::isFormClass
bool isFormClass(FormClass FC) const
Definition: DWARFFormValue.cpp:212
llvm::DWARFContext::getDWARFObj
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:132
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::DWARFFormValue::getForm
dwarf::Form getForm() const
Definition: DWARFFormValue.h:77
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::reserve
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition: DenseMap.h:104
llvm::DWARFFormValue::getAsReference
Optional< uint64_t > getAsReference() const
getAsFoo functions below return the extracted value as Foo if only DWARFFormValue has form class is s...
Definition: DWARFFormValue.cpp:691
llvm::DWARFVerifier::DieRangeInfo::contains
bool contains(const DieRangeInfo &RHS) const
Return true if ranges in this object contains all ranges within RHS.
Definition: DWARFVerifier.cpp:69
llvm::dwarf::DWARF64
@ DWARF64
Definition: Dwarf.h:92
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:43
llvm::WithColor::note
static raw_ostream & note()
Convenience method for printing "note: " to stderr.
Definition: WithColor.cpp:79
llvm::DWARFAddressRange
Definition: DWARFAddressRange.h:22
llvm::DWARFDie::isSubprogramDIE
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
Definition: DWARFDie.cpp:814
llvm::DWARFDebugNames
.debug_names section consists of one or more units.
Definition: DWARFAcceleratorTable.h:231
llvm::DWARFUnit::getDIEForOffset
DWARFDie getDIEForOffset(uint64_t Offset)
Return the DIE object for a given offset inside the unit's DIE vector.
Definition: DWARFUnit.h:479
llvm::dwarf::TagString
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
llvm::DWARFDebugNames::NameIndex::getAbbrevs
const DenseSet< Abbrev, AbbrevMapInfo > & getAbbrevs() const
Definition: DWARFAcceleratorTable.h:453
llvm::DWARFDebugNames::NameIndex::getCUCount
uint32_t getCUCount() const
Definition: DWARFAcceleratorTable.h:425
raw_ostream.h
llvm::DIE::getOffset
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:777
llvm::DWARFContext::isSupportedVersion
static bool isSupportedVersion(unsigned version)
Definition: DWARFContext.h:381
llvm::DWARFDebugNames::NameIndex::getCUOffset
uint64_t getCUOffset(uint32_t CU) const
Reads offset of compilation unit CU. CU is 0-based.
Definition: DWARFAcceleratorTable.cpp:587
TableRef
Definition: AMDGPULibCalls.cpp:378
llvm::DWARFSection::Data
StringRef Data
Definition: DWARFSection.h:17
CU
Definition: AArch64AsmBackend.cpp:504
llvm::DWARFVerifier::DieRangeInfo::insert
Optional< DWARFAddressRange > insert(const DWARFAddressRange &R)
Inserts the address range.
Definition: DWARFVerifier.cpp:32
llvm::handleAllErrors
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:968
llvm::dwarf::UnitTypeString
StringRef UnitTypeString(unsigned)
Definition: Dwarf.cpp:576
llvm::dwarf::AttributeString
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
llvm::DWARFUnit::getVersion
uint16_t getVersion() const
Definition: DWARFUnit.h:285
llvm::DWARFDie::getFirstChild
DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition: DWARFDie.cpp:1154
isVariableIndexable
static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx)
Definition: DWARFVerifier.cpp:1362
SmallSet.h
llvm::DataExtractor::getU16
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
Definition: DataExtractor.cpp:93
llvm::DIDumpOptions
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:180
llvm::DWARFUnitVector
Describe a collection of units.
Definition: DWARFUnit.h:120