[llvm] r291967 - Add a variant of DWARFDie::find() and DWARFDie::findRecursively() that takes a llvm::ArrayRef<dwarf::Attribute>.
Greg Clayton via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 13 14:32:12 PST 2017
Author: gclayton
Date: Fri Jan 13 16:32:12 2017
New Revision: 291967
URL: http://llvm.org/viewvc/llvm-project?rev=291967&view=rev
Log:
Add a variant of DWARFDie::find() and DWARFDie::findRecursively() that takes a llvm::ArrayRef<dwarf::Attribute>.
This allows us efficiently look for more than one attribute, something that is quite common in DWARF consumption.
Differential Revision: https://reviews.llvm.org/D28704
Modified:
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
llvm/trunk/tools/dsymutil/DwarfLinker.cpp
llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h?rev=291967&r1=291966&r2=291967&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h Fri Jan 13 16:32:12 2017
@@ -10,6 +10,7 @@
#ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H
#define LLVM_LIB_DEBUGINFO_DWARFDIE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Optional.h"
@@ -125,8 +126,20 @@ public:
/// \returns an optional DWARFFormValue that will have the form value if the
/// attribute was successfully extracted.
Optional<DWARFFormValue> find(dwarf::Attribute Attr) const;
-
+ /// Extract the first value of any attribute in Attrs from this DIE.
+ ///
+ /// Extract the first attribute that matches from this DIE only. This call
+ /// doesn't look for the attribute value in any DW_AT_specification or
+ /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched
+ /// linearly in the order they are specified within Attrs.
+ ///
+ /// \param Attrs an array of DWARF attribute to look for.
+ /// \returns an optional that has a valid DWARFFormValue for the first
+ /// matching attribute in Attrs, or None if none of the attributes in Attrs
+ /// exist in this DIE.
+ Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const;
+
/// Extract an attribute value from this DIE and recurse into any
/// DW_AT_specification or DW_AT_abstract_origin referenced DIEs.
///
@@ -135,6 +148,18 @@ public:
/// attribute was successfully extracted.
Optional<DWARFFormValue> findRecursively(dwarf::Attribute Attr) const;
+ /// Extract the first value of any attribute in Attrs from this DIE and
+ /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced
+ /// DIEs.
+ ///
+ /// \param Attrs an array of DWARF attribute to look for.
+ /// \returns an optional that has a valid DWARFFormValue for the first
+ /// matching attribute in Attrs, or None if none of the attributes in Attrs
+ /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin
+ /// DIEs.
+ Optional<DWARFFormValue>
+ findRecursively(ArrayRef<dwarf::Attribute> Attrs) const;
+
/// Extract the specified attribute from this DIE as the referenced DIE.
///
/// Regardless of the reference type, return the correct DWARFDie instance if
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=291967&r1=291966&r2=291967&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Fri Jan 13 16:32:12 2017
@@ -158,6 +158,35 @@ DWARFDie::findRecursively(dwarf::Attribu
return None;
}
+Optional<DWARFFormValue>
+DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
+ if (!isValid())
+ return None;
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl) {
+ for (auto Attr : Attrs) {
+ if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
+ return Value;
+ }
+ }
+ return None;
+}
+
+Optional<DWARFFormValue>
+DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
+ if (!isValid())
+ return None;
+ if (auto Value = find(Attrs))
+ return Value;
+ if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
+ if (auto Value = Die.find(Attrs))
+ return Value;
+ if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification))
+ if (auto Value = Die.find(Attrs))
+ return Value;
+ return None;
+}
+
DWARFDie
DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
auto SpecRef = toReference(find(Attr));
@@ -171,10 +200,7 @@ DWARFDie::getAttributeValueAsReferencedD
Optional<uint64_t>
DWARFDie::getRangesBaseAttribute() const {
- auto Result = toSectionOffset(find(DW_AT_rnglists_base));
- if (Result)
- return Result;
- return toSectionOffset(find(DW_AT_GNU_ranges_base));
+ return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
}
Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
@@ -256,11 +282,8 @@ DWARFDie::getName(DINameKind Kind) const
return nullptr;
// Try to get mangled name only if it was asked for.
if (Kind == DINameKind::LinkageName) {
- if (auto Name = dwarf::toString(findRecursively(DW_AT_MIPS_linkage_name),
- nullptr))
- return Name;
- if (auto Name = dwarf::toString(findRecursively(DW_AT_linkage_name),
- nullptr))
+ if (auto Name = dwarf::toString(findRecursively({DW_AT_MIPS_linkage_name,
+ DW_AT_linkage_name}), nullptr))
return Name;
}
if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr))
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=291967&r1=291966&r2=291967&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Fri Jan 13 16:32:12 2017
@@ -226,9 +226,7 @@ size_t DWARFUnit::extractDIEsIfNeeded(bo
// If CU DIE was just parsed, copy several attribute values from it.
if (!HasCUDie) {
DWARFDie UnitDie = getUnitDIE();
- auto BaseAddr = toAddress(UnitDie.find(DW_AT_low_pc));
- if (!BaseAddr)
- BaseAddr = toAddress(UnitDie.find(DW_AT_entry_pc));
+ auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}));
if (BaseAddr)
setBaseAddress(*BaseAddr);
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=291967&r1=291966&r2=291967&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Fri Jan 13 16:32:12 2017
@@ -3184,10 +3184,8 @@ void DwarfLinker::DIECloner::copyAbbrev(
static uint64_t getDwoId(const DWARFDie &CUDie,
const DWARFUnit &Unit) {
- auto DwoId = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_dwo_id));
- if (DwoId)
- return *DwoId;
- DwoId = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_GNU_dwo_id));
+ auto DwoId = dwarf::toUnsigned(CUDie.find({dwarf::DW_AT_dwo_id,
+ dwarf::DW_AT_GNU_dwo_id}));
if (DwoId)
return *DwoId;
return 0;
@@ -3196,9 +3194,9 @@ static uint64_t getDwoId(const DWARFDie
bool DwarfLinker::registerModuleReference(
const DWARFDie &CUDie, const DWARFUnit &Unit,
DebugMap &ModuleMap, unsigned Indent) {
- std::string PCMfile = dwarf::toString(CUDie.find(dwarf::DW_AT_dwo_name), "");
- if (PCMfile.empty())
- PCMfile = dwarf::toString(CUDie.find(dwarf::DW_AT_GNU_dwo_name), "");
+ std::string PCMfile =
+ dwarf::toString(CUDie.find({dwarf::DW_AT_dwo_name,
+ dwarf::DW_AT_GNU_dwo_name}), "");
if (PCMfile.empty())
return false;
Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp?rev=291967&r1=291966&r2=291967&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp Fri Jan 13 16:32:12 2017
@@ -1476,4 +1476,71 @@ TEST(DWARFDebugInfo, TestDwarfToFunction
// Test
}
+TEST(DWARFDebugInfo, TestFindAttrs) {
+ // Test the DWARFDie::find() and DWARFDie::findRecursively() that take an
+ // ArrayRef<dwarf::Attribute> value to make sure they work correctly.
+ uint16_t Version = 4;
+
+ const uint8_t AddrSize = sizeof(void *);
+ initLLVMIfNeeded();
+ Triple Triple = getHostTripleForAddrSize(AddrSize);
+ auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
+ if (HandleExpectedError(ExpectedDG))
+ return;
+ dwarfgen::Generator *DG = ExpectedDG.get().get();
+ dwarfgen::CompileUnit &CU = DG->addCompileUnit();
+
+ StringRef DieMangled("_Z3fooi");
+ // Scope to allow us to re-use the same DIE names
+ {
+ // Create a compile unit DIE that has an abbreviation that says it has
+ // children, but doesn't have any actual attributes. This helps us test
+ // a DIE that has only one child: a NULL DIE.
+ auto CUDie = CU.getUnitDIE();
+ auto FuncSpecDie = CUDie.addChild(DW_TAG_subprogram);
+ auto FuncDie = CUDie.addChild(DW_TAG_subprogram);
+ FuncSpecDie.addAttribute(DW_AT_MIPS_linkage_name, DW_FORM_strp, DieMangled);
+ FuncDie.addAttribute(DW_AT_specification, DW_FORM_ref4, FuncSpecDie);
+ }
+
+ MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
+ auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
+ EXPECT_TRUE((bool)Obj);
+ DWARFContextInMemory DwarfContext(*Obj.get());
+
+ // Verify the number of compile units is correct.
+ uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+ EXPECT_EQ(NumCUs, 1u);
+ DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+
+ // Get the compile unit DIE is valid.
+ auto CUDie = U->getUnitDIE(false);
+ EXPECT_TRUE(CUDie.isValid());
+
+ auto FuncSpecDie = CUDie.getFirstChild();
+ auto FuncDie = FuncSpecDie.getSibling();
+
+ // Make sure that passing in an empty attribute list behave correctly.
+ EXPECT_FALSE(FuncDie.find(ArrayRef<dwarf::Attribute>()).hasValue());
+
+ // Make sure that passing in a list of attribute that are not contained
+ // in the DIE returns nothing.
+ EXPECT_FALSE(FuncDie.find({DW_AT_low_pc, DW_AT_entry_pc}).hasValue());
+
+ ArrayRef<dwarf::Attribute>
+ Attrs = { DW_AT_linkage_name, DW_AT_MIPS_linkage_name };
+
+ // Make sure we can't extract the linkage name attributes when using
+ // DWARFDie::find() since it won't check the DW_AT_specification DIE.
+ EXPECT_FALSE(FuncDie.find(Attrs).hasValue());
+
+ // Make sure we can extract the name from the specification die when using
+ // DWARFDie::findRecursively() since it should recurse through the
+ // DW_AT_specification DIE.
+ auto NameOpt = FuncDie.findRecursively(Attrs);
+ EXPECT_TRUE(NameOpt.hasValue());
+ EXPECT_EQ(DieMangled, toString(NameOpt, ""));
+
+}
+
} // end anonymous namespace
More information about the llvm-commits
mailing list