diff options
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 80 |
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; } |