summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/RecordIterator.h23
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/TypeStream.h4
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp4
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp7
7 files changed, 29 insertions, 15 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
index bab18f247d0..95473dd0c83 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -78,7 +78,7 @@ public:
/// Visits the type records in Data. Sets the error flag on parse failures.
void visitTypeStream(ArrayRef<uint8_t> Data) {
- for (const auto &I : makeTypeRange(Data)) {
+ for (const auto &I : makeTypeRange(Data, &HadError)) {
visitTypeRecord(I);
if (hadError())
break;
diff --git a/llvm/include/llvm/DebugInfo/CodeView/RecordIterator.h b/llvm/include/llvm/DebugInfo/CodeView/RecordIterator.h
index f2ed8d26173..f5ef7de3ddd 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/RecordIterator.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/RecordIterator.h
@@ -31,12 +31,12 @@ public:
ArrayRef<uint8_t> Data;
};
- explicit RecordIterator(const ArrayRef<uint8_t> &RecordBytes)
- : Data(RecordBytes), AtEnd(false) {
+ explicit RecordIterator(const ArrayRef<uint8_t> &RecordBytes, bool *HadError)
+ : HadError(HadError), Data(RecordBytes), AtEnd(false) {
next(); // Prime the pump
}
- RecordIterator() : AtEnd(true) {}
+ RecordIterator() : HadError(nullptr), AtEnd(true) {}
// For iterators to compare equal, they must both point at the same record
// in the same data stream, or they must both be at the end of a stream.
@@ -82,13 +82,16 @@ private:
// FIXME: Use consumeObject when it deals in ArrayRef<uint8_t>.
if (Data.size() < sizeof(RecordPrefix))
- return;
+ return parseError();
const auto *Rec = reinterpret_cast<const RecordPrefix *>(Data.data());
Data = Data.drop_front(sizeof(RecordPrefix));
Current.Length = Rec->RecordLen;
Current.Type = static_cast<Kind>(uint16_t(Rec->RecordKind));
- Current.Data = Data.slice(0, Current.Length - 2);
+ size_t RecLen = Current.Length - 2;
+ if (RecLen > Data.size())
+ return parseError();
+ Current.Data = Data.slice(0, RecLen);
// The next record starts immediately after this one.
Data = Data.drop_front(Current.Data.size());
@@ -100,6 +103,12 @@ private:
return;
}
+ void parseError() {
+ if (HadError)
+ *HadError = true;
+ }
+
+ bool *HadError;
ArrayRef<uint8_t> Data;
Record Current;
bool AtEnd;
@@ -107,8 +116,8 @@ private:
template <typename Kind>
inline iterator_range<RecordIterator<Kind>>
-makeRecordRange(ArrayRef<uint8_t> Data) {
- return make_range(RecordIterator<Kind>(Data), RecordIterator<Kind>());
+makeRecordRange(ArrayRef<uint8_t> Data, bool *HadError) {
+ return make_range(RecordIterator<Kind>(Data, HadError), RecordIterator<Kind>());
}
}
}
diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index fc8cf904b84..2999b95248f 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -329,7 +329,7 @@ struct ThreadLocalDataSym {
typedef RecordIterator<SymbolRecordKind> SymbolIterator;
inline iterator_range<SymbolIterator> makeSymbolRange(ArrayRef<uint8_t> Data) {
- return make_range(SymbolIterator(Data), SymbolIterator());
+ return make_range(SymbolIterator(Data, nullptr), SymbolIterator());
}
} // namespace codeview
diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeStream.h b/llvm/include/llvm/DebugInfo/CodeView/TypeStream.h
index 1998d10090d..c1370d889c8 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/TypeStream.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/TypeStream.h
@@ -27,8 +27,8 @@ namespace codeview {
typedef RecordIterator<TypeLeafKind> TypeIterator;
-inline iterator_range<TypeIterator> makeTypeRange(ArrayRef<uint8_t> Data) {
- return make_range(TypeIterator(Data), TypeIterator());
+inline iterator_range<TypeIterator> makeTypeRange(ArrayRef<uint8_t> Data, bool *HadError) {
+ return make_range(TypeIterator(Data, HadError), TypeIterator());
}
} // end namespace codeview
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
index 7681b124280..ac7c7978e34 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
@@ -38,7 +38,7 @@ public:
uint32_t TypeIndexEnd() const;
uint32_t NumTypeRecords() const;
- iterator_range<codeview::TypeIterator> types() const;
+ iterator_range<codeview::TypeIterator> types(bool *HadError) const;
private:
PDBFile &Pdb;
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index fd0d0eb2c40..db2ea20ce14 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -129,6 +129,6 @@ uint32_t TpiStream::NumTypeRecords() const {
return TypeIndexEnd() - TypeIndexBegin();
}
-iterator_range<codeview::TypeIterator> TpiStream::types() const {
- return codeview::makeTypeRange(RecordsBuffer.data());
+iterator_range<codeview::TypeIterator> TpiStream::types(bool *HadError) const {
+ return codeview::makeTypeRange(RecordsBuffer.data(), /*HadError=*/HadError);
}
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index 62016d2d389..748bccfe9de 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -44,6 +44,7 @@
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
@@ -376,7 +377,8 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File) {
ListScope L(P, "Records");
codeview::CVTypeDumper TD(P, false);
- for (auto &Type : Tpi.types()) {
+ bool HadError = false;
+ for (auto &Type : Tpi.types(&HadError)) {
DictScope DD(P, "");
if (opts::DumpTpiRecords)
@@ -385,6 +387,9 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File) {
if (opts::DumpTpiRecordBytes)
P.printBinaryBlock("Bytes", Type.Data);
}
+ if (HadError)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "TPI stream contained corrupt record");
}
return Error::success();
}
OpenPOWER on IntegriCloud