29 using namespace dwarf;
51 :
Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
52 LineSection(LS), StringSection(SS), StringOffsetSection([&]() {
55 return SOS.
slice(
C->Offset,
C->Offset +
C->Length);
66 uint64_t &Result)
const {
67 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
68 if (AddrOffsetSection.
size() < Offset + AddrSize)
70 DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
80 if (StringOffsetSection.
size() < Offset + ItemSize)
83 Result = DA.
getU32(&Offset);
88 Length = debug_info.
getU32(offset_ptr);
89 Version = debug_info.
getU16(offset_ptr);
90 uint64_t AbbrOffset = debug_info.
getU32(offset_ptr);
94 auto *UnitContrib = IndexEntry->
getOffset();
95 if (!UnitContrib || UnitContrib->Length != (Length + 4))
100 AbbrOffset = AbbrEntry->
Offset;
102 AddrSize = debug_info.
getU8(offset_ptr);
106 bool AddrSizeOK = AddrSize == 4 || AddrSize == 8;
108 if (!LengthOK || !VersionOK || !AddrSizeOK)
112 return Abbrevs !=
nullptr;
118 Offset = *offset_ptr;
125 *offset_ptr = Offset;
134 assert(!DieArray.empty());
135 DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
136 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
137 return RangeList.
extract(RangesData, &ActualRangeListOffset);
147 RangeSectionBase = 0;
148 AddrOffsetSectionBase = 0;
161 void DWARFUnit::extractDIEsToVector(
162 bool AppendCUDie,
bool AppendNonCUDies,
163 std::vector<DWARFDebugInfoEntry> &Dies)
const {
164 if (!AppendCUDie && !AppendNonCUDies)
176 while (DIE.
extractFast(*
this, &DIEOffset, DebugInfoData, NextCUOffset,
181 if (!AppendNonCUDies)
186 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
192 if (
const DWARFAbbreviationDeclaration *AbbrDecl =
195 if (AbbrDecl->hasChildren())
209 if (DIEOffset > NextCUOffset)
210 fprintf(stderr,
"warning: DWARF compile unit extends beyond its "
211 "bounds cu 0x%8.8x at 0x%8.8x'\n",
getOffset(), DIEOffset);
214 size_t DWARFUnit::extractDIEsIfNeeded(
bool CUDieOnly) {
215 if ((CUDieOnly && !DieArray.empty()) ||
219 bool HasCUDie = !DieArray.empty();
220 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
222 if (DieArray.empty())
228 auto BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_low_pc);
230 BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_entry_pc);
233 AddrOffsetSectionBase =
234 UnitDie.getAttributeValueAsSectionOffset(DW_AT_GNU_addr_base)
237 UnitDie.getAttributeValueAsSectionOffset(DW_AT_rnglists_base)
243 return DieArray.size();
246 DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath)
254 DWOFile = std::move(Obj.get());
256 cast<DWARFContext>(
new DWARFContextInMemory(*DWOFile.getBinary())));
257 if (DWOContext->getNumDWOCompileUnits() > 0)
258 DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
261 bool DWARFUnit::parseDWO() {
269 const char *DWOFileName =
270 UnitDie.getAttributeValueAsString(DW_AT_GNU_dwo_name,
nullptr);
273 const char *CompilationDir =
274 UnitDie.getAttributeValueAsString(DW_AT_comp_dir,
nullptr);
275 SmallString<16> AbsolutePath;
280 DWO = llvm::make_unique<DWOHolder>(AbsolutePath);
283 if (!DWOCU || DWOCU->getDWOId() !=
getDWOId()) {
288 DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
289 auto DWORangesBase = UnitDie.getRangesBaseAttribute();
290 DWOCU->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
294 void DWARFUnit::clearDIEs(
bool KeepCUDie) {
295 if (DieArray.size() > (
unsigned)KeepCUDie) {
303 std::vector<DWARFDebugInfoEntry> TmpArray;
304 DieArray.swap(TmpArray);
307 DieArray.push_back(TmpArray.front());
317 if (!CUDIERanges.empty()) {
318 CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
328 const bool ClearDIEs = extractDIEsIfNeeded(
false) > 1;
332 bool DWOCreated = parseDWO();
334 DWO->getUnit()->collectAddressRanges(CURanges);
345 DWARFUnit::getSubprogramForAddress(uint64_t
Address) {
346 extractDIEsIfNeeded(
false);
349 if (DIE.isSubprogramDIE() &&
350 DIE.addressRangeContainsAddress(Address)) {
366 SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
368 SubprogramDIE = getSubprogramForAddress(Address);
374 InlinedChain.
clear();
396 const uint32_t ParentDepth = Depth - 1;
397 for (
uint32_t I = getDIEIndex(Die) - 1;
I > 0; --
I) {
398 if (DieArray[
I].getDepth() == ParentDepth)
416 for (
size_t I=getDIEIndex(Die)+1, EndIdx = DieArray.size();
I<EndIdx; ++
I) {
417 if (DieArray[
I].getDepth() ==
Depth)
const DWARFUnitIndex & getTUIndex()
virtual StringRef getAddrSection()=0
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Create ObjectFile from path.
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const
uint32_t getDepth() const
DWARFAddressRangesVector getAddressRanges() const
Get the address ranges for this DIE.
void setBaseAddress(uint64_t base_addr)
virtual StringRef getStringOffsetDWOSection()=0
virtual StringRef getRangeDWOSection()=0
bool is_relative(const Twine &path)
Is path relative?
std::vector< std::pair< uint64_t, uint64_t > > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
virtual const DWARFSection & getLineSection()=0
virtual uint32_t getHeaderSize() const
Size in bytes of the unit header.
void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const
Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any of its children.
uint32_t getNextUnitOffset() const
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
virtual StringRef getStringDWOSection()=0
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr)
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
DWARFDie getSibling(const DWARFDebugInfoEntry *Die)
const char * getAttributeValueAsString(dwarf::Attribute Attr, const char *FailValue) const
Extract the specified attribute from this DIE as a C string.
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
virtual StringRef getRangeSection()=0
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
bool extract(DataExtractor data, uint32_t *offset_ptr)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
const DWARFAbbreviationDeclarationSet * getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const
void collectAddressRanges(DWARFAddressRangesVector &CURanges)
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry=nullptr)
void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, DWARFUnitIndex *Index=nullptr)
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
A structured debug information entry.
void getInlinedChainForAddress(const uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain) const
Get inlined chain for a given address, rooted at the current DIE.
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...
Optional< uint64_t > getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as an unsigned integer.
const char * getCompilationDir()
void consumeError(Error Err)
Consume a Error without doing anything.
const DWARFUnitIndex & getDWARFUnitIndex(DWARFContext &Context, DWARFSectionKind Kind)
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
bool extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const
extractRangeList - extracts the range list referenced by this compile unit from .debug_ranges section...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
bool extract(DataExtractor debug_info, uint32_t *offset_ptr)
static void clear(coro::Shape &Shape)
DataExtractor getDebugInfoExtractor() const
static bool isSupportedVersion(unsigned version)
const SectionContribution * getOffset(DWARFSectionKind Sec) const
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Optional< uint64_t > getDWOId()
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const
uint32_t getOffset() const
const DWARFUnitIndex & getCUIndex()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Base class for all DWARFUnitSection classes.
virtual const DWARFSection & getLineDWOSection()=0
DWARFDebugInfoEntry - A DIE with only the minimum required data.
void parse(DWARFContext &C, const DWARFSection &Section)
StringRef - Represent a constant reference to a string, i.e.
virtual StringRef getStringSection()=0
virtual bool isLittleEndian() const =0