aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp80
1 files changed, 35 insertions, 45 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index bf499b6ee092..1fd6c1d7d282 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -196,6 +196,14 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
NumUnitErrors++;
}
+ // According to DWARF Debugging Information Format Version 5,
+ // 3.1.2 Skeleton Compilation Unit Entries:
+ // "A skeleton compilation unit has no children."
+ if (Die.getTag() == dwarf::DW_TAG_skeleton_unit && Die.hasChildren()) {
+ error() << "Skeleton compilation unit has children.\n";
+ NumUnitErrors++;
+ }
+
DieRangeInfo RI;
NumUnitErrors += verifyDieRanges(Die, RI);
@@ -468,27 +476,21 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
ReportError("DIE has invalid DW_AT_stmt_list encoding:");
break;
case DW_AT_location: {
- auto VerifyLocationExpr = [&](ArrayRef<uint8_t> D) {
+ if (Expected<std::vector<DWARFLocationExpression>> Loc =
+ Die.getLocations(DW_AT_location)) {
DWARFUnit *U = Die.getDwarfUnit();
- DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), 0);
- DWARFExpression Expression(Data, U->getVersion(),
- U->getAddressByteSize());
- bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
- return Op.isError();
- });
- if (Error || !Expression.verify(U))
- ReportError("DIE contains invalid DWARF expression:");
- };
- if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) {
- // Verify inlined location.
- VerifyLocationExpr(*Expr);
- } else if (auto LocOffset = AttrValue.Value.getAsSectionOffset()) {
- // Verify location list.
- if (auto DebugLoc = DCtx.getDebugLoc())
- if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset))
- for (const auto &Entry : LocList->Entries)
- VerifyLocationExpr(Entry.Loc);
- }
+ for (const auto &Entry : *Loc) {
+ DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
+ DWARFExpression Expression(Data, U->getVersion(),
+ U->getAddressByteSize());
+ bool Error = any_of(Expression, [](DWARFExpression::Operation &Op) {
+ return Op.isError();
+ });
+ if (Error || !Expression.verify(U))
+ ReportError("DIE contains invalid DWARF expression:");
+ }
+ } else
+ ReportError(toString(Loc.takeError()));
break;
}
case DW_AT_specification:
@@ -640,7 +642,7 @@ unsigned DWARFVerifier::verifyDebugInfoReferences() {
// getting the DIE by offset and emitting an error
OS << "Verifying .debug_info references...\n";
unsigned NumErrors = 0;
- for (const std::pair<uint64_t, std::set<uint64_t>> &Pair :
+ for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
ReferenceToDIEOffsets) {
if (DCtx.getDIEForOffset(Pair.first))
continue;
@@ -968,7 +970,7 @@ DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
: Bucket(Bucket), Index(Index) {}
- bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; };
+ bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
};
uint32_t NumErrors = 0;
@@ -1278,36 +1280,24 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
}
static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
- Optional<DWARFFormValue> Location = Die.findRecursively(DW_AT_location);
- if (!Location)
+ Expected<std::vector<DWARFLocationExpression>> Loc =
+ Die.getLocations(DW_AT_location);
+ if (!Loc) {
+ consumeError(Loc.takeError());
return false;
-
- auto ContainsInterestingOperators = [&](ArrayRef<uint8_t> D) {
- DWARFUnit *U = Die.getDwarfUnit();
- DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), U->getAddressByteSize());
+ }
+ DWARFUnit *U = Die.getDwarfUnit();
+ for (const auto &Entry : *Loc) {
+ DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
+ U->getAddressByteSize());
DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
- return any_of(Expression, [](DWARFExpression::Operation &Op) {
+ bool IsInteresting = any_of(Expression, [](DWARFExpression::Operation &Op) {
return !Op.isError() && (Op.getCode() == DW_OP_addr ||
Op.getCode() == DW_OP_form_tls_address ||
Op.getCode() == DW_OP_GNU_push_tls_address);
});
- };
-
- if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
- // Inlined location.
- if (ContainsInterestingOperators(*Expr))
+ if (IsInteresting)
return true;
- } else if (Optional<uint64_t> Offset = Location->getAsSectionOffset()) {
- // Location list.
- if (const DWARFDebugLoc *DebugLoc = DCtx.getDebugLoc()) {
- if (const DWARFDebugLoc::LocationList *LocList =
- DebugLoc->getLocationListAtOffset(*Offset)) {
- if (any_of(LocList->Entries, [&](const DWARFDebugLoc::Entry &E) {
- return ContainsInterestingOperators(E.Loc);
- }))
- return true;
- }
- }
}
return false;
}