mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[codeview] Try to handle errors better in record iterator
llvm-svn: 269381
This commit is contained in:
parent
21c4b894af
commit
a9f9bd2354
@ -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;
|
||||
|
@ -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>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user