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