[DWARF] Improved error reporting for range lists.
Errors found processing the DW_AT_ranges attribute are propagated by lower level
routines and reported by their callers.
Reviewer: JDevlieghere
Differential Revision: https://reviews.llvm.org/D48344
llvm-svn: 335188
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 260c5dc..6b7970d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -181,8 +181,8 @@
return Table;
}
-bool DWARFUnit::extractRangeList(uint32_t RangeListOffset,
- DWARFDebugRangeList &RangeList) const {
+Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,
+ DWARFDebugRangeList &RangeList) const {
// Require that compile unit is extracted.
assert(!DieArray.empty());
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
@@ -397,26 +397,39 @@
}
}
-DWARFAddressRangesVector DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
+Expected<DWARFAddressRangesVector>
+DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
if (getVersion() <= 4) {
DWARFDebugRangeList RangeList;
- if (extractRangeList(Offset, RangeList))
- return RangeList.getAbsoluteRanges(getBaseAddress());
- return DWARFAddressRangesVector();
+ if (Error E = extractRangeList(Offset, RangeList))
+ return std::move(E);
+ return RangeList.getAbsoluteRanges(getBaseAddress());
}
if (RngListTable) {
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
isLittleEndian, RngListTable->getAddrSize());
- if (auto RangeList = RngListTable->findRangeList(RangesData, Offset))
- return RangeList->getAbsoluteRanges(getBaseAddress());
+ auto RangeListOrError = RngListTable->findRangeList(RangesData, Offset);
+ if (RangeListOrError)
+ return RangeListOrError.get().getAbsoluteRanges(getBaseAddress());
+ return RangeListOrError.takeError();
}
- return DWARFAddressRangesVector();
+
+ return make_error<StringError>("missing or invalid range list table",
+ inconvertibleErrorCode());
}
-DWARFAddressRangesVector DWARFUnit::findRnglistFromIndex(uint32_t Index) {
+Expected<DWARFAddressRangesVector>
+DWARFUnit::findRnglistFromIndex(uint32_t Index) {
if (auto Offset = getRnglistOffset(Index))
return findRnglistFromOffset(*Offset + RangeSectionBase);
- return DWARFAddressRangesVector();
+
+ std::string Buffer;
+ raw_string_ostream Stream(Buffer);
+ if (RngListTable)
+ Stream << format("invalid range list table index %d", Index);
+ else
+ Stream << "missing or invalid range list table";
+ return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
}
void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
@@ -424,11 +437,16 @@
if (!UnitDie)
return;
// First, check if unit DIE describes address ranges for the whole unit.
- const auto &CUDIERanges = UnitDie.getAddressRanges();
- if (!CUDIERanges.empty()) {
- CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
- return;
- }
+ auto CUDIERangesOrError = UnitDie.getAddressRanges();
+ if (CUDIERangesOrError) {
+ if (!CUDIERangesOrError.get().empty()) {
+ CURanges.insert(CURanges.end(), CUDIERangesOrError.get().begin(),
+ CUDIERangesOrError.get().end());
+ return;
+ }
+ } else
+ WithColor::error() << "decoding address ranges: "
+ << toString(CUDIERangesOrError.takeError()) << '\n';
// This function is usually called if there in no .debug_aranges section
// in order to produce a compile unit level set of address ranges that
@@ -454,21 +472,25 @@
void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
if (Die.isSubroutineDIE()) {
- for (const auto &R : Die.getAddressRanges()) {
- // Ignore 0-sized ranges.
- if (R.LowPC == R.HighPC)
- continue;
- auto B = AddrDieMap.upper_bound(R.LowPC);
- if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
- // The range is a sub-range of existing ranges, we need to split the
- // existing range.
- if (R.HighPC < B->second.first)
- AddrDieMap[R.HighPC] = B->second;
- if (R.LowPC > B->first)
- AddrDieMap[B->first].first = R.LowPC;
+ auto DIERangesOrError = Die.getAddressRanges();
+ if (DIERangesOrError) {
+ for (const auto &R : DIERangesOrError.get()) {
+ // Ignore 0-sized ranges.
+ if (R.LowPC == R.HighPC)
+ continue;
+ auto B = AddrDieMap.upper_bound(R.LowPC);
+ if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
+ // The range is a sub-range of existing ranges, we need to split the
+ // existing range.
+ if (R.HighPC < B->second.first)
+ AddrDieMap[R.HighPC] = B->second;
+ if (R.LowPC > B->first)
+ AddrDieMap[B->first].first = R.LowPC;
+ }
+ AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
}
- AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
- }
+ } else
+ llvm::consumeError(DIERangesOrError.takeError());
}
// Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
// simplify the logic to update AddrDieMap. The child's range will always