Index: lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -210,9 +210,41 @@ return (isHeaderChainValid && NumDebugInfoErrors == 0); } +static unsigned verifyDieParentRange(raw_ostream &OS, + const DWARFAddressRange &Range, + uint64_t ParentLowPC, + uint64_t ParentHighPC) { + unsigned NumErrors = 0; + + if (Range.LowPC < ParentLowPC) { + ++NumErrors; + OS << format("error: Address 0x%08" PRIx64 + " not in parent range [0x%08" PRIx64 " - 0x%08" PRIx64 "].\n", + Range.LowPC, ParentLowPC, ParentHighPC); + } + + if (Range.HighPC > ParentHighPC) { + ++NumErrors; + OS << format("error: Address 0x%08" PRIx64 + " not in parent range [0x%08" PRIx64 " - 0x%08" PRIx64 "].\n", + Range.HighPC, ParentLowPC, ParentHighPC); + } + + return NumErrors; +} + unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die) { unsigned NumErrors = 0; + + // Remember low and high PC. + uint64_t LowPC = -1; + uint64_t HighPC = 0; + for (auto Range : Die.getAddressRanges()) { + if (Range.LowPC < LowPC) + LowPC = Range.LowPC; + if (Range.HighPC > HighPC) + HighPC = Range.HighPC; if (Range.LowPC >= Range.HighPC) { ++NumErrors; OS << format("error: Invalid address range [0x%08" PRIx64 @@ -220,6 +252,25 @@ Range.LowPC, Range.HighPC); } } + + // The loop didn't execute and there's nothing more to check. + if (LowPC > HighPC) + return NumErrors; + + // Verify that all children fall within parent range. + DWARFAddressRangesVector ChildrenRanges; + Die.collectChildrenAddressRanges(ChildrenRanges); + for (auto Range : ChildrenRanges) { + NumErrors += verifyDieParentRange(OS, Range, LowPC, HighPC); + } + + // Verify that sibling falls within parent range. + if (DWARFDie Sibling = Die.getSibling()) { + for (auto Range : Die.getSibling().getAddressRanges()) { + NumErrors += verifyDieParentRange(OS, Range, LowPC, HighPC); + } + } + return NumErrors; }