aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorJonas Devlieghere <jonas@devlieghere.com>2018-09-21 07:49:29 +0000
committerJonas Devlieghere <jonas@devlieghere.com>2018-09-21 07:49:29 +0000
commit7ef2c2021e2ab03c96296066666c8c01372f435c (patch)
treeb1efd315df620cd99aa640b80a5b01cbfca877e7 /llvm/lib
parentb6eb21c29f5d5f062f47d5a736353436e89d7653 (diff)
downloadllvm-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.cpp9
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp32
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;
}