Fix llvm-symbolizer to navigate both DW_AT_abstract_origin and DW_AT_specification in a single chain

In a recent refactoring (r291959) this regressed to only following one
or the other, not both, in a single chain.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297676 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2017-03-13 21:46:37 +00:00
parent 6f54996a23
commit bc67646a35
3 changed files with 28 additions and 42 deletions

View File

@ -146,14 +146,6 @@ public:
/// 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.
///
/// \param Attr the attribute to extract.
/// \returns an optional DWARFFormValue that will have the form value if the
/// 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.

View File

@ -149,21 +149,6 @@ DWARFDie::find(dwarf::Attribute Attr) const {
return None;
}
Optional<DWARFFormValue>
DWARFDie::findRecursively(dwarf::Attribute Attr) const {
if (!isValid())
return None;
if (auto Value = find(Attr))
return Value;
if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
if (auto Value = Die.find(Attr))
return Value;
if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification))
if (auto Value = Die.find(Attr))
return Value;
return None;
}
Optional<DWARFFormValue>
DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
if (!isValid())
@ -182,14 +167,17 @@ Optional<DWARFFormValue>
DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
if (!isValid())
return None;
if (auto Value = find(Attrs))
auto Die = *this;
if (auto Value = Die.find(Attrs))
return Value;
if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
Die = D;
if (auto Value = Die.find(Attrs))
return Value;
if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
Die = D;
if (auto Value = Die.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;
}

View File

@ -1279,17 +1279,21 @@ TEST(DWARFDebugInfo, TestFindRecurse) {
dwarfgen::Generator *DG = ExpectedDG.get().get();
dwarfgen::CompileUnit &CU = DG->addCompileUnit();
StringRef SpecDieName("spec");
StringRef AbsDieName("abs");
StringRef SpecDieName = "spec";
StringRef SpecLinkageName = "spec_linkage";
StringRef AbsDieName = "abs";
// Scope to allow us to re-use the same DIE names
{
auto CUDie = CU.getUnitDIE();
auto FuncSpecDie = CUDie.addChild(DW_TAG_subprogram);
auto FuncAbsDie = CUDie.addChild(DW_TAG_subprogram);
auto FuncDie = CUDie.addChild(DW_TAG_subprogram);
auto VarAbsDie = CUDie.addChild(DW_TAG_variable);
auto VarDie = CUDie.addChild(DW_TAG_variable);
FuncSpecDie.addAttribute(DW_AT_name, DW_FORM_strp, SpecDieName);
FuncDie.addAttribute(DW_AT_specification, DW_FORM_ref4, FuncSpecDie);
FuncAbsDie.addAttribute(DW_AT_linkage_name, DW_FORM_strp, SpecLinkageName);
FuncAbsDie.addAttribute(DW_AT_specification, DW_FORM_ref4, FuncSpecDie);
FuncDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, FuncAbsDie);
VarAbsDie.addAttribute(DW_AT_name, DW_FORM_strp, AbsDieName);
VarDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, VarAbsDie);
}
@ -1309,41 +1313,43 @@ TEST(DWARFDebugInfo, TestFindRecurse) {
EXPECT_TRUE(CUDie.isValid());
auto FuncSpecDie = CUDie.getFirstChild();
auto FuncDie = FuncSpecDie.getSibling();
auto FuncAbsDie = FuncSpecDie.getSibling();
auto FuncDie = FuncAbsDie.getSibling();
auto VarAbsDie = FuncDie.getSibling();
auto VarDie = VarAbsDie.getSibling();
// Make sure we can't extract the name from the specification die when using
// DWARFDie::find() since it won't check the DW_AT_specification DIE.
EXPECT_FALSE(FuncDie.find(DW_AT_name).hasValue());
EXPECT_FALSE(FuncDie.find(DW_AT_name));
// 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(DW_AT_name);
EXPECT_TRUE(NameOpt.hasValue());
EXPECT_TRUE(NameOpt);
// Test the dwarf::toString() helper function.
auto StringOpt = toString(NameOpt);
EXPECT_TRUE(StringOpt.hasValue());
EXPECT_TRUE(StringOpt);
EXPECT_EQ(SpecDieName, StringOpt.getValueOr(nullptr));
// Test the dwarf::toString() helper function with a default value specified.
EXPECT_EQ(SpecDieName, toString(NameOpt, nullptr));
auto LinkageNameOpt = FuncDie.findRecursively(DW_AT_linkage_name);
EXPECT_EQ(SpecLinkageName, toString(LinkageNameOpt).getValueOr(nullptr));
// Make sure we can't extract the name from the abstract origin die when using
// DWARFDie::find() since it won't check the DW_AT_abstract_origin DIE.
EXPECT_FALSE(VarDie.find(DW_AT_name).hasValue());
EXPECT_FALSE(VarDie.find(DW_AT_name));
// Make sure we can extract the name from the abstract origin die when using
// DWARFDie::findRecursively() since it should recurse through the
// DW_AT_abstract_origin DIE.
NameOpt = VarDie.findRecursively(DW_AT_name);
EXPECT_TRUE(NameOpt.hasValue());
EXPECT_TRUE(NameOpt);
// Test the dwarf::toString() helper function.
StringOpt = toString(NameOpt);
EXPECT_TRUE(StringOpt.hasValue());
EXPECT_TRUE(StringOpt);
EXPECT_EQ(AbsDieName, StringOpt.getValueOr(nullptr));
// Test the dwarf::toString() helper function with a default value specified.
EXPECT_EQ(AbsDieName, toString(NameOpt, nullptr));
}
TEST(DWARFDebugInfo, TestDwarfToFunctions) {