diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2018-09-21 07:49:29 +0000 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2018-09-21 07:49:29 +0000 |
commit | 7ef2c2021e2ab03c96296066666c8c01372f435c (patch) | |
tree | b1efd315df620cd99aa640b80a5b01cbfca877e7 /llvm/lib | |
parent | b6eb21c29f5d5f062f47d5a736353436e89d7653 (diff) | |
download | llvm-7ef2c2021e2ab03c96296066666c8c01372f435c.zip llvm-7ef2c2021e2ab03c96296066666c8c01372f435c.tar.gz llvm-7ef2c2021e2ab03c96296066666c8c01372f435c.tar.bz2 |
[dwarfdump] Verify compatibility of attribute TAGs.
Verify that DW_AT_specification and DW_AT_abstract_origin reference a
DIE with a compatible tag.
Differential revision: https://reviews.llvm.org/D38719
llvm-svn: 342712
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 32 |
2 files changed, 34 insertions, 7 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index b2bc2c8..6c3c62d 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -112,6 +112,15 @@ void DWARFUnitVector::addUnitsImpl( } } +DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) { + auto I = std::upper_bound(begin(), end(), Unit, + [](const std::unique_ptr<DWARFUnit> &LHS, + const std::unique_ptr<DWARFUnit> &RHS) { + return LHS->getOffset() < RHS->getOffset(); + }); + return this->insert(I, std::move(Unit))->get(); +} + DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const { auto end = begin() + getNumInfoUnits(); auto *CU = diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 56187d2..94accc6 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -261,7 +261,8 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S, bool isUnitDWARF64 = false; bool isHeaderChainValid = true; bool hasDIE = DebugInfoData.isValidOffset(Offset); - DWARFUnitVector UnitVector{}; + DWARFUnitVector TypeUnitVector; + DWARFUnitVector CompileUnitVector; while (hasDIE) { OffsetStart = Offset; if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType, @@ -272,15 +273,15 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S, } else { DWARFUnitHeader Header; Header.extract(DCtx, DebugInfoData, &OffsetStart, SectionKind); - std::unique_ptr<DWARFUnit> Unit; + DWARFUnit *Unit; switch (UnitType) { case dwarf::DW_UT_type: case dwarf::DW_UT_split_type: { - Unit.reset(new DWARFTypeUnit( + Unit = TypeUnitVector.addUnit(llvm::make_unique<DWARFTypeUnit>( DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(), DObj.getStringSection(), DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), DObj.getLineSection(), - DCtx.isLittleEndian(), false, UnitVector)); + DCtx.isLittleEndian(), false, TypeUnitVector)); break; } case dwarf::DW_UT_skeleton: @@ -289,11 +290,11 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S, case dwarf::DW_UT_partial: // UnitType = 0 means that we are verifying a compile unit in DWARF v4. case 0: { - Unit.reset(new DWARFCompileUnit( + Unit = CompileUnitVector.addUnit(llvm::make_unique<DWARFCompileUnit>( DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(), DObj.getStringSection(), DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), DObj.getLineSection(), - DCtx.isLittleEndian(), false, UnitVector)); + DCtx.isLittleEndian(), false, CompileUnitVector)); break; } default: { llvm_unreachable("Invalid UnitType."); } @@ -444,7 +445,24 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, } break; } - + case DW_AT_specification: + case DW_AT_abstract_origin: { + if (auto ReferencedDie = Die.getAttributeValueAsReferencedDie(Attr)) { + auto DieTag = Die.getTag(); + auto RefTag = ReferencedDie.getTag(); + if (DieTag == RefTag) + break; + if (DieTag == DW_TAG_inlined_subroutine && RefTag == DW_TAG_subprogram) + break; + if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member) + break; + ReportError("DIE with tag " + TagString(DieTag) + " has " + + AttributeString(Attr) + + " that points to DIE with " + "incompatible tag " + + TagString(RefTag)); + } + } default: break; } |