forked from OSchip/llvm-project
[Debuginfo][DWARF][NFC] Add paired methods working with DWARFDebugInfoEntry.
This review is extracted from D96035. DWARF Debuginfo classes have two representations for DIEs: DWARFDebugInfoEntry (short) and DWARFDie(extended). Depending on the task, it might be more convenient to use DWARFDebugInfoEntry or/and DWARFDie. DWARFUnit class already has methods working with DWARFDie and DWARFDebugInfoEntry. This patch adds more methods working with DWARFDebugInfoEntry to have paired functionality. Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D126059
This commit is contained in:
parent
7d76da539f
commit
ece341f598
|
@ -252,13 +252,36 @@ class DWARFUnit {
|
|||
|
||||
std::shared_ptr<DWARFUnit> DWO;
|
||||
|
||||
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
|
||||
protected:
|
||||
/// Return the index of a \p Die entry inside the unit's DIE vector.
|
||||
///
|
||||
/// It is illegal to call this method with a DIE that hasn't be
|
||||
/// created by this unit. In other word, it's illegal to call this
|
||||
/// method on a DIE that isn't accessible by following
|
||||
/// children/sibling links starting from this unit's getUnitDIE().
|
||||
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {
|
||||
auto First = DieArray.data();
|
||||
assert(Die >= First && Die < First + DieArray.size());
|
||||
return Die - First;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Return DWARFDebugInfoEntry for the specified index \p Index.
|
||||
const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {
|
||||
assert(Index < DieArray.size());
|
||||
return &DieArray[Index];
|
||||
}
|
||||
|
||||
const DWARFDebugInfoEntry *
|
||||
getParentEntry(const DWARFDebugInfoEntry *Die) const;
|
||||
const DWARFDebugInfoEntry *
|
||||
getSiblingEntry(const DWARFDebugInfoEntry *Die) const;
|
||||
const DWARFDebugInfoEntry *
|
||||
getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const;
|
||||
const DWARFDebugInfoEntry *
|
||||
getFirstChildEntry(const DWARFDebugInfoEntry *Die) const;
|
||||
const DWARFDebugInfoEntry *
|
||||
getLastChildEntry(const DWARFDebugInfoEntry *Die) const;
|
||||
|
||||
const DWARFUnitHeader &getHeader() const { return Header; }
|
||||
|
||||
/// Find the unit's contribution to the string offsets table and determine its
|
||||
|
@ -472,14 +495,13 @@ public:
|
|||
/// created by this unit. In other word, it's illegal to call this
|
||||
/// method on a DIE that isn't accessible by following
|
||||
/// children/sibling links starting from this unit's getUnitDIE().
|
||||
uint32_t getDIEIndex(const DWARFDie &D) {
|
||||
uint32_t getDIEIndex(const DWARFDie &D) const {
|
||||
return getDIEIndex(D.getDebugInfoEntry());
|
||||
}
|
||||
|
||||
/// Return the DIE object at the given index.
|
||||
/// Return the DIE object at the given index \p Index.
|
||||
DWARFDie getDIEAtIndex(unsigned Index) {
|
||||
assert(Index < DieArray.size());
|
||||
return DWARFDie(this, &DieArray[Index]);
|
||||
return DWARFDie(this, getDebugInfoEntry(Index));
|
||||
}
|
||||
|
||||
DWARFDie getParent(const DWARFDebugInfoEntry *Die);
|
||||
|
@ -488,19 +510,26 @@ public:
|
|||
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
|
||||
DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
|
||||
|
||||
/// Return the DIE object for a given offset inside the
|
||||
/// Return the DIE object for a given offset \p Offset inside the
|
||||
/// unit's DIE vector.
|
||||
///
|
||||
/// The unit needs to have its DIEs extracted for this method to work.
|
||||
DWARFDie getDIEForOffset(uint64_t Offset) {
|
||||
if (Optional<uint32_t> DieIdx = getDIEIndexForOffset(Offset))
|
||||
return DWARFDie(this, &DieArray[*DieIdx]);
|
||||
|
||||
return DWARFDie();
|
||||
}
|
||||
|
||||
/// Return the DIE index for a given offset \p Offset inside the
|
||||
/// unit's DIE vector.
|
||||
Optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
|
||||
extractDIEsIfNeeded(false);
|
||||
auto It =
|
||||
llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
|
||||
return DIE.getOffset() < Offset;
|
||||
});
|
||||
if (It != DieArray.end() && It->getOffset() == Offset)
|
||||
return DWARFDie(this, &*It);
|
||||
return DWARFDie();
|
||||
return It - DieArray.begin();
|
||||
return None;
|
||||
}
|
||||
|
||||
uint32_t getLineTableOffset() const {
|
||||
|
|
|
@ -877,39 +877,66 @@ const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
|
|||
}
|
||||
|
||||
DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
|
||||
if (const DWARFDebugInfoEntry *Entry = getParentEntry(Die))
|
||||
return DWARFDie(this, Entry);
|
||||
|
||||
return DWARFDie();
|
||||
}
|
||||
|
||||
const DWARFDebugInfoEntry *
|
||||
DWARFUnit::getParentEntry(const DWARFDebugInfoEntry *Die) const {
|
||||
if (!Die)
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
|
||||
|
||||
if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) {
|
||||
assert(*ParentIdx < DieArray.size() &&
|
||||
"ParentIdx is out of DieArray boundaries");
|
||||
return DWARFDie(this, &DieArray[*ParentIdx]);
|
||||
return getDebugInfoEntry(*ParentIdx);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
|
||||
if (const DWARFDebugInfoEntry *Sibling = getSiblingEntry(Die))
|
||||
return DWARFDie(this, Sibling);
|
||||
|
||||
return DWARFDie();
|
||||
}
|
||||
|
||||
DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
|
||||
const DWARFDebugInfoEntry *
|
||||
DWARFUnit::getSiblingEntry(const DWARFDebugInfoEntry *Die) const {
|
||||
if (!Die)
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
|
||||
|
||||
if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
|
||||
assert(*SiblingIdx < DieArray.size() &&
|
||||
"SiblingIdx is out of DieArray boundaries");
|
||||
return DWARFDie(this, &DieArray[*SiblingIdx]);
|
||||
return &DieArray[*SiblingIdx];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
|
||||
if (const DWARFDebugInfoEntry *Sibling = getPreviousSiblingEntry(Die))
|
||||
return DWARFDie(this, Sibling);
|
||||
|
||||
return DWARFDie();
|
||||
}
|
||||
|
||||
DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
|
||||
const DWARFDebugInfoEntry *
|
||||
DWARFUnit::getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const {
|
||||
if (!Die)
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
|
||||
|
||||
Optional<uint32_t> ParentIdx = Die->getParentIdx();
|
||||
if (!ParentIdx)
|
||||
// Die is a root die, there is no previous sibling.
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
|
||||
assert(*ParentIdx < DieArray.size() &&
|
||||
"ParentIdx is out of DieArray boundaries");
|
||||
|
@ -918,7 +945,7 @@ DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
|
|||
uint32_t PrevDieIdx = getDIEIndex(Die) - 1;
|
||||
if (PrevDieIdx == *ParentIdx)
|
||||
// Immediately previous node is parent, there is no previous sibling.
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
|
||||
while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
|
||||
PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
|
||||
|
@ -929,32 +956,56 @@ DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
|
|||
"PrevDieIdx is not a child of parent of Die");
|
||||
}
|
||||
|
||||
return DWARFDie(this, &DieArray[PrevDieIdx]);
|
||||
return &DieArray[PrevDieIdx];
|
||||
}
|
||||
|
||||
DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
|
||||
if (const DWARFDebugInfoEntry *Child = getFirstChildEntry(Die))
|
||||
return DWARFDie(this, Child);
|
||||
|
||||
return DWARFDie();
|
||||
}
|
||||
|
||||
const DWARFDebugInfoEntry *
|
||||
DWARFUnit::getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {
|
||||
if (!Die)
|
||||
return nullptr;
|
||||
assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
|
||||
|
||||
if (!Die->hasChildren())
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
|
||||
// TODO: Instead of checking here for invalid die we might reject
|
||||
// invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
|
||||
// We do not want access out of bounds when parsing corrupted debug data.
|
||||
size_t I = getDIEIndex(Die) + 1;
|
||||
if (I >= DieArray.size())
|
||||
return DWARFDie();
|
||||
return DWARFDie(this, &DieArray[I]);
|
||||
return nullptr;
|
||||
return &DieArray[I];
|
||||
}
|
||||
|
||||
DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
|
||||
if (const DWARFDebugInfoEntry *Child = getLastChildEntry(Die))
|
||||
return DWARFDie(this, Child);
|
||||
|
||||
return DWARFDie();
|
||||
}
|
||||
|
||||
const DWARFDebugInfoEntry *
|
||||
DWARFUnit::getLastChildEntry(const DWARFDebugInfoEntry *Die) const {
|
||||
if (!Die)
|
||||
return nullptr;
|
||||
assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
|
||||
|
||||
if (!Die->hasChildren())
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
|
||||
if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
|
||||
assert(*SiblingIdx < DieArray.size() &&
|
||||
"SiblingIdx is out of DieArray boundaries");
|
||||
assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&
|
||||
"Bad end of children marker");
|
||||
return DWARFDie(this, &DieArray[*SiblingIdx - 1]);
|
||||
return &DieArray[*SiblingIdx - 1];
|
||||
}
|
||||
|
||||
// If SiblingIdx is set for non-root dies we could be sure that DWARF is
|
||||
|
@ -969,11 +1020,13 @@ DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
|
|||
if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
|
||||
DieArray.back().getTag() == dwarf::DW_TAG_null) {
|
||||
// For the unit die we might take last item from DieArray.
|
||||
assert(getDIEIndex(Die) == getDIEIndex(getUnitDIE()) && "Bad unit die");
|
||||
return DWARFDie(this, &DieArray.back());
|
||||
assert(getDIEIndex(Die) ==
|
||||
getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) &&
|
||||
"Bad unit die");
|
||||
return &DieArray.back();
|
||||
}
|
||||
|
||||
return DWARFDie();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
|
||||
|
|
Loading…
Reference in New Issue