summaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorWolfgang Pieb <Wolfgang.Pieb@sony.com>2018-06-20 22:56:37 +0000
committerWolfgang Pieb <Wolfgang.Pieb@sony.com>2018-06-20 22:56:37 +0000
commit5a4174c5401ebc6f6d2576b751b45e374e3c9d37 (patch)
tree877398c8d06cd78966c7723ef5f236228a5c821c /lib/DebugInfo
parenta5a4f60b04467710d4603dea6ebf4f7a36e32cc7 (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335188 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp7
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp23
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp10
-rw-r--r--lib/DebugInfo/DWARF/DWARFDie.cpp28
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp82
-rw-r--r--lib/DebugInfo/DWARF/DWARFVerifier.cpp9
6 files changed, 108 insertions, 51 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index a4053a30536..2ac94d05bc6 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -470,8 +470,13 @@ void DWARFContext::dump(
isLittleEndian(), savedAddressByteSize);
uint32_t offset = 0;
DWARFDebugRangeList rangeList;
- while (rangeList.extract(rangesData, &offset))
+ while (rangesData.isValidOffset(offset)) {
+ if (Error E = rangeList.extract(rangesData, &offset)) {
+ WithColor::error() << toString(std::move(E)) << '\n';
+ break;
+ }
rangeList.dump(OS);
+ }
}
if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index 87a0fd366af..a565718debd 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -16,20 +16,30 @@
using namespace llvm;
+// FIXME: There are several versions of this. Consolidate them.
+template <typename... Ts>
+static Error createError(char const *Fmt, const Ts &... Vals) {
+ std::string Buffer;
+ raw_string_ostream Stream(Buffer);
+ Stream << format(Fmt, Vals...);
+ return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
+}
+
void DWARFDebugRangeList::clear() {
Offset = -1U;
AddressSize = 0;
Entries.clear();
}
-bool DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
- uint32_t *offset_ptr) {
+Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
+ uint32_t *offset_ptr) {
clear();
if (!data.isValidOffset(*offset_ptr))
- return false;
+ return createError("invalid range list offset 0x%" PRIx32, *offset_ptr);
+
AddressSize = data.getAddressSize();
if (AddressSize != 4 && AddressSize != 8)
- return false;
+ return createError("invalid address size: %d", AddressSize);
Offset = *offset_ptr;
while (true) {
RangeListEntry Entry;
@@ -43,13 +53,14 @@ bool DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
// Check that both values were extracted correctly.
if (*offset_ptr != prev_offset + 2 * AddressSize) {
clear();
- return false;
+ return createError("invalid range list entry at offset 0x%" PRIx32,
+ prev_offset);
}
if (Entry.isEndOfListEntry())
break;
Entries.push_back(Entry);
}
- return true;
+ return Error::success();
}
void DWARFDebugRangeList::dump(raw_ostream &OS) const {
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 34359c0ef87..533b0922c1d 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -208,6 +208,8 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
Error DWARFDebugRnglist::extract(DWARFDataExtractor Data, uint32_t HeaderOffset,
uint32_t End, uint32_t *OffsetPtr) {
+ if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)
+ return createError("invalid range list offset 0x%" PRIx32, *OffsetPtr);
Entries.clear();
while (*OffsetPtr < End) {
RangeListEntry Entry{0, 0, 0, 0, 0};
@@ -351,7 +353,7 @@ uint32_t DWARFDebugRnglistTable::length() const {
return HeaderData.Length + sizeof(uint32_t);
}
-Optional<DWARFDebugRnglist>
+Expected<DWARFDebugRnglist>
DWARFDebugRnglistTable::findRangeList(DWARFDataExtractor Data,
uint32_t Offset) {
auto Entry = Ranges.find(Offset);
@@ -362,10 +364,8 @@ DWARFDebugRnglistTable::findRangeList(DWARFDataExtractor Data,
DWARFDebugRnglist RngList;
uint32_t End = HeaderOffset + length();
uint32_t StartingOffset = Offset;
- if (Error E = RngList.extract(Data, HeaderOffset, End, &Offset)) {
- llvm::consumeError(std::move(E));
- return None;
- }
+ if (Error E = RngList.extract(Data, HeaderOffset, End, &Offset))
+ return std::move(E);
Ranges[StartingOffset] = RngList;
return RngList;
}
diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp
index a471d97d75d..0ef65c2b0b6 100644
--- a/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -270,8 +270,12 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
FV.setUValue(*RangeListOffset);
FV.dump(OS, DumpOpts);
}
- dumpRanges(Obj, OS, Die.getAddressRanges(), U->getAddressByteSize(),
- sizeof(BaseIndent) + Indent + 4, DumpOpts);
+ if (auto RangesOrError = Die.getAddressRanges())
+ dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
+ sizeof(BaseIndent) + Indent + 4, DumpOpts);
+ else
+ WithColor::error() << "decoding address ranges: "
+ << toString(RangesOrError.takeError()) << '\n';
}
OS << ")\n";
@@ -385,13 +389,13 @@ bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
return false;
}
-DWARFAddressRangesVector DWARFDie::getAddressRanges() const {
+Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const {
if (isNULL())
return DWARFAddressRangesVector();
// Single range specified by low/high PC.
uint64_t LowPC, HighPC, Index;
if (getLowAndHighPC(LowPC, HighPC, Index))
- return {{LowPC, HighPC, Index}};
+ return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
Optional<DWARFFormValue> Value = find(DW_AT_ranges);
if (Value) {
@@ -407,8 +411,11 @@ void DWARFDie::collectChildrenAddressRanges(
if (isNULL())
return;
if (isSubprogramDIE()) {
- const auto &DIERanges = getAddressRanges();
- Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
+ if (auto DIERangesOrError = getAddressRanges())
+ Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(),
+ DIERangesOrError.get().end());
+ else
+ llvm::consumeError(DIERangesOrError.takeError());
}
for (auto Child : children())
@@ -416,10 +423,15 @@ void DWARFDie::collectChildrenAddressRanges(
}
bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
- for (const auto &R : getAddressRanges()) {
+ auto RangesOrError = getAddressRanges();
+ if (!RangesOrError) {
+ llvm::consumeError(RangesOrError.takeError());
+ return false;
+ }
+
+ for (const auto &R : RangesOrError.get())
if (R.LowPC <= Address && Address < R.HighPC)
return true;
- }
return false;
}
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 260c5dc94c4..6b7970d426b 100644
--- a/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -181,8 +181,8 @@ parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
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 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
}
}
-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 @@ void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
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::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
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
diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index e456de5b103..bb52f062d28 100644
--- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -324,8 +324,15 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
if (!Die.isValid())
return NumErrors;
- DWARFAddressRangesVector Ranges = Die.getAddressRanges();
+ auto RangesOrError = Die.getAddressRanges();
+ if (!RangesOrError) {
+ // FIXME: Report the error.
+ ++NumErrors;
+ llvm::consumeError(RangesOrError.takeError());
+ return NumErrors;
+ }
+ DWARFAddressRangesVector Ranges = RangesOrError.get();
// Build RI for this DIE and check that ranges within this DIE do not
// overlap.
DieRangeInfo RI(Die);