LLVM  7.0.0svn
DWARFUnit.cpp
Go to the documentation of this file.
1 //===- DWARFUnit.cpp ------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/Path.h"
22 #include "llvm/Support/WithColor.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cstddef>
26 #include <cstdint>
27 #include <cstdio>
28 #include <utility>
29 #include <vector>
30 
31 using namespace llvm;
32 using namespace dwarf;
33 
35  const DWARFObject &D = C.getDWARFObj();
36  parseImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
38  &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false,
39  false);
40 }
41 
43  const DWARFSection &DWOSection, bool Lazy) {
44  const DWARFObject &D = C.getDWARFObj();
45  parseImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
48  true, Lazy);
49 }
50 
52  const DWARFUnitHeader &Header,
53  const DWARFDebugAbbrev *DA, const DWARFSection *RS,
54  StringRef SS, const DWARFSection &SOS,
55  const DWARFSection *AOS, const DWARFSection &LS, bool LE,
56  bool IsDWO, const DWARFUnitSectionBase &UnitSection)
57  : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
58  RangeSection(RS), LineSection(LS), StringSection(SS),
59  StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
60  isDWO(IsDWO), UnitSection(UnitSection) {
61  clear();
62 }
63 
64 DWARFUnit::~DWARFUnit() = default;
65 
67  return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
69 }
70 
72  uint64_t &Result) const {
73  uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
74  if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
75  return false;
76  DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
77  isLittleEndian, getAddressByteSize());
78  Result = DA.getRelocatedAddress(&Offset);
79  return true;
80 }
81 
83  uint64_t &Result) const {
84  if (!StringOffsetsTableContribution)
85  return false;
86  unsigned ItemSize = getDwarfStringOffsetsByteSize();
87  uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
88  if (StringOffsetSection.Data.size() < Offset + ItemSize)
89  return false;
90  DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
91  isLittleEndian, 0);
92  Result = DA.getRelocatedValue(ItemSize, &Offset);
93  return true;
94 }
95 
97  const DWARFDataExtractor &debug_info,
98  uint32_t *offset_ptr,
100  const DWARFUnitIndex *Index) {
101  Offset = *offset_ptr;
102  IndexEntry = Index ? Index->getFromOffset(*offset_ptr) : nullptr;
103  Length = debug_info.getU32(offset_ptr);
104  // FIXME: Support DWARF64.
105  unsigned SizeOfLength = 4;
107  FormParams.Version = debug_info.getU16(offset_ptr);
108  if (FormParams.Version >= 5) {
109  UnitType = debug_info.getU8(offset_ptr);
110  FormParams.AddrSize = debug_info.getU8(offset_ptr);
111  AbbrOffset = debug_info.getU32(offset_ptr);
112  } else {
113  AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr);
114  FormParams.AddrSize = debug_info.getU8(offset_ptr);
115  // Fake a unit type based on the section type. This isn't perfect,
116  // but distinguishing compile and type units is generally enough.
117  if (SectionKind == DW_SECT_TYPES)
118  UnitType = DW_UT_type;
119  else
120  UnitType = DW_UT_compile;
121  }
122  if (IndexEntry) {
123  if (AbbrOffset)
124  return false;
125  auto *UnitContrib = IndexEntry->getOffset();
126  if (!UnitContrib || UnitContrib->Length != (Length + 4))
127  return false;
128  auto *AbbrEntry = IndexEntry->getOffset(DW_SECT_ABBREV);
129  if (!AbbrEntry)
130  return false;
131  AbbrOffset = AbbrEntry->Offset;
132  }
133  if (isTypeUnit()) {
134  TypeHash = debug_info.getU64(offset_ptr);
135  TypeOffset = debug_info.getU32(offset_ptr);
136  } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
137  DWOId = debug_info.getU64(offset_ptr);
138 
139  // Header fields all parsed, capture the size of this unit header.
140  assert(*offset_ptr - Offset <= 255 && "unexpected header size");
141  Size = uint8_t(*offset_ptr - Offset);
142 
143  // Type offset is unit-relative; should be after the header and before
144  // the end of the current unit.
145  bool TypeOffsetOK =
146  !isTypeUnit()
147  ? true
148  : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
149  bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
150  bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
151  bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
152 
153  if (!LengthOK || !VersionOK || !AddrSizeOK || !TypeOffsetOK)
154  return false;
155 
156  // Keep track of the highest DWARF version we encounter across all units.
158  return true;
159 }
160 
161 // Parse the rangelist table header, including the optional array of offsets
162 // following it (DWARF v5 and later).
165  // TODO: Support DWARF64
166  // We are expected to be called with Offset 0 or pointing just past the table
167  // header, which is 12 bytes long for DWARF32.
168  if (Offset > 0) {
169  if (Offset < 12U) {
170  std::string Buffer;
171  raw_string_ostream Stream(Buffer);
172  Stream << format(
173  "Did not detect a valid range list table with base = 0x%x", Offset);
174  return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
175  }
176  Offset -= 12U;
177  }
179  if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
180  return std::move(E);
181  return Table;
182 }
183 
185  DWARFDebugRangeList &RangeList) const {
186  // Require that compile unit is extracted.
187  assert(!DieArray.empty());
188  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
189  isLittleEndian, getAddressByteSize());
190  uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
191  return RangeList.extract(RangesData, &ActualRangeListOffset);
192 }
193 
195  Abbrevs = nullptr;
196  BaseAddr.reset();
197  RangeSectionBase = 0;
198  AddrOffsetSectionBase = 0;
199  clearDIEs(false);
200  DWO.reset();
201 }
202 
204  return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
205 }
206 
207 void DWARFUnit::extractDIEsToVector(
208  bool AppendCUDie, bool AppendNonCUDies,
209  std::vector<DWARFDebugInfoEntry> &Dies) const {
210  if (!AppendCUDie && !AppendNonCUDies)
211  return;
212 
213  // Set the offset to that of the first DIE and calculate the start of the
214  // next compilation unit header.
215  uint32_t DIEOffset = getOffset() + getHeaderSize();
216  uint32_t NextCUOffset = getNextUnitOffset();
218  DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
219  uint32_t Depth = 0;
220  bool IsCUDie = true;
221 
222  while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
223  Depth)) {
224  if (IsCUDie) {
225  if (AppendCUDie)
226  Dies.push_back(DIE);
227  if (!AppendNonCUDies)
228  break;
229  // The average bytes per DIE entry has been seen to be
230  // around 14-20 so let's pre-reserve the needed memory for
231  // our DIE entries accordingly.
232  Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
233  IsCUDie = false;
234  } else {
235  Dies.push_back(DIE);
236  }
237 
238  if (const DWARFAbbreviationDeclaration *AbbrDecl =
240  // Normal DIE
241  if (AbbrDecl->hasChildren())
242  ++Depth;
243  } else {
244  // NULL DIE.
245  if (Depth > 0)
246  --Depth;
247  if (Depth == 0)
248  break; // We are done with this compile unit!
249  }
250  }
251 
252  // Give a little bit of info if we encounter corrupt DWARF (our offset
253  // should always terminate at or before the start of the next compilation
254  // unit header).
255  if (DIEOffset > NextCUOffset)
256  WithColor::warning() << format("DWARF compile unit extends beyond its "
257  "bounds cu 0x%8.8x at 0x%8.8x\n",
258  getOffset(), DIEOffset);
259 }
260 
261 size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
262  if ((CUDieOnly && !DieArray.empty()) ||
263  DieArray.size() > 1)
264  return 0; // Already parsed.
265 
266  bool HasCUDie = !DieArray.empty();
267  extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
268 
269  if (DieArray.empty())
270  return 0;
271 
272  // If CU DIE was just parsed, copy several attribute values from it.
273  if (!HasCUDie) {
274  DWARFDie UnitDie = getUnitDIE();
275  if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
276  Header.setDWOId(*DWOId);
277  if (!isDWO) {
278  assert(AddrOffsetSectionBase == 0);
279  assert(RangeSectionBase == 0);
280  AddrOffsetSectionBase =
281  toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
282  RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
283  }
284 
285  // In general, in DWARF v5 and beyond we derive the start of the unit's
286  // contribution to the string offsets table from the unit DIE's
287  // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
288  // attribute, so we assume that there is a contribution to the string
289  // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
290  // In both cases we need to determine the format of the contribution,
291  // which may differ from the unit's format.
292  uint64_t StringOffsetsContributionBase =
293  isDWO ? 0 : toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
294  auto IndexEntry = Header.getIndexEntry();
295  if (IndexEntry)
296  if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
297  StringOffsetsContributionBase += C->Offset;
298 
299  DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
300  isLittleEndian, 0);
301  if (isDWO)
302  StringOffsetsTableContribution =
304  DA, StringOffsetsContributionBase);
305  else if (getVersion() >= 5)
306  StringOffsetsTableContribution = determineStringOffsetsTableContribution(
307  DA, StringOffsetsContributionBase);
308 
309  // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
310  // describe address ranges.
311  if (getVersion() >= 5) {
312  if (isDWO)
314  else
316  toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
317  // Parse the range list table header. Individual range lists are
318  // extracted lazily.
319  DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
320  isLittleEndian, 0);
321  if (auto TableOrError =
322  parseRngListTableHeader(RangesDA, RangeSectionBase))
323  RngListTable = TableOrError.get();
324  else
325  WithColor::error() << "parsing a range list table: "
326  << toString(TableOrError.takeError())
327  << '\n';
328 
329  // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
330  // Adjust RangeSectionBase to point past the table header.
331  if (isDWO && RngListTable)
332  RangeSectionBase = RngListTable->getHeaderSize();
333  }
334 
335  // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
336  // skeleton CU DIE, so that DWARF users not aware of it are not broken.
337  }
338 
339  return DieArray.size();
340 }
341 
342 bool DWARFUnit::parseDWO() {
343  if (isDWO)
344  return false;
345  if (DWO.get())
346  return false;
347  DWARFDie UnitDie = getUnitDIE();
348  if (!UnitDie)
349  return false;
350  auto DWOFileName = dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
351  if (!DWOFileName)
352  return false;
353  auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
354  SmallString<16> AbsolutePath;
355  if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
356  *CompilationDir) {
357  sys::path::append(AbsolutePath, *CompilationDir);
358  }
359  sys::path::append(AbsolutePath, *DWOFileName);
360  auto DWOId = getDWOId();
361  if (!DWOId)
362  return false;
363  auto DWOContext = Context.getDWOContext(AbsolutePath);
364  if (!DWOContext)
365  return false;
366 
367  DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
368  if (!DWOCU)
369  return false;
370  DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
371  // Share .debug_addr and .debug_ranges section with compile unit in .dwo
372  DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
373  if (getVersion() >= 5) {
374  DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
375  DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
376  isLittleEndian, 0);
377  if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))
378  DWO->RngListTable = TableOrError.get();
379  else
380  WithColor::error() << "parsing a range list table: "
381  << toString(TableOrError.takeError())
382  << '\n';
383  if (DWO->RngListTable)
384  DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
385  } else {
386  auto DWORangesBase = UnitDie.getRangesBaseAttribute();
387  DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
388  }
389 
390  return true;
391 }
392 
393 void DWARFUnit::clearDIEs(bool KeepCUDie) {
394  if (DieArray.size() > (unsigned)KeepCUDie) {
395  DieArray.resize((unsigned)KeepCUDie);
396  DieArray.shrink_to_fit();
397  }
398 }
399 
401  if (getVersion() <= 4) {
402  DWARFDebugRangeList RangeList;
403  if (extractRangeList(Offset, RangeList))
404  return RangeList.getAbsoluteRanges(getBaseAddress());
405  return DWARFAddressRangesVector();
406  }
407  if (RngListTable) {
408  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
409  isLittleEndian, RngListTable->getAddrSize());
410  if (auto RangeList = RngListTable->findRangeList(RangesData, Offset))
411  return RangeList->getAbsoluteRanges(getBaseAddress());
412  }
413  return DWARFAddressRangesVector();
414 }
415 
417  if (auto Offset = getRnglistOffset(Index))
418  return findRnglistFromOffset(*Offset + RangeSectionBase);
419  return DWARFAddressRangesVector();
420 }
421 
423  DWARFDie UnitDie = getUnitDIE();
424  if (!UnitDie)
425  return;
426  // First, check if unit DIE describes address ranges for the whole unit.
427  const auto &CUDIERanges = UnitDie.getAddressRanges();
428  if (!CUDIERanges.empty()) {
429  CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
430  return;
431  }
432 
433  // This function is usually called if there in no .debug_aranges section
434  // in order to produce a compile unit level set of address ranges that
435  // is accurate. If the DIEs weren't parsed, then we don't want all dies for
436  // all compile units to stay loaded when they weren't needed. So we can end
437  // up parsing the DWARF and then throwing them all away to keep memory usage
438  // down.
439  const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
441 
442  // Collect address ranges from DIEs in .dwo if necessary.
443  bool DWOCreated = parseDWO();
444  if (DWO)
445  DWO->collectAddressRanges(CURanges);
446  if (DWOCreated)
447  DWO.reset();
448 
449  // Keep memory down by clearing DIEs if this generate function
450  // caused them to be parsed.
451  if (ClearDIEs)
452  clearDIEs(true);
453 }
454 
456  if (Die.isSubroutineDIE()) {
457  for (const auto &R : Die.getAddressRanges()) {
458  // Ignore 0-sized ranges.
459  if (R.LowPC == R.HighPC)
460  continue;
461  auto B = AddrDieMap.upper_bound(R.LowPC);
462  if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
463  // The range is a sub-range of existing ranges, we need to split the
464  // existing range.
465  if (R.HighPC < B->second.first)
466  AddrDieMap[R.HighPC] = B->second;
467  if (R.LowPC > B->first)
468  AddrDieMap[B->first].first = R.LowPC;
469  }
470  AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
471  }
472  }
473  // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
474  // simplify the logic to update AddrDieMap. The child's range will always
475  // be equal or smaller than the parent's range. With this assumption, when
476  // adding one range into the map, it will at most split a range into 3
477  // sub-ranges.
478  for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
479  updateAddressDieMap(Child);
480 }
481 
483  extractDIEsIfNeeded(false);
484  if (AddrDieMap.empty())
486  auto R = AddrDieMap.upper_bound(Address);
487  if (R == AddrDieMap.begin())
488  return DWARFDie();
489  // upper_bound's previous item contains Address.
490  --R;
491  if (Address >= R->second.first)
492  return DWARFDie();
493  return R->second.second;
494 }
495 
496 void
498  SmallVectorImpl<DWARFDie> &InlinedChain) {
499  assert(InlinedChain.empty());
500  // Try to look for subprogram DIEs in the DWO file.
501  parseDWO();
502  // First, find the subroutine that contains the given address (the leaf
503  // of inlined chain).
504  DWARFDie SubroutineDIE =
505  (DWO ? DWO.get() : this)->getSubroutineForAddress(Address);
506 
507  if (!SubroutineDIE)
508  return;
509 
510  while (!SubroutineDIE.isSubprogramDIE()) {
511  if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
512  InlinedChain.push_back(SubroutineDIE);
513  SubroutineDIE = SubroutineDIE.getParent();
514  }
515  InlinedChain.push_back(SubroutineDIE);
516 }
517 
520  if (Kind == DW_SECT_INFO)
521  return Context.getCUIndex();
522  assert(Kind == DW_SECT_TYPES);
523  return Context.getTUIndex();
524 }
525 
527  if (!Die)
528  return DWARFDie();
529  const uint32_t Depth = Die->getDepth();
530  // Unit DIEs always have a depth of zero and never have parents.
531  if (Depth == 0)
532  return DWARFDie();
533  // Depth of 1 always means parent is the compile/type unit.
534  if (Depth == 1)
535  return getUnitDIE();
536  // Look for previous DIE with a depth that is one less than the Die's depth.
537  const uint32_t ParentDepth = Depth - 1;
538  for (uint32_t I = getDIEIndex(Die) - 1; I > 0; --I) {
539  if (DieArray[I].getDepth() == ParentDepth)
540  return DWARFDie(this, &DieArray[I]);
541  }
542  return DWARFDie();
543 }
544 
546  if (!Die)
547  return DWARFDie();
548  uint32_t Depth = Die->getDepth();
549  // Unit DIEs always have a depth of zero and never have siblings.
550  if (Depth == 0)
551  return DWARFDie();
552  // NULL DIEs don't have siblings.
553  if (Die->getAbbreviationDeclarationPtr() == nullptr)
554  return DWARFDie();
555 
556  // Find the next DIE whose depth is the same as the Die's depth.
557  for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
558  ++I) {
559  if (DieArray[I].getDepth() == Depth)
560  return DWARFDie(this, &DieArray[I]);
561  }
562  return DWARFDie();
563 }
564 
566  if (!Die->hasChildren())
567  return DWARFDie();
568 
569  // We do not want access out of bounds when parsing corrupted debug data.
570  size_t I = getDIEIndex(Die) + 1;
571  if (I >= DieArray.size())
572  return DWARFDie();
573  return DWARFDie(this, &DieArray[I]);
574 }
575 
577  if (!Abbrevs)
578  Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
579  return Abbrevs;
580 }
581 
583  if (BaseAddr)
584  return BaseAddr;
585 
586  DWARFDie UnitDie = getUnitDIE();
587  Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
588  if (Optional<uint64_t> Addr = toAddress(PC))
589  BaseAddr = {*Addr, PC->getSectionIndex()};
590 
591  return BaseAddr;
592 }
593 
596  DWARFDataExtractor &DA) {
597  uint8_t EntrySize = getDwarfOffsetByteSize();
598  // In order to ensure that we don't read a partial record at the end of
599  // the section we validate for a multiple of the entry size.
600  uint64_t ValidationSize = alignTo(Size, EntrySize);
601  // Guard against overflow.
602  if (ValidationSize >= Size)
603  if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
604  return *this;
606 }
607 
608 // Look for a DWARF64-formatted contribution to the string offsets table
609 // starting at a given offset and record it in a descriptor.
612  if (!DA.isValidOffsetForDataOfSize(Offset, 16))
614 
615  if (DA.getU32(&Offset) != 0xffffffff)
617 
618  uint64_t Size = DA.getU64(&Offset);
619  uint8_t Version = DA.getU16(&Offset);
620  (void)DA.getU16(&Offset); // padding
621  // The encoded length includes the 2-byte version field and the 2-byte
622  // padding, so we need to subtract them out when we populate the descriptor.
623  return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
624  //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
625 }
626 
627 // Look for a DWARF32-formatted contribution to the string offsets table
628 // starting at a given offset and record it in a descriptor.
631  if (!DA.isValidOffsetForDataOfSize(Offset, 8))
633  uint32_t ContributionSize = DA.getU32(&Offset);
634  if (ContributionSize >= 0xfffffff0)
636  uint8_t Version = DA.getU16(&Offset);
637  (void)DA.getU16(&Offset); // padding
638  // The encoded length includes the 2-byte version field and the 2-byte
639  // padding, so we need to subtract them out when we populate the descriptor.
640  return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version,
641  DWARF32);
642  //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
643 }
644 
647  uint64_t Offset) {
649  // Attempt to find a DWARF64 contribution 16 bytes before the base.
650  if (Offset >= 16)
651  Descriptor =
653  // Try to find a DWARF32 contribution 8 bytes before the base.
654  if (!Descriptor && Offset >= 8)
655  Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8);
656  return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor;
657 }
658 
661  uint64_t Offset) {
662  if (getVersion() >= 5) {
663  // Look for a valid contribution at the given offset.
664  auto Descriptor =
666  if (!Descriptor)
667  Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset);
668  return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor;
669  }
670  // Prior to DWARF v5, we derive the contribution size from the
671  // index table (in a package file). In a .dwo file it is simply
672  // the length of the string offsets section.
673  uint64_t Size = 0;
674  auto IndexEntry = Header.getIndexEntry();
675  if (!IndexEntry)
676  Size = StringOffsetSection.Data.size();
677  else if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
678  Size = C->Length;
679  // Return a descriptor with the given offset as base, version 4 and
680  // DWARF32 format.
681  //return Optional<StrOffsetsContributionDescriptor>(
682  //StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32));
683  return StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32);
684 }
const DWARFAbbreviationDeclarationSet * getAbbreviations() const
Definition: DWARFUnit.cpp:576
const DWARFUnitIndex & getTUIndex()
uint64_t CallInst * C
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:497
virtual ~DWARFUnit()
virtual const DWARFSection & getAddrSection() const
Definition: DWARFObject.h:67
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:495
LLVMContext & Context
bool extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const
extractRangeList - extracts the range list referenced by this compile unit from .debug_ranges section...
Definition: DWARFUnit.cpp:184
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Represents a unit&#39;s contribution to the string offsets table.
Definition: DWARFUnit.h:232
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
Definition: DWARFDie.cpp:280
uint64_t getSectionIndex() const
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
void collectAddressRanges(DWARFAddressRangesVector &CURanges)
Definition: DWARFUnit.cpp:422
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
static raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition: WithColor.cpp:63
void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const
Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any of its children.
Definition: DWARFDie.cpp:405
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, bool Lazy=false)
Definition: DWARFUnit.cpp:42
DWARFDie getSibling(const DWARFDebugInfoEntry *Die)
Definition: DWARFUnit.cpp:545
uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx=nullptr) const
Extracts an address-sized value and applies a relocation to the result if one exists for the given of...
unsigned second
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition: WithColor.cpp:65
static Optional< StrOffsetsContributionDescriptor > parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset)
Definition: DWARFUnit.cpp:611
Optional< StrOffsetsContributionDescriptor > validateContributionSize(DWARFDataExtractor &DA)
Determine whether a contribution to the string offsets table is consistent with the relevant section ...
Definition: DWARFUnit.cpp:595
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:677
virtual const DWARFSection & getRnglistsDWOSection() const
Definition: DWARFObject.h:66
Optional< StrOffsetsContributionDescriptor > determineStringOffsetsTableContribution(DWARFDataExtractor &DA, uint64_t Offset)
Find the unit&#39;s contribution to the string offsets table and determine its length and form...
Definition: DWARFUnit.cpp:646
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
uint8_t getDwarfStringOffsetsByteSize() const
Definition: DWARFUnit.h:386
uint16_t getU16(uint32_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
Optional< uint64_t > toAddress(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
Definition: DWARFUnit.cpp:482
static Optional< StrOffsetsContributionDescriptor > parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset)
Definition: DWARFUnit.cpp:630
virtual bool isLittleEndian() const =0
uint32_t getNextUnitOffset() const
Definition: DWARFUnit.h:345
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const
Definition: DWARFUnit.cpp:71
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:471
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:947
uint32_t getU32(uint32_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
static ManagedStatic< DebugCounter > DC
const char * getCompilationDir()
Definition: DWARFUnit.cpp:203
Optional< uint64_t > getRangesBaseAttribute() const
Extract the range base attribute from this DIE as absolute section offset.
Definition: DWARFDie.cpp:355
uint64_t getAbbrOffset() const
Definition: DWARFUnit.h:86
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract the table header and the array of offsets.
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
virtual const DWARFSection & getStringOffsetDWOSection() const
Definition: DWARFObject.h:62
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:338
void parse(DWARFContext &C, const DWARFSection &Section)
Definition: DWARFUnit.cpp:34
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
uint16_t getVersion() const
Definition: DWARFUnit.h:337
DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition: DWARFDie.cpp:540
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die)
Definition: DWARFUnit.cpp:565
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const
Test the availability of length bytes of data from offset.
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
Definition: DWARFDie.h:43
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
virtual const DWARFSection & getStringOffsetSection() const
Definition: DWARFObject.h:54
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
DWARFSectionKind
A structured debug information entry.
Definition: DIE.h:662
bool isSubroutineDIE() const
Returns true if DIE represents a subprogram or an inlined subroutine.
Definition: DWARFDie.cpp:282
Optional< uint64_t > getDWOId()
Definition: DWARFUnit.h:445
bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr)
Extracts a debug info entry, which is a child of a given unit, starting at a given offset...
const DWARFAbbreviationDeclarationSet * getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
Definition: DWARFUnit.cpp:526
virtual const DWARFSection & getLineDWOSection() const
Definition: DWARFObject.h:59
uint8_t getU8(uint32_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:23
virtual StringRef getStringSection() const
Definition: DWARFObject.h:46
void setRangesSection(const DWARFSection *RS, uint32_t Base)
Definition: DWARFUnit.h:360
virtual StringRef getStringDWOSection() const
Definition: DWARFObject.h:61
bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info, uint32_t *offset_ptr, DWARFSectionKind Kind=DW_SECT_INFO, const DWARFUnitIndex *Index=nullptr)
Parse a unit header from debug_info starting at offset_ptr.
Definition: DWARFUnit.cpp:96
uint32_t getHeaderSize() const
Size in bytes of the parsed unit header.
Definition: DWARFUnit.h:305
uint64_t getU64(uint32_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
const DWARFUnitIndex & getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind)
Definition: DWARFUnit.cpp:518
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:929
DWARFAddressRangesVector getAbsoluteRanges(llvm::Optional< BaseAddress > BaseAddr) const
getAbsoluteRanges - Returns absolute address ranges defined by this range list.
Base class describing the header of any kind of "unit." Some information is specific to certain unit ...
Definition: DWARFUnit.h:47
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:493
uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off, uint64_t *SectionIndex=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset...
llvm::Optional< BaseAddress > getBaseAddress()
Definition: DWARFUnit.cpp:582
UnitType
Constants for unit types in DWARF v5.
Definition: Dwarf.h:328
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
uint64_t getStringOffsetsBase() const
Definition: DWARFUnit.h:391
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:437
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
void setDWOId(uint64_t Id)
Definition: DWARFUnit.h:88
const DWARFUnitIndex::Entry * getIndexEntry() const
Definition: DWARFUnit.h:92
static Expected< DWARFDebugRnglistTable > parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset)
Definition: DWARFUnit.cpp:164
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:59
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Optional< const char * > toString(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
virtual const DWARFSection & getRnglistsSection() const
Definition: DWARFObject.h:48
DWARFAddressRangesVector findRnglistFromOffset(uint32_t Offset)
Return a vector of address ranges resulting from a (possibly encoded) range list starting at a given ...
Definition: DWARFUnit.cpp:400
uint32_t getLength() const
Definition: DWARFUnit.h:343
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection)
Definition: DWARFUnit.cpp:51
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:66
Basic Alias true
virtual const DWARFSection & getLineSection() const
Definition: DWARFObject.h:44
static bool isSupportedVersion(unsigned version)
Definition: DWARFContext.h:301
virtual const DWARFSection & getRangeDWOSection() const
Definition: DWARFObject.h:65
DWARFAddressRangesVector findRnglistFromIndex(uint32_t Index)
Return a vector of address ranges retrieved from an encoded range list whose offset is found via a ta...
Definition: DWARFUnit.cpp:416
bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const
Definition: DWARFUnit.cpp:82
dwarf::Tag getTag() const
Definition: DWARFDie.h:72
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:62
A class representing a table of range lists as specified in DWARF v5.
#define I(x, y, z)
Definition: MD5.cpp:58
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition: Path.cpp:690
uint32_t getOffset() const
Definition: DWARFUnit.h:333
void updateAddressDieMap(DWARFDie Die)
Recursively update address to Die map.
Definition: DWARFUnit.cpp:455
bool isLittleEndian() const
Definition: DWARFContext.h:300
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:124
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
const DWARFUnitIndex & getCUIndex()
virtual const DWARFSection & getRangeSection() const
Definition: DWARFObject.h:47
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DwarfFormat Format
Definition: Dwarf.h:498
Base class for all DWARFUnitSection classes.
Definition: DWARFUnit.h:106
Optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:287
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:477
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
DWARFDebugInfoEntry - A DIE with only the minimum required data.
DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition: DWARFDie.cpp:546
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
const Entry * getFromOffset(uint32_t Offset) const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Optional< uint32_t > getRnglistOffset(uint32_t Index)
Return a rangelist&#39;s offset based on an index.
Definition: DWARFUnit.h:463
const uint64_t Version
Definition: InstrProf.h:895
bool extract(const DWARFDataExtractor &data, uint32_t *offset_ptr)
uint8_t getDwarfOffsetByteSize() const
Definition: DWARFUnit.h:340
void setMaxVersionIfGreater(unsigned Version)
Definition: DWARFContext.h:216
Optional< uint64_t > toUnsigned(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
DWARFDie getParent() const
Get the parent of this DIE object.
Definition: DWARFDie.cpp:534
Optional< StrOffsetsContributionDescriptor > determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA, uint64_t Offset)
Find the unit&#39;s contribution to the string offsets table and determine its length and form...
Definition: DWARFUnit.cpp:660
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:73
DWARFAddressRangesVector getAddressRanges() const
Get the address ranges for this DIE.
Definition: DWARFDie.cpp:388