diff options
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/RecordIterator.h | 23 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/TypeStream.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Raw/TpiStream.h | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 7 |
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(); } |