18 using namespace dwarf;
37 : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
38 StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
39 isLittleEndian(LE), UnitSection(UnitSection) {
47 uint64_t &Result)
const {
48 uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
49 if (AddrOffsetSection.
size() < Offset + AddrSize)
51 DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
57 uint32_t &Result)
const {
59 const uint32_t ItemSize = 4;
60 uint32_t Offset = Index * ItemSize;
61 if (StringOffsetSection.
size() < Offset + ItemSize)
64 Result = DA.
getU32(&Offset);
69 Length = debug_info.
getU32(offset_ptr);
70 Version = debug_info.
getU16(offset_ptr);
71 uint64_t AbbrOffset = debug_info.
getU32(offset_ptr);
72 AddrSize = debug_info.
getU8(offset_ptr);
76 bool AddrSizeOK = AddrSize == 4 || AddrSize == 8;
78 if (!LengthOK || !VersionOK || !AddrSizeOK)
82 return Abbrevs !=
nullptr;
104 assert(DieArray.size() > 0);
105 DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize);
106 uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
107 return RangeList.
extract(RangesData, &ActualRangeListOffset);
117 RangeSectionBase = 0;
118 AddrOffsetSectionBase = 0;
124 extractDIEsIfNeeded(
true);
125 if (DieArray.empty())
127 return DieArray[0].getAttributeValueAsString(
this,
DW_AT_comp_dir,
nullptr);
131 extractDIEsIfNeeded(
true);
132 const uint64_t FailValue = -1ULL;
133 if (DieArray.empty())
139 void DWARFUnit::setDIERelations() {
140 if (DieArray.size() <= 1)
143 std::vector<DWARFDebugInfoEntryMinimal *> ParentChain;
145 for (
auto &
DIE : DieArray) {
150 DIE.getAbbreviationDeclarationPtr()) {
152 if (AbbrDecl->hasChildren()) {
153 ParentChain.push_back(&
DIE);
154 SiblingChain =
nullptr;
160 SiblingChain = ParentChain.back();
161 ParentChain.pop_back();
164 assert(SiblingChain ==
nullptr || SiblingChain == &DieArray[0]);
165 assert(ParentChain.empty());
168 void DWARFUnit::extractDIEsToVector(
169 bool AppendCUDie,
bool AppendNonCUDies,
170 std::vector<DWARFDebugInfoEntryMinimal> &Dies)
const {
171 if (!AppendCUDie && !AppendNonCUDies)
182 while (DIEOffset < NextCUOffset && DIE.
extractFast(
this, &DIEOffset)) {
186 if (!AppendNonCUDies)
191 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
200 if (AbbrDecl->hasChildren())
214 if (DIEOffset > NextCUOffset)
215 fprintf(stderr,
"warning: DWARF compile unit extends beyond its "
216 "bounds cu 0x%8.8x at 0x%8.8x'\n",
getOffset(), DIEOffset);
219 size_t DWARFUnit::extractDIEsIfNeeded(
bool CUDieOnly) {
220 if ((CUDieOnly && DieArray.size() > 0) ||
224 bool HasCUDie = DieArray.size() > 0;
225 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
227 if (DieArray.empty())
233 DieArray[0].getAttributeValueAsAddress(
this,
DW_AT_low_pc, -1ULL);
234 if (BaseAddr == -1ULL)
235 BaseAddr = DieArray[0].getAttributeValueAsAddress(
this,
DW_AT_entry_pc, 0);
237 AddrOffsetSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
239 RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
246 return DieArray.size();
249 DWARFUnit::DWOHolder::DWOHolder(
StringRef DWOPath)
250 : DWOFile(), DWOContext(), DWOU(nullptr) {
254 DWOFile = std::move(Obj.get());
257 if (DWOContext->getNumDWOCompileUnits() > 0)
258 DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
261 bool DWARFUnit::parseDWO() {
264 extractDIEsIfNeeded(
true);
265 if (DieArray.empty())
267 const char *DWOFileName =
271 const char *CompilationDir =
272 DieArray[0].getAttributeValueAsString(
this,
DW_AT_comp_dir,
nullptr);
278 DWO = llvm::make_unique<DWOHolder>(AbsolutePath);
281 if (!DWOCU || DWOCU->getDWOId() !=
getDWOId()) {
286 DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
287 uint32_t DWORangesBase = DieArray[0].getRangesBaseAttribute(
this, 0);
288 DWOCU->setRangesSection(RangeSection, DWORangesBase);
292 void DWARFUnit::clearDIEs(
bool KeepCUDie) {
293 if (DieArray.size() > (
unsigned)KeepCUDie) {
301 std::vector<DWARFDebugInfoEntryMinimal> TmpArray;
302 DieArray.swap(TmpArray);
305 DieArray.push_back(TmpArray.front());
314 const auto &CUDIERanges = U->getAddressRanges(
this);
315 if (!CUDIERanges.empty()) {
316 CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
326 const bool ClearDIEs = extractDIEsIfNeeded(
false) > 1;
327 DieArray[0].collectChildrenAddressRanges(
this, CURanges);
330 bool DWOCreated = parseDWO();
332 DWO->getUnit()->collectAddressRanges(CURanges);
343 DWARFUnit::getSubprogramForAddress(uint64_t
Address) {
344 extractDIEsIfNeeded(
false);
360 getSubprogramForAddress(Address);
367 SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
369 ChainCU = DWO->getUnit();
virtual StringRef getAddrSection()=0
size_t size() const
size - Get the string size.
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.
void collectAddressRanges(DWARFAddressRangesVector &CURanges)
virtual uint32_t getHeaderSize() const
Size in bytes of the unit header.
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, bool LE, const DWARFUnitSectionBase &UnitSection)
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(const DWARFUnit *U, const uint64_t Address) const
Get inlined chain for a given address, rooted at the current DIE.
bool extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const
extractRangeList - extracts the range list referenced by this compile unit from .debug_ranges section...
uint32_t getNextUnitOffset() const
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
virtual StringRef getStringDWOSection()=0
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
const char * getCompilationDir()
virtual StringRef getRangeSection()=0
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address)
getInlinedChainForAddress - fetches inlined chain for a given address.
void parse(DWARFContext &C, const DWARFSection &Section)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
bool addressRangeContainsAddress(const DWARFUnit *U, const uint64_t Address) const
bool extract(DataExtractor data, uint32_t *offset_ptr)
DWARFContextInMemory is the simplest possible implementation of a DWARFContext.
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
const DWARFAbbreviationDeclarationSet * getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const
DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
DIE - A structured debug information entry.
bool extract(DataExtractor debug_info, uint32_t *offset_ptr)
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
void parseDWO(DWARFContext &C, const DWARFSection &DWOSection)
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const
static bool isSupportedVersion(unsigned version)
void setSibling(const DWARFDebugInfoEntryMinimal *Sibling)
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr)
uint32_t getOffset() const
Base class for all DWARFUnitSection classes.
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
const DWARFDebugInfoEntryMinimal * getUnitDIE(bool ExtractUnitDIEOnly=true)
static ErrorOr< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Create ObjectFile from path.
StringRef - Represent a constant reference to a string, i.e.
virtual StringRef getStringSection()=0
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...
virtual bool isLittleEndian() const =0
DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine DIEs, (possibly ending wit...