diff options
author | Greg Clayton <gclayton@apple.com> | 2016-12-21 21:37:06 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2016-12-21 21:37:06 +0000 |
commit | 78a07bfa66e673ae766f8dfb7dd4f9bebba8fce6 (patch) | |
tree | 6e307bcba084e2926c758986d8dd09b48d4a0f14 /llvm/lib | |
parent | e9ce09b89f6cb865ea651af3f33f2fd247b23544 (diff) | |
download | bcm5719-llvm-78a07bfa66e673ae766f8dfb7dd4f9bebba8fce6.tar.gz bcm5719-llvm-78a07bfa66e673ae766f8dfb7dd4f9bebba8fce6.zip |
Add the ability for DWARFDie objects to get the parent DWARFDie.
In order for the llvm DWARF parser to be used in LLDB we will need to be able to get the parent of a DIE. This patch adds that functionality by changing the DWARFDebugInfoEntry class to store a depth field instead of a sibling index. Using a depth field allows us to easily calculate the sibling and the parent without increasing the size of DWARFDebugInfoEntry.
I tested llvm-dsymutil on a debug version of clang where this fully parses DWARF in over 1200 .o files to verify there was no serious regression in performance.
Added a full suite of unit tests to test this functionality.
Differential Revision: https://reviews.llvm.org/D27995
llvm-svn: 290274
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 71 |
3 files changed, 56 insertions, 36 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp index 8ea65ebfdd5..9f623e4954c 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -26,13 +26,13 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr) { DataExtractor DebugInfoData = U.getDebugInfoExtractor(); const uint32_t UEndOffset = U.getNextUnitOffset(); - return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset); + return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0); } -bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, - uint32_t *OffsetPtr, - const DataExtractor &DebugInfoData, - uint32_t UEndOffset) { +bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr, + const DataExtractor &DebugInfoData, + uint32_t UEndOffset, uint32_t D) { Offset = *OffsetPtr; + Depth = D; if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) return false; uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index 94777109e44..deec1633022 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -428,3 +428,14 @@ void DWARFDie::getInlinedChainForAddress( std::reverse(InlinedChain.begin(), InlinedChain.end()); } +DWARFDie DWARFDie::getParent() const { + if (isValid()) + return U->getParent(Die); + return DWARFDie(); +} + +DWARFDie DWARFDie::getSibling() const { + if (isValid()) + return U->getSibling(Die); + return DWARFDie(); +} diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 2ddbc507ff6..63fb0d3bc36 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -158,35 +158,6 @@ Optional<uint64_t> DWARFUnit::getDWOId() { return getUnitDIE().getAttributeValueAsUnsignedConstant(DW_AT_GNU_dwo_id); } -void DWARFUnit::setDIERelations() { - if (DieArray.size() <= 1) - return; - - std::vector<DWARFDebugInfoEntry *> ParentChain; - DWARFDebugInfoEntry *SiblingChain = nullptr; - for (auto &DIE : DieArray) { - if (SiblingChain) { - SiblingChain->setSibling(&DIE); - } - if (const DWARFAbbreviationDeclaration *AbbrDecl = - DIE.getAbbreviationDeclarationPtr()) { - // Normal DIE. - if (AbbrDecl->hasChildren()) { - ParentChain.push_back(&DIE); - SiblingChain = nullptr; - } else { - SiblingChain = &DIE; - } - } else { - // NULL entry terminates the sibling chain. - SiblingChain = ParentChain.back(); - ParentChain.pop_back(); - } - } - assert(SiblingChain == nullptr || SiblingChain == &DieArray[0]); - assert(ParentChain.empty()); -} - void DWARFUnit::extractDIEsToVector( bool AppendCUDie, bool AppendNonCUDies, std::vector<DWARFDebugInfoEntry> &Dies) const { @@ -202,7 +173,8 @@ void DWARFUnit::extractDIEsToVector( uint32_t Depth = 0; bool IsCUDie = true; - while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset)) { + while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset, + Depth)) { if (IsCUDie) { if (AppendCUDie) Dies.push_back(DIE); @@ -266,7 +238,6 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { // skeleton CU DIE, so that DWARF users not aware of it are not broken. } - setDIERelations(); return DieArray.size(); } @@ -409,4 +380,42 @@ const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, return Context.getTUIndex(); } +DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) { + if (!Die) + return DWARFDie(); + const uint32_t Depth = Die->getDepth(); + // Unit DIEs always have a depth of zero and never have parents. + if (Depth == 0) + return DWARFDie(); + // Depth of 1 always means parent is the compile/type unit. + if (Depth == 1) + return getUnitDIE(); + // Look for previous DIE with a depth that is one less than the Die's depth. + const uint32_t ParentDepth = Depth - 1; + for (uint32_t I = getDIEIndex(Die) - 1; I > 0; --I) { + if (DieArray[I].getDepth() == ParentDepth) + return DWARFDie(this, &DieArray[I]); + } + return DWARFDie(); +} + +DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) { + if (!Die) + return DWARFDie(); + uint32_t Depth = Die->getDepth(); + // Unit DIEs always have a depth of zero and never have siblings. + if (Depth == 0) + return DWARFDie(); + // NULL DIEs don't have siblings. + if (Die->getAbbreviationDeclarationPtr() == nullptr) + return DWARFDie(); + + // Find the next DIE whose depth is the same as the Die's depth. + for (size_t I=getDIEIndex(Die)+1, EndIdx = DieArray.size(); I<EndIdx; ++I) { + if (DieArray[I].getDepth() == Depth) + return DWARFDie(this, &DieArray[I]); + } + return DWARFDie(); +} + } // end namespace llvm |