LLVM  16.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  case DW_AT_call_line:
708  case DW_AT_decl_line: {
709  if (!AttrValue.Value.getAsUnsignedConstant()) {
710  ReportError("DIE has " + AttributeString(Attr) +
711  " with invalid encoding");
712  }
713  break;
714  }
715  default:
716  break;
717  }
718  return NumErrors;
719 }
720 
721 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
722  DWARFAttribute &AttrValue,
723  ReferenceMap &LocalReferences,
724  ReferenceMap &CrossUnitReferences) {
725  auto DieCU = Die.getDwarfUnit();
726  unsigned NumErrors = 0;
727  const auto Form = AttrValue.Value.getForm();
728  switch (Form) {
729  case DW_FORM_ref1:
730  case DW_FORM_ref2:
731  case DW_FORM_ref4:
732  case DW_FORM_ref8:
733  case DW_FORM_ref_udata: {
734  // Verify all CU relative references are valid CU offsets.
735  Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
736  assert(RefVal);
737  if (RefVal) {
738  auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
739  auto CUOffset = AttrValue.Value.getRawUValue();
740  if (CUOffset >= CUSize) {
741  ++NumErrors;
742  error() << FormEncodingString(Form) << " CU offset "
743  << format("0x%08" PRIx64, CUOffset)
744  << " is invalid (must be less than CU size of "
745  << format("0x%08" PRIx64, CUSize) << "):\n";
746  Die.dump(OS, 0, DumpOpts);
747  dump(Die) << '\n';
748  } else {
749  // Valid reference, but we will verify it points to an actual
750  // DIE later.
751  LocalReferences[*RefVal].insert(Die.getOffset());
752  }
753  }
754  break;
755  }
756  case DW_FORM_ref_addr: {
757  // Verify all absolute DIE references have valid offsets in the
758  // .debug_info section.
759  Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
760  assert(RefVal);
761  if (RefVal) {
762  if (*RefVal >= DieCU->getInfoSection().Data.size()) {
763  ++NumErrors;
764  error() << "DW_FORM_ref_addr offset beyond .debug_info "
765  "bounds:\n";
766  dump(Die) << '\n';
767  } else {
768  // Valid reference, but we will verify it points to an actual
769  // DIE later.
770  CrossUnitReferences[*RefVal].insert(Die.getOffset());
771  }
772  }
773  break;
774  }
775  case DW_FORM_strp:
776  case DW_FORM_strx:
777  case DW_FORM_strx1:
778  case DW_FORM_strx2:
779  case DW_FORM_strx3:
780  case DW_FORM_strx4: {
781  if (Error E = AttrValue.Value.getAsCString().takeError()) {
782  ++NumErrors;
783  error() << toString(std::move(E)) << ":\n";
784  dump(Die) << '\n';
785  }
786  break;
787  }
788  default:
789  break;
790  }
791  return NumErrors;
792 }
793 
794 unsigned DWARFVerifier::verifyDebugInfoReferences(
795  const ReferenceMap &References,
796  llvm::function_ref<DWARFUnit *(uint64_t)> GetUnitForOffset) {
797  auto GetDIEForOffset = [&](uint64_t Offset) {
798  if (DWARFUnit *U = GetUnitForOffset(Offset))
799  return U->getDIEForOffset(Offset);
800  return DWARFDie();
801  };
802  unsigned NumErrors = 0;
803  for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
804  References) {
805  if (GetDIEForOffset(Pair.first))
806  continue;
807  ++NumErrors;
808  error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
809  << ". Offset is in between DIEs:\n";
810  for (auto Offset : Pair.second)
811  dump(GetDIEForOffset(Offset)) << '\n';
812  OS << "\n";
813  }
814  return NumErrors;
815 }
816 
817 void DWARFVerifier::verifyDebugLineStmtOffsets() {
818  std::map<uint64_t, DWARFDie> StmtListToDie;
819  for (const auto &CU : DCtx.compile_units()) {
820  auto Die = CU->getUnitDIE();
821  // Get the attribute value as a section offset. No need to produce an
822  // error here if the encoding isn't correct because we validate this in
823  // the .debug_info verifier.
824  auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
825  if (!StmtSectionOffset)
826  continue;
827  const uint64_t LineTableOffset = *StmtSectionOffset;
828  auto LineTable = DCtx.getLineTableForUnit(CU.get());
829  if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
830  if (!LineTable) {
831  ++NumDebugLineErrors;
832  error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
833  << "] was not able to be parsed for CU:\n";
834  dump(Die) << '\n';
835  continue;
836  }
837  } else {
838  // Make sure we don't get a valid line table back if the offset is wrong.
839  assert(LineTable == nullptr);
840  // Skip this line table as it isn't valid. No need to create an error
841  // here because we validate this in the .debug_info verifier.
842  continue;
843  }
844  auto Iter = StmtListToDie.find(LineTableOffset);
845  if (Iter != StmtListToDie.end()) {
846  ++NumDebugLineErrors;
847  error() << "two compile unit DIEs, "
848  << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
849  << format("0x%08" PRIx64, Die.getOffset())
850  << ", have the same DW_AT_stmt_list section offset:\n";
851  dump(Iter->second);
852  dump(Die) << '\n';
853  // Already verified this line table before, no need to do it again.
854  continue;
855  }
856  StmtListToDie[LineTableOffset] = Die;
857  }
858 }
859 
860 void DWARFVerifier::verifyDebugLineRows() {
861  for (const auto &CU : DCtx.compile_units()) {
862  auto Die = CU->getUnitDIE();
863  auto LineTable = DCtx.getLineTableForUnit(CU.get());
864  // If there is no line table we will have created an error in the
865  // .debug_info verifier or in verifyDebugLineStmtOffsets().
866  if (!LineTable)
867  continue;
868 
869  // Verify prologue.
870  uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
871  uint32_t FileIndex = 1;
872  StringMap<uint16_t> FullPathMap;
873  for (const auto &FileName : LineTable->Prologue.FileNames) {
874  // Verify directory index.
875  if (FileName.DirIdx > MaxDirIndex) {
876  ++NumDebugLineErrors;
877  error() << ".debug_line["
878  << format("0x%08" PRIx64,
879  *toSectionOffset(Die.find(DW_AT_stmt_list)))
880  << "].prologue.file_names[" << FileIndex
881  << "].dir_idx contains an invalid index: " << FileName.DirIdx
882  << "\n";
883  }
884 
885  // Check file paths for duplicates.
886  std::string FullPath;
887  const bool HasFullPath = LineTable->getFileNameByIndex(
888  FileIndex, CU->getCompilationDir(),
890  assert(HasFullPath && "Invalid index?");
891  (void)HasFullPath;
892  auto It = FullPathMap.find(FullPath);
893  if (It == FullPathMap.end())
894  FullPathMap[FullPath] = FileIndex;
895  else if (It->second != FileIndex) {
896  warn() << ".debug_line["
897  << format("0x%08" PRIx64,
898  *toSectionOffset(Die.find(DW_AT_stmt_list)))
899  << "].prologue.file_names[" << FileIndex
900  << "] is a duplicate of file_names[" << It->second << "]\n";
901  }
902 
903  FileIndex++;
904  }
905 
906  // Verify rows.
907  uint64_t PrevAddress = 0;
908  uint32_t RowIndex = 0;
909  for (const auto &Row : LineTable->Rows) {
910  // Verify row address.
911  if (Row.Address.Address < PrevAddress) {
912  ++NumDebugLineErrors;
913  error() << ".debug_line["
914  << format("0x%08" PRIx64,
915  *toSectionOffset(Die.find(DW_AT_stmt_list)))
916  << "] row[" << RowIndex
917  << "] decreases in address from previous row:\n";
918 
920  if (RowIndex > 0)
921  LineTable->Rows[RowIndex - 1].dump(OS);
922  Row.dump(OS);
923  OS << '\n';
924  }
925 
926  // Verify file index.
927  if (!LineTable->hasFileAtIndex(Row.File)) {
928  ++NumDebugLineErrors;
929  bool isDWARF5 = LineTable->Prologue.getVersion() >= 5;
930  error() << ".debug_line["
931  << format("0x%08" PRIx64,
932  *toSectionOffset(Die.find(DW_AT_stmt_list)))
933  << "][" << RowIndex << "] has invalid file index " << Row.File
934  << " (valid values are [" << (isDWARF5 ? "0," : "1,")
935  << LineTable->Prologue.FileNames.size()
936  << (isDWARF5 ? ")" : "]") << "):\n";
938  Row.dump(OS);
939  OS << '\n';
940  }
941  if (Row.EndSequence)
942  PrevAddress = 0;
943  else
944  PrevAddress = Row.Address.Address;
945  ++RowIndex;
946  }
947  }
948 }
949 
951  DIDumpOptions DumpOpts)
952  : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
953  IsMachOObject(false) {
954  if (const auto *F = DCtx.getDWARFObj().getFile()) {
955  IsObjectFile = F->isRelocatableObject();
956  IsMachOObject = F->isMachO();
957  }
958 }
959 
961  NumDebugLineErrors = 0;
962  OS << "Verifying .debug_line...\n";
963  verifyDebugLineStmtOffsets();
964  verifyDebugLineRows();
965  return NumDebugLineErrors == 0;
966 }
967 
968 unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
969  DataExtractor *StrData,
970  const char *SectionName) {
971  unsigned NumErrors = 0;
972  DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
973  DCtx.isLittleEndian(), 0);
974  AppleAcceleratorTable AccelTable(AccelSectionData, *StrData);
975 
976  OS << "Verifying " << SectionName << "...\n";
977 
978  // Verify that the fixed part of the header is not too short.
979  if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
980  error() << "Section is too small to fit a section header.\n";
981  return 1;
982  }
983 
984  // Verify that the section is not too short.
985  if (Error E = AccelTable.extract()) {
986  error() << toString(std::move(E)) << '\n';
987  return 1;
988  }
989 
990  // Verify that all buckets have a valid hash index or are empty.
991  uint32_t NumBuckets = AccelTable.getNumBuckets();
992  uint32_t NumHashes = AccelTable.getNumHashes();
993 
994  uint64_t BucketsOffset =
995  AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
996  uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
997  uint64_t OffsetsBase = HashesBase + NumHashes * 4;
998  for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
999  uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
1000  if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
1001  error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
1002  HashIdx);
1003  ++NumErrors;
1004  }
1005  }
1006  uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
1007  if (NumAtoms == 0) {
1008  error() << "No atoms: failed to read HashData.\n";
1009  return 1;
1010  }
1011  if (!AccelTable.validateForms()) {
1012  error() << "Unsupported form: failed to read HashData.\n";
1013  return 1;
1014  }
1015 
1016  for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
1017  uint64_t HashOffset = HashesBase + 4 * HashIdx;
1018  uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
1019  uint32_t Hash = AccelSectionData.getU32(&HashOffset);
1020  uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
1021  if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
1022  sizeof(uint64_t))) {
1023  error() << format("Hash[%d] has invalid HashData offset: "
1024  "0x%08" PRIx64 ".\n",
1025  HashIdx, HashDataOffset);
1026  ++NumErrors;
1027  }
1028 
1029  uint64_t StrpOffset;
1030  uint64_t StringOffset;
1031  uint32_t StringCount = 0;
1032  uint64_t Offset;
1033  unsigned Tag;
1034  while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
1035  const uint32_t NumHashDataObjects =
1036  AccelSectionData.getU32(&HashDataOffset);
1037  for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
1038  ++HashDataIdx) {
1039  std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
1040  auto Die = DCtx.getDIEForOffset(Offset);
1041  if (!Die) {
1042  const uint32_t BucketIdx =
1043  NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
1044  StringOffset = StrpOffset;
1045  const char *Name = StrData->getCStr(&StringOffset);
1046  if (!Name)
1047  Name = "<NULL>";
1048 
1049  error() << format(
1050  "%s Bucket[%d] Hash[%d] = 0x%08x "
1051  "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
1052  "is not a valid DIE offset for \"%s\".\n",
1053  SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
1054  HashDataIdx, Offset, Name);
1055 
1056  ++NumErrors;
1057  continue;
1058  }
1059  if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
1060  error() << "Tag " << dwarf::TagString(Tag)
1061  << " in accelerator table does not match Tag "
1062  << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
1063  << "].\n";
1064  ++NumErrors;
1065  }
1066  }
1067  ++StringCount;
1068  }
1069  }
1070  return NumErrors;
1071 }
1072 
1073 unsigned
1074 DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
1075  // A map from CU offset to the (first) Name Index offset which claims to index
1076  // this CU.
1078  const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
1079 
1080  CUMap.reserve(DCtx.getNumCompileUnits());
1081  for (const auto &CU : DCtx.compile_units())
1082  CUMap[CU->getOffset()] = NotIndexed;
1083 
1084  unsigned NumErrors = 0;
1085  for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
1086  if (NI.getCUCount() == 0) {
1087  error() << formatv("Name Index @ {0:x} does not index any CU\n",
1088  NI.getUnitOffset());
1089  ++NumErrors;
1090  continue;
1091  }
1092  for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
1093  uint64_t Offset = NI.getCUOffset(CU);
1094  auto Iter = CUMap.find(Offset);
1095 
1096  if (Iter == CUMap.end()) {
1097  error() << formatv(
1098  "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
1099  NI.getUnitOffset(), Offset);
1100  ++NumErrors;
1101  continue;
1102  }
1103 
1104  if (Iter->second != NotIndexed) {
1105  error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
1106  "this CU is already indexed by Name Index @ {2:x}\n",
1107  NI.getUnitOffset(), Offset, Iter->second);
1108  continue;
1109  }
1110  Iter->second = NI.getUnitOffset();
1111  }
1112  }
1113 
1114  for (const auto &KV : CUMap) {
1115  if (KV.second == NotIndexed)
1116  warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
1117  }
1118 
1119  return NumErrors;
1120 }
1121 
1122 unsigned
1123 DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
1124  const DataExtractor &StrData) {
1125  struct BucketInfo {
1126  uint32_t Bucket;
1127  uint32_t Index;
1128 
1129  constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
1130  : Bucket(Bucket), Index(Index) {}
1131  bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
1132  };
1133 
1134  uint32_t NumErrors = 0;
1135  if (NI.getBucketCount() == 0) {
1136  warn() << formatv("Name Index @ {0:x} does not contain a hash table.\n",
1137  NI.getUnitOffset());
1138  return NumErrors;
1139  }
1140 
1141  // Build up a list of (Bucket, Index) pairs. We use this later to verify that
1142  // each Name is reachable from the appropriate bucket.
1143  std::vector<BucketInfo> BucketStarts;
1144  BucketStarts.reserve(NI.getBucketCount() + 1);
1145  for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End; ++Bucket) {
1146  uint32_t Index = NI.getBucketArrayEntry(Bucket);
1147  if (Index > NI.getNameCount()) {
1148  error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
1149  "value {2}. Valid range is [0, {3}].\n",
1150  Bucket, NI.getUnitOffset(), Index, NI.getNameCount());
1151  ++NumErrors;
1152  continue;
1153  }
1154  if (Index > 0)
1155  BucketStarts.emplace_back(Bucket, Index);
1156  }
1157 
1158  // If there were any buckets with invalid values, skip further checks as they
1159  // will likely produce many errors which will only confuse the actual root
1160  // problem.
1161  if (NumErrors > 0)
1162  return NumErrors;
1163 
1164  // Sort the list in the order of increasing "Index" entries.
1165  array_pod_sort(BucketStarts.begin(), BucketStarts.end());
1166 
1167  // Insert a sentinel entry at the end, so we can check that the end of the
1168  // table is covered in the loop below.
1169  BucketStarts.emplace_back(NI.getBucketCount(), NI.getNameCount() + 1);
1170 
1171  // Loop invariant: NextUncovered is the (1-based) index of the first Name
1172  // which is not reachable by any of the buckets we processed so far (and
1173  // hasn't been reported as uncovered).
1174  uint32_t NextUncovered = 1;
1175  for (const BucketInfo &B : BucketStarts) {
1176  // Under normal circumstances B.Index be equal to NextUncovered, but it can
1177  // be less if a bucket points to names which are already known to be in some
1178  // bucket we processed earlier. In that case, we won't trigger this error,
1179  // but report the mismatched hash value error instead. (We know the hash
1180  // will not match because we have already verified that the name's hash
1181  // puts it into the previous bucket.)
1182  if (B.Index > NextUncovered) {
1183  error() << formatv("Name Index @ {0:x}: Name table entries [{1}, {2}] "
1184  "are not covered by the hash table.\n",
1185  NI.getUnitOffset(), NextUncovered, B.Index - 1);
1186  ++NumErrors;
1187  }
1188  uint32_t Idx = B.Index;
1189 
1190  // The rest of the checks apply only to non-sentinel entries.
1191  if (B.Bucket == NI.getBucketCount())
1192  break;
1193 
1194  // This triggers if a non-empty bucket points to a name with a mismatched
1195  // hash. Clients are likely to interpret this as an empty bucket, because a
1196  // mismatched hash signals the end of a bucket, but if this is indeed an
1197  // empty bucket, the producer should have signalled this by marking the
1198  // bucket as empty.
1199  uint32_t FirstHash = NI.getHashArrayEntry(Idx);
1200  if (FirstHash % NI.getBucketCount() != B.Bucket) {
1201  error() << formatv(
1202  "Name Index @ {0:x}: Bucket {1} is not empty but points to a "
1203  "mismatched hash value {2:x} (belonging to bucket {3}).\n",
1204  NI.getUnitOffset(), B.Bucket, FirstHash,
1205  FirstHash % NI.getBucketCount());
1206  ++NumErrors;
1207  }
1208 
1209  // This find the end of this bucket and also verifies that all the hashes in
1210  // this bucket are correct by comparing the stored hashes to the ones we
1211  // compute ourselves.
1212  while (Idx <= NI.getNameCount()) {
1213  uint32_t Hash = NI.getHashArrayEntry(Idx);
1214  if (Hash % NI.getBucketCount() != B.Bucket)
1215  break;
1216 
1217  const char *Str = NI.getNameTableEntry(Idx).getString();
1218  if (caseFoldingDjbHash(Str) != Hash) {
1219  error() << formatv("Name Index @ {0:x}: String ({1}) at index {2} "
1220  "hashes to {3:x}, but "
1221  "the Name Index hash is {4:x}\n",
1222  NI.getUnitOffset(), Str, Idx,
1223  caseFoldingDjbHash(Str), Hash);
1224  ++NumErrors;
1225  }
1226 
1227  ++Idx;
1228  }
1229  NextUncovered = std::max(NextUncovered, Idx);
1230  }
1231  return NumErrors;
1232 }
1233 
1234 unsigned DWARFVerifier::verifyNameIndexAttribute(
1235  const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr,
1237  StringRef FormName = dwarf::FormEncodingString(AttrEnc.Form);
1238  if (FormName.empty()) {
1239  error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
1240  "unknown form: {3}.\n",
1241  NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
1242  AttrEnc.Form);
1243  return 1;
1244  }
1245 
1246  if (AttrEnc.Index == DW_IDX_type_hash) {
1247  if (AttrEnc.Form != dwarf::DW_FORM_data8) {
1248  error() << formatv(
1249  "NameIndex @ {0:x}: Abbreviation {1:x}: DW_IDX_type_hash "
1250  "uses an unexpected form {2} (should be {3}).\n",
1251  NI.getUnitOffset(), Abbr.Code, AttrEnc.Form, dwarf::DW_FORM_data8);
1252  return 1;
1253  }
1254  }
1255 
1256  // A list of known index attributes and their expected form classes.
1257  // DW_IDX_type_hash is handled specially in the check above, as it has a
1258  // specific form (not just a form class) we should expect.
1259  struct FormClassTable {
1262  StringLiteral ClassName;
1263  };
1264  static constexpr FormClassTable Table[] = {
1265  {dwarf::DW_IDX_compile_unit, DWARFFormValue::FC_Constant, {"constant"}},
1266  {dwarf::DW_IDX_type_unit, DWARFFormValue::FC_Constant, {"constant"}},
1267  {dwarf::DW_IDX_die_offset, DWARFFormValue::FC_Reference, {"reference"}},
1268  {dwarf::DW_IDX_parent, DWARFFormValue::FC_Constant, {"constant"}},
1269  };
1270 
1272  auto Iter = find_if(TableRef, [AttrEnc](const FormClassTable &T) {
1273  return T.Index == AttrEnc.Index;
1274  });
1275  if (Iter == TableRef.end()) {
1276  warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains an "
1277  "unknown index attribute: {2}.\n",
1278  NI.getUnitOffset(), Abbr.Code, AttrEnc.Index);
1279  return 0;
1280  }
1281 
1282  if (!DWARFFormValue(AttrEnc.Form).isFormClass(Iter->Class)) {
1283  error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
1284  "unexpected form {3} (expected form class {4}).\n",
1285  NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
1286  AttrEnc.Form, Iter->ClassName);
1287  return 1;
1288  }
1289  return 0;
1290 }
1291 
1292 unsigned
1293 DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
1294  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
1295  warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
1296  "not currently supported.\n",
1297  NI.getUnitOffset());
1298  return 0;
1299  }
1300 
1301  unsigned NumErrors = 0;
1302  for (const auto &Abbrev : NI.getAbbrevs()) {
1303  StringRef TagName = dwarf::TagString(Abbrev.Tag);
1304  if (TagName.empty()) {
1305  warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} references an "
1306  "unknown tag: {2}.\n",
1307  NI.getUnitOffset(), Abbrev.Code, Abbrev.Tag);
1308  }
1310  for (const auto &AttrEnc : Abbrev.Attributes) {
1311  if (!Attributes.insert(AttrEnc.Index).second) {
1312  error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains "
1313  "multiple {2} attributes.\n",
1314  NI.getUnitOffset(), Abbrev.Code, AttrEnc.Index);
1315  ++NumErrors;
1316  continue;
1317  }
1318  NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
1319  }
1320 
1321  if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
1322  error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
1323  "and abbreviation {1:x} has no {2} attribute.\n",
1324  NI.getUnitOffset(), Abbrev.Code,
1325  dwarf::DW_IDX_compile_unit);
1326  ++NumErrors;
1327  }
1328  if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
1329  error() << formatv(
1330  "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
1331  NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
1332  ++NumErrors;
1333  }
1334  }
1335  return NumErrors;
1336 }
1337 
1339  bool IncludeLinkageName = true) {
1341  if (const char *Str = DIE.getShortName())
1342  Result.emplace_back(Str);
1343  else if (DIE.getTag() == dwarf::DW_TAG_namespace)
1344  Result.emplace_back("(anonymous namespace)");
1345 
1346  if (IncludeLinkageName) {
1347  if (const char *Str = DIE.getLinkageName())
1348  Result.emplace_back(Str);
1349  }
1350 
1351  return Result;
1352 }
1353 
1354 unsigned DWARFVerifier::verifyNameIndexEntries(
1355  const DWARFDebugNames::NameIndex &NI,
1356  const DWARFDebugNames::NameTableEntry &NTE) {
1357  // Verifying type unit indexes not supported.
1358  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
1359  return 0;
1360 
1361  const char *CStr = NTE.getString();
1362  if (!CStr) {
1363  error() << formatv(
1364  "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
1365  NI.getUnitOffset(), NTE.getIndex());
1366  return 1;
1367  }
1368  StringRef Str(CStr);
1369 
1370  unsigned NumErrors = 0;
1371  unsigned NumEntries = 0;
1372  uint64_t EntryID = NTE.getEntryOffset();
1373  uint64_t NextEntryID = EntryID;
1374  Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
1375  for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
1376  EntryOr = NI.getEntry(&NextEntryID)) {
1377  uint32_t CUIndex = *EntryOr->getCUIndex();
1378  if (CUIndex > NI.getCUCount()) {
1379  error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
1380  "invalid CU index ({2}).\n",
1381  NI.getUnitOffset(), EntryID, CUIndex);
1382  ++NumErrors;
1383  continue;
1384  }
1385  uint64_t CUOffset = NI.getCUOffset(CUIndex);
1386  uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
1387  DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
1388  if (!DIE) {
1389  error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
1390  "non-existing DIE @ {2:x}.\n",
1391  NI.getUnitOffset(), EntryID, DIEOffset);
1392  ++NumErrors;
1393  continue;
1394  }
1395  if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
1396  error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
1397  "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
1398  NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
1399  DIE.getDwarfUnit()->getOffset());
1400  ++NumErrors;
1401  }
1402  if (DIE.getTag() != EntryOr->tag()) {
1403  error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
1404  "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1405  NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
1406  DIE.getTag());
1407  ++NumErrors;
1408  }
1409 
1410  auto EntryNames = getNames(DIE);
1411  if (!is_contained(EntryNames, Str)) {
1412  error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
1413  "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
1414  NI.getUnitOffset(), EntryID, DIEOffset, Str,
1415  make_range(EntryNames.begin(), EntryNames.end()));
1416  ++NumErrors;
1417  }
1418  }
1419  handleAllErrors(EntryOr.takeError(),
1420  [&](const DWARFDebugNames::SentinelError &) {
1421  if (NumEntries > 0)
1422  return;
1423  error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
1424  "not associated with any entries.\n",
1425  NI.getUnitOffset(), NTE.getIndex(), Str);
1426  ++NumErrors;
1427  },
1428  [&](const ErrorInfoBase &Info) {
1429  error()
1430  << formatv("Name Index @ {0:x}: Name {1} ({2}): {3}\n",
1431  NI.getUnitOffset(), NTE.getIndex(), Str,
1432  Info.message());
1433  ++NumErrors;
1434  });
1435  return NumErrors;
1436 }
1437 
1438 static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
1440  Die.getLocations(DW_AT_location);
1441  if (!Loc) {
1442  consumeError(Loc.takeError());
1443  return false;
1444  }
1445  DWARFUnit *U = Die.getDwarfUnit();
1446  for (const auto &Entry : *Loc) {
1447  DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
1448  U->getAddressByteSize());
1450  U->getFormParams().Format);
1451  bool IsInteresting =
1453  return !Op.isError() && (Op.getCode() == DW_OP_addr ||
1454  Op.getCode() == DW_OP_form_tls_address ||
1455  Op.getCode() == DW_OP_GNU_push_tls_address);
1456  });
1457  if (IsInteresting)
1458  return true;
1459  }
1460  return false;
1461 }
1462 
1463 unsigned DWARFVerifier::verifyNameIndexCompleteness(
1464  const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI) {
1465 
1466  // First check, if the Die should be indexed. The code follows the DWARF v5
1467  // wording as closely as possible.
1468 
1469  // "All non-defining declarations (that is, debugging information entries
1470  // with a DW_AT_declaration attribute) are excluded."
1471  if (Die.find(DW_AT_declaration))
1472  return 0;
1473 
1474  // "DW_TAG_namespace debugging information entries without a DW_AT_name
1475  // attribute are included with the name “(anonymous namespace)”.
1476  // All other debugging information entries without a DW_AT_name attribute
1477  // are excluded."
1478  // "If a subprogram or inlined subroutine is included, and has a
1479  // DW_AT_linkage_name attribute, there will be an additional index entry for
1480  // the linkage name."
1481  auto IncludeLinkageName = Die.getTag() == DW_TAG_subprogram ||
1482  Die.getTag() == DW_TAG_inlined_subroutine;
1483  auto EntryNames = getNames(Die, IncludeLinkageName);
1484  if (EntryNames.empty())
1485  return 0;
1486 
1487  // We deviate from the specification here, which says:
1488  // "The name index must contain an entry for each debugging information entry
1489  // that defines a named subprogram, label, variable, type, or namespace,
1490  // subject to ..."
1491  // Explicitly exclude all TAGs that we know shouldn't be indexed.
1492  switch (Die.getTag()) {
1493  // Compile units and modules have names but shouldn't be indexed.
1494  case DW_TAG_compile_unit:
1495  case DW_TAG_module:
1496  return 0;
1497 
1498  // Function and template parameters are not globally visible, so we shouldn't
1499  // index them.
1500  case DW_TAG_formal_parameter:
1501  case DW_TAG_template_value_parameter:
1502  case DW_TAG_template_type_parameter:
1503  case DW_TAG_GNU_template_parameter_pack:
1504  case DW_TAG_GNU_template_template_param:
1505  return 0;
1506 
1507  // Object members aren't globally visible.
1508  case DW_TAG_member:
1509  return 0;
1510 
1511  // According to a strict reading of the specification, enumerators should not
1512  // be indexed (and LLVM currently does not do that). However, this causes
1513  // problems for the debuggers, so we may need to reconsider this.
1514  case DW_TAG_enumerator:
1515  return 0;
1516 
1517  // Imported declarations should not be indexed according to the specification
1518  // and LLVM currently does not do that.
1519  case DW_TAG_imported_declaration:
1520  return 0;
1521 
1522  // "DW_TAG_subprogram, DW_TAG_inlined_subroutine, and DW_TAG_label debugging
1523  // information entries without an address attribute (DW_AT_low_pc,
1524  // DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded."
1525  case DW_TAG_subprogram:
1526  case DW_TAG_inlined_subroutine:
1527  case DW_TAG_label:
1528  if (Die.findRecursively(
1529  {DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_entry_pc}))
1530  break;
1531  return 0;
1532 
1533  // "DW_TAG_variable debugging information entries with a DW_AT_location
1534  // attribute that includes a DW_OP_addr or DW_OP_form_tls_address operator are
1535  // included; otherwise, they are excluded."
1536  //
1537  // LLVM extension: We also add DW_OP_GNU_push_tls_address to this list.
1538  case DW_TAG_variable:
1539  if (isVariableIndexable(Die, DCtx))
1540  break;
1541  return 0;
1542 
1543  default:
1544  break;
1545  }
1546 
1547  // Now we know that our Die should be present in the Index. Let's check if
1548  // that's the case.
1549  unsigned NumErrors = 0;
1550  uint64_t DieUnitOffset = Die.getOffset() - Die.getDwarfUnit()->getOffset();
1551  for (StringRef Name : EntryNames) {
1552  if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) {
1553  return E.getDIEUnitOffset() == DieUnitOffset;
1554  })) {
1555  error() << formatv("Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with "
1556  "name {3} missing.\n",
1557  NI.getUnitOffset(), Die.getOffset(), Die.getTag(),
1558  Name);
1559  ++NumErrors;
1560  }
1561  }
1562  return NumErrors;
1563 }
1564 
1565 unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
1566  const DataExtractor &StrData) {
1567  unsigned NumErrors = 0;
1568  DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
1569  DCtx.isLittleEndian(), 0);
1570  DWARFDebugNames AccelTable(AccelSectionData, StrData);
1571 
1572  OS << "Verifying .debug_names...\n";
1573 
1574  // This verifies that we can read individual name indices and their
1575  // abbreviation tables.
1576  if (Error E = AccelTable.extract()) {
1577  error() << toString(std::move(E)) << '\n';
1578  return 1;
1579  }
1580 
1581  NumErrors += verifyDebugNamesCULists(AccelTable);
1582  for (const auto &NI : AccelTable)
1583  NumErrors += verifyNameIndexBuckets(NI, StrData);
1584  for (const auto &NI : AccelTable)
1585  NumErrors += verifyNameIndexAbbrevs(NI);
1586 
1587  // Don't attempt Entry validation if any of the previous checks found errors
1588  if (NumErrors > 0)
1589  return NumErrors;
1590  for (const auto &NI : AccelTable)
1591  for (const DWARFDebugNames::NameTableEntry &NTE : NI)
1592  NumErrors += verifyNameIndexEntries(NI, NTE);
1593 
1594  if (NumErrors > 0)
1595  return NumErrors;
1596 
1597  for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
1598  if (const DWARFDebugNames::NameIndex *NI =
1599  AccelTable.getCUNameIndex(U->getOffset())) {
1600  auto *CU = cast<DWARFCompileUnit>(U.get());
1601  for (const DWARFDebugInfoEntry &Die : CU->dies())
1602  NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
1603  }
1604  }
1605  return NumErrors;
1606 }
1607 
1609  const DWARFObject &D = DCtx.getDWARFObj();
1610  DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
1611  unsigned NumErrors = 0;
1612  if (!D.getAppleNamesSection().Data.empty())
1613  NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
1614  ".apple_names");
1615  if (!D.getAppleTypesSection().Data.empty())
1616  NumErrors += verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData,
1617  ".apple_types");
1618  if (!D.getAppleNamespacesSection().Data.empty())
1619  NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
1620  ".apple_namespaces");
1621  if (!D.getAppleObjCSection().Data.empty())
1622  NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
1623  ".apple_objc");
1624 
1625  if (!D.getNamesSection().Data.empty())
1626  NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
1627  return NumErrors == 0;
1628 }
1629 
1630 raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
1631 
1632 raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
1633 
1634 raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
1635 
1636 raw_ostream &DWARFVerifier::dump(const DWARFDie &Die, unsigned indent) const {
1637  Die.dump(OS, indent, DumpOpts);
1638  return OS;
1639 }
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:1642
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
llvm::hlsl::ResourceKind::NumEntries
@ NumEntries
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:18
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:942
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:1748
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
llvm::Attribute
Definition: Attributes.h:66
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:1922
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:629
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
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:2263
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:32
llvm::DWARFVerifier::DWARFVerifier
DWARFVerifier(raw_ostream &S, DWARFContext &D, DIDumpOptions DumpOpts=DIDumpOptions::getForSingleDIE())
Definition: DWARFVerifier.cpp:950
llvm::DWARFFormValue::getAsUnsignedConstant
Optional< uint64_t > getAsUnsignedConstant() const
Definition: DWARFFormValue.cpp:728
llvm::StringMap::end
iterator end()
Definition: StringMap.h:204
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:37
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
T
#define T
Definition: Mips16ISelLowering.cpp:341
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::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
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:217
llvm::DWARFUnit::getFormParams
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:315
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:311
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:1042
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::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:265
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:39
llvm::DWARFUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:426
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:845
getNames
static SmallVector< StringRef, 2 > getNames(const DWARFDie &DIE, bool IncludeLinkageName=true)
Definition: DWARFVerifier.cpp:1338
Error.h
DWARFVerifier.h
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:419
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:722
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:628
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:960
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:53
llvm::DWARFObject
Definition: DWARFObject.h:26
llvm::DWARFFormValue
Definition: DWARFFormValue.h:28
llvm::DWARFObject::getRangesSection
virtual const DWARFSection & getRangesSection() const
Definition: DWARFObject.h:49
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
DebugLocVerifyLevel::None
@ None
llvm::DWARFUnit::getLineSection
const DWARFSection & getLineSection() const
Definition: DWARFUnit.h:332
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:1608
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:567
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::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
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:407
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:40
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
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:329
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:380
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:714
llvm::DWARFFormValue::FormClass
FormClass
Definition: DWARFFormValue.h:30
llvm::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:347
llvm::DWARFDebugLine::Row::dumpTableHeader
static void dumpTableHeader(raw_ostream &OS, unsigned Indent)
Definition: DWARFDebugLine.cpp:486
TableRef
ArrayRef< TableEntry > TableRef
Definition: AMDGPULibCalls.cpp:380
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:252
Attributes
AMDGPU Kernel Attributes
Definition: AMDGPULowerKernelAttributes.cpp:347
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:1868
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:150
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:1861
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:276
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:411
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:1741
llvm::DWARFDie::hasChildren
bool hasChildren() const
Definition: DWARFDie.h:79
llvm::logicalview::LVAttributeKind::Range
@ Range
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Dwarf.h
llvm::DWARFUnit::getContext
DWARFContext & getContext() const
Definition: DWARFUnit.h:312
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:64
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:1761
llvm::DWARFDebugNames::Entry
DWARF v5-specific implementation of an Accelerator Entry.
Definition: DWARFAcceleratorTable.h:283
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
WithColor.h
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::DWARFDie::getParent
DWARFDie getParent() const
Get the parent of this DIE object.
Definition: DWARFDie.cpp:627
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:319
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:348
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:295
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:314
DWARFExpression.h
llvm::DWARFDie::getFullName
void getFullName(raw_string_ostream &, std::string *OriginalFullName=nullptr) const
Definition: DWARFDie.cpp:235
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:596
llvm::DWARFDie::getAttributeValueAsReferencedDie
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition: DWARFDie.cpp:309
llvm::DWARFDebugNames::NameIndex::getNameCount
uint32_t getNameCount() const
Definition: DWARFAcceleratorTable.h:451
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::AttributeSet
Definition: Attributes.h:294
llvm::DWARFDie::getTag
dwarf::Tag getTag() const
Definition: DWARFDie.h:72
llvm::DWARFDie::attributes
iterator_range< attribute_iterator > attributes() const
Get an iterator range to all attributes in the current DIE only.
Definition: DWARFDie.cpp:657
llvm::DWARFObject::getRnglistsSection
virtual const DWARFSection & getRnglistsSection() const
Definition: DWARFObject.h:50
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:143
llvm::DWARFFormValue::isFormClass
bool isFormClass(FormClass FC) const
Definition: DWARFFormValue.cpp:216
llvm::DWARFContext::getDWARFObj
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:126
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:103
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:695
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:245
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 Offset inside the unit's DIE vector.
Definition: DWARFUnit.h:516
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
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:965
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:318
llvm::DWARFDie::getFirstChild
DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition: DWARFDie.cpp:645
llvm::ArrayRef::end
iterator end() const
Definition: ArrayRef.h:153
isVariableIndexable
static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx)
Definition: DWARFVerifier.cpp:1438
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