From 5cfb6469b84100a42882cf2d5acec05ce71633c1 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Sat, 28 May 2016 05:21:57 +0000 Subject: [PATCH] [pdb] Finish conversion to zero copy pdb access. This converts remaining uses of ByteStream, which was still left in the symbol stream and type stream, to using the new StreamInterface zero-copy classes. RecordIterator is finally deleted, so this is the only way left now. Additionally, more error checking is added when iterating the various streams. With this, the transition to zero copy pdb access is complete. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271101 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/CodeView/ByteStream.h | 12 +- include/llvm/DebugInfo/CodeView/CVRecord.h | 47 +++++++ include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h | 6 +- include/llvm/DebugInfo/CodeView/CVTypeVisitor.h | 7 +- include/llvm/DebugInfo/CodeView/RecordIterator.h | 143 --------------------- include/llvm/DebugInfo/CodeView/StreamArray.h | 54 ++++++-- include/llvm/DebugInfo/CodeView/StreamInterface.h | 2 - include/llvm/DebugInfo/CodeView/StreamReader.h | 5 +- include/llvm/DebugInfo/CodeView/StreamRef.h | 5 - include/llvm/DebugInfo/CodeView/SymbolDumper.h | 2 +- include/llvm/DebugInfo/CodeView/SymbolRecord.h | 8 +- include/llvm/DebugInfo/CodeView/TypeDumper.h | 3 +- include/llvm/DebugInfo/CodeView/TypeRecord.h | 5 + include/llvm/DebugInfo/CodeView/TypeStream.h | 37 ------ include/llvm/DebugInfo/CodeView/TypeStreamMerger.h | 3 +- include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h | 3 +- include/llvm/DebugInfo/PDB/Raw/ModInfo.h | 13 +- include/llvm/DebugInfo/PDB/Raw/ModStream.h | 5 +- include/llvm/DebugInfo/PDB/Raw/PublicsStream.h | 6 +- include/llvm/DebugInfo/PDB/Raw/SymbolStream.h | 7 +- include/llvm/DebugInfo/PDB/Raw/TpiStream.h | 8 +- lib/DebugInfo/CodeView/ByteStream.cpp | 32 +---- lib/DebugInfo/CodeView/StreamReader.cpp | 13 +- lib/DebugInfo/CodeView/SymbolDumper.cpp | 4 +- lib/DebugInfo/CodeView/TypeDumper.cpp | 5 +- lib/DebugInfo/CodeView/TypeStreamMerger.cpp | 12 +- lib/DebugInfo/PDB/Raw/ModInfo.cpp | 29 ++--- lib/DebugInfo/PDB/Raw/ModStream.cpp | 4 +- lib/DebugInfo/PDB/Raw/PublicsStream.cpp | 11 +- lib/DebugInfo/PDB/Raw/SymbolStream.cpp | 17 +-- lib/DebugInfo/PDB/Raw/TpiStream.cpp | 7 +- tools/llvm-pdbdump/llvm-pdbdump.cpp | 18 ++- tools/llvm-readobj/COFFDumper.cpp | 45 ++++++- 33 files changed, 228 insertions(+), 350 deletions(-) create mode 100644 include/llvm/DebugInfo/CodeView/CVRecord.h delete mode 100644 include/llvm/DebugInfo/CodeView/RecordIterator.h delete mode 100644 include/llvm/DebugInfo/CodeView/TypeStream.h diff --git a/include/llvm/DebugInfo/CodeView/ByteStream.h b/include/llvm/DebugInfo/CodeView/ByteStream.h index ba162320235..44fcbaabd6d 100644 --- a/include/llvm/DebugInfo/CodeView/ByteStream.h +++ b/include/llvm/DebugInfo/CodeView/ByteStream.h @@ -24,16 +24,9 @@ class StreamReader; class ByteStream : public StreamInterface { public: ByteStream(); - explicit ByteStream(MutableArrayRef Data); + explicit ByteStream(ArrayRef Data); ~ByteStream() override; - void reset(); - - void load(uint32_t Length); - Error load(StreamReader &Reader, uint32_t Length); - - Error readBytes(uint32_t Offset, - MutableArrayRef Buffer) const override; Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const override; @@ -43,8 +36,7 @@ public: StringRef str() const; private: - MutableArrayRef Data; - std::unique_ptr Ownership; + ArrayRef Data; }; } // end namespace pdb diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h new file mode 100644 index 00000000000..f6736dd3669 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -0,0 +1,47 @@ +//===- RecordIterator.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H +#define LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/StreamInterface.h" +#include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/Support/Endian.h" + +namespace llvm { +namespace codeview { + +template struct CVRecord { + uint32_t Length; + Kind Type; + ArrayRef Data; +}; + +template struct VarStreamArrayExtractor> { + Error operator()(const StreamInterface &Stream, uint32_t &Len, + CVRecord &Item) const { + const RecordPrefix *Prefix = nullptr; + StreamReader Reader(Stream); + if (auto EC = Reader.readObject(Prefix)) + return EC; + Item.Length = Prefix->RecordLen; + Item.Type = static_cast(uint16_t(Prefix->RecordKind)); + if (auto EC = Reader.readBytes(Item.Data, Item.Length - 2)) + return EC; + Len = Prefix->RecordLen + 2; + return Error::success(); + } +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h index febd9a02615..7c88956c984 100644 --- a/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h @@ -10,8 +10,8 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H +#include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/RecordIterator.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h" #include "llvm/Support/ErrorOr.h" @@ -72,8 +72,8 @@ public: } /// Visits the symbol records in Data. Sets the error flag on parse failures. - void visitSymbolStream(ArrayRef Data) { - for (const auto &I : makeSymbolRange(Data, &HadError)) { + void visitSymbolStream(const CVSymbolArray &Symbols) { + for (const auto &I : Symbols) { visitSymbolRecord(I); if (hadError()) break; diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index 6d260900257..0e21bfc669d 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -10,11 +10,10 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H +#include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/RecordIterator.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/Support/ErrorOr.h" namespace llvm { @@ -81,8 +80,8 @@ public: } /// Visits the type records in Data. Sets the error flag on parse failures. - void visitTypeStream(ArrayRef Data) { - for (const auto &I : makeTypeRange(Data, &HadError)) { + void visitTypeStream(const CVTypeArray &Types) { + for (const auto &I : Types) { visitTypeRecord(I); if (hadError()) break; diff --git a/include/llvm/DebugInfo/CodeView/RecordIterator.h b/include/llvm/DebugInfo/CodeView/RecordIterator.h deleted file mode 100644 index a8073eae9c7..00000000000 --- a/include/llvm/DebugInfo/CodeView/RecordIterator.h +++ /dev/null @@ -1,143 +0,0 @@ -//===- RecordIterator.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H -#define LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/iterator_range.h" -#include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/CodeView/StreamInterface.h" -#include "llvm/DebugInfo/CodeView/StreamReader.h" -#include "llvm/Support/Endian.h" - -namespace llvm { -namespace codeview { - -template struct CVRecord { - uint32_t Length; - Kind Type; - ArrayRef Data; -}; - -template struct VarStreamArrayExtractor> { - uint32_t operator()(const StreamInterface &Stream, - CVRecord &Item) const { - const RecordPrefix *Prefix = nullptr; - StreamReader Reader(Stream); - if (auto EC = Reader.readObject(Prefix)) { - consumeError(std::move(EC)); - return 0; - } - Item.Length = Prefix->RecordLen; - Item.Type = static_cast(uint16_t(Prefix->RecordKind)); - if (auto EC = Reader.readBytes(Item.Length - 2, Item.Data)) { - consumeError(std::move(EC)); - return 0; - } - return Prefix->RecordLen + 2; - } -}; - -// A const input iterator interface to the CodeView record stream. -template class RecordIterator { -public: - - explicit RecordIterator(const ArrayRef &RecordBytes, bool *HadError) - : HadError(HadError), Data(RecordBytes), AtEnd(false) { - next(); // Prime the pump - } - - 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. - friend bool operator==(const RecordIterator &lhs, - const RecordIterator &rhs) { - return (lhs.Data.begin() == rhs.Data.begin()) || (lhs.AtEnd && rhs.AtEnd); - } - - friend bool operator!=(const RecordIterator &lhs, - const RecordIterator &rhs) { - return !(lhs == rhs); - } - - const CVRecord &operator*() const { - assert(!AtEnd); - return Current; - } - - const CVRecord *operator->() const { - assert(!AtEnd); - return &Current; - } - - RecordIterator &operator++() { - next(); - return *this; - } - - RecordIterator operator++(int) { - RecordIterator Original = *this; - ++*this; - return Original; - } - -private: - void next() { - assert(!AtEnd && "Attempted to advance more than one past the last rec"); - if (Data.empty()) { - // We've advanced past the last record. - AtEnd = true; - return; - } - - // FIXME: Use consumeObject when it deals in ArrayRef. - if (Data.size() < sizeof(RecordPrefix)) - return parseError(); - const auto *Rec = reinterpret_cast(Data.data()); - Data = Data.drop_front(sizeof(RecordPrefix)); - - Current.Length = Rec->RecordLen; - Current.Type = static_cast(uint16_t(Rec->RecordKind)); - 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()); - - // FIXME: The stream contains LF_PAD bytes that we need to ignore, but those - // are typically included in LeafData. We may need to call skipPadding() if - // we ever find a record that doesn't count those bytes. - - return; - } - - void parseError() { - if (HadError) - *HadError = true; - } - - bool *HadError; - ArrayRef Data; - CVRecord Current; - bool AtEnd; -}; - -template -inline iterator_range> -makeRecordRange(ArrayRef Data, bool *HadError) { - return make_range(RecordIterator(Data, HadError), RecordIterator()); -} -} -} - -#endif diff --git a/include/llvm/DebugInfo/CodeView/StreamArray.h b/include/llvm/DebugInfo/CodeView/StreamArray.h index 7e4296c5209..23e475d7546 100644 --- a/include/llvm/DebugInfo/CodeView/StreamArray.h +++ b/include/llvm/DebugInfo/CodeView/StreamArray.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_CODEVIEW_STREAMARRAY_H #include "llvm/DebugInfo/CodeView/StreamRef.h" +#include "llvm/Support/Error.h" #include #include @@ -25,8 +26,11 @@ namespace codeview { /// value type. template struct VarStreamArrayExtractor { // Method intentionally deleted. You must provide an explicit specialization - // with the following method implemented. - uint32_t operator()(const StreamInterface &Stream, T &t) const = delete; + // with the following method implemented. On output return `Len` should + // contain the number of bytes to consume from the stream, and `Item` should + // be initialized with the proper value. + Error operator()(const StreamInterface &Stream, uint32_t &Len, + T &Item) const = delete; }; /// VarStreamArray represents an array of variable length records backed by a @@ -52,7 +56,9 @@ public: VarStreamArray(StreamRef Stream) : Stream(Stream) {} - Iterator begin() const { return Iterator(*this); } + Iterator begin(bool *HadError = nullptr) const { + return Iterator(*this, HadError); + } Iterator end() const { return Iterator(); } @@ -65,11 +71,20 @@ template class VarStreamArrayIterator { typedef VarStreamArray ArrayType; public: - VarStreamArrayIterator(const ArrayType &Array) - : Array(&Array), IterRef(Array.Stream) { - ThisLen = Extract(IterRef, ThisValue); + VarStreamArrayIterator(const ArrayType &Array, bool *HadError = nullptr) + : Array(&Array), IterRef(Array.Stream), HasError(false), + HadError(HadError) { + auto EC = Extract(IterRef, ThisLen, ThisValue); + if (EC) { + consumeError(std::move(EC)); + HasError = true; + if (HadError) + *HadError = true; + } } - VarStreamArrayIterator() : Array(nullptr), IterRef() {} + VarStreamArrayIterator() : Array(nullptr), IterRef(), HasError(false) {} + ~VarStreamArrayIterator() {} + bool operator==(const IterType &R) const { if (Array && R.Array) { // Both have a valid array, make sure they're same. @@ -87,19 +102,30 @@ public: bool operator!=(const IterType &R) { return !(*this == R); } - const ValueType &operator*() const { return ThisValue; } + const ValueType &operator*() const { + assert(Array && !HasError); + return ThisValue; + } IterType &operator++() { - if (!Array || IterRef.getLength() == 0 || ThisLen == 0) + if (!Array || IterRef.getLength() == 0 || ThisLen == 0 || HasError) return *this; IterRef = IterRef.drop_front(ThisLen); if (IterRef.getLength() == 0) ThisLen = 0; - else - // TODO: We should report an error if Extract fails. - ThisLen = Extract(IterRef, ThisValue); - if (ThisLen == 0) + else { + auto EC = Extract(IterRef, ThisLen, ThisValue); + if (EC) { + consumeError(std::move(EC)); + HasError = true; + if (HadError) + *HadError = true; + } + } + if (ThisLen == 0 || HasError) { Array = nullptr; + ThisLen = 0; + } return *this; } @@ -114,6 +140,8 @@ private: uint32_t ThisLen; ValueType ThisValue; StreamRef IterRef; + bool HasError; + bool *HadError; Extractor Extract; }; diff --git a/include/llvm/DebugInfo/CodeView/StreamInterface.h b/include/llvm/DebugInfo/CodeView/StreamInterface.h index fb73da35111..f875f1896a4 100644 --- a/include/llvm/DebugInfo/CodeView/StreamInterface.h +++ b/include/llvm/DebugInfo/CodeView/StreamInterface.h @@ -28,8 +28,6 @@ class StreamInterface { public: virtual ~StreamInterface() {} - virtual Error readBytes(uint32_t Offset, - MutableArrayRef Buffer) const = 0; virtual Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const = 0; diff --git a/include/llvm/DebugInfo/CodeView/StreamReader.h b/include/llvm/DebugInfo/CodeView/StreamReader.h index 71691dc2643..adc23ca4086 100644 --- a/include/llvm/DebugInfo/CodeView/StreamReader.h +++ b/include/llvm/DebugInfo/CodeView/StreamReader.h @@ -28,18 +28,17 @@ class StreamReader { public: StreamReader(const StreamInterface &S); - Error readBytes(uint32_t Size, ArrayRef &Buffer); + Error readBytes(ArrayRef &Buffer, uint32_t Size); Error readInteger(uint16_t &Dest); Error readInteger(uint32_t &Dest); Error readZeroString(StringRef &Dest); Error readFixedString(StringRef &Dest, uint32_t Length); Error readStreamRef(StreamRef &Ref); Error readStreamRef(StreamRef &Ref, uint32_t Length); - Error readBytes(MutableArrayRef Buffer); template Error readObject(const T *&Dest) { ArrayRef Buffer; - if (auto EC = readBytes(sizeof(T), Buffer)) + if (auto EC = readBytes(Buffer, sizeof(T))) return EC; Dest = reinterpret_cast(Buffer.data()); return Error::success(); diff --git a/include/llvm/DebugInfo/CodeView/StreamRef.h b/include/llvm/DebugInfo/CodeView/StreamRef.h index 1597f9a5ea0..7fdfb2ad8f7 100644 --- a/include/llvm/DebugInfo/CodeView/StreamRef.h +++ b/include/llvm/DebugInfo/CodeView/StreamRef.h @@ -26,11 +26,6 @@ public: : Stream(Other.Stream), ViewOffset(Other.ViewOffset), Length(Other.Length) {} - Error readBytes(uint32_t Offset, - MutableArrayRef Buffer) const override { - return Stream->readBytes(ViewOffset + Offset, Buffer); - } - Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const override { return Stream->readBytes(ViewOffset + Offset, Size, Buffer); diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/include/llvm/DebugInfo/CodeView/SymbolDumper.h index 97c795225e2..648e40f5581 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDumper.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDumper.h @@ -39,7 +39,7 @@ public: /// Dumps the type records in Data. Returns false if there was a type stream /// parse error, and true otherwise. - bool dump(ArrayRef Data); + bool dump(const CVSymbolArray &Symbols); private: ScopedPrinter &W; diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 9ab559d8e27..0677f5c9cc8 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -12,8 +12,8 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/RecordIterator.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamInterface.h" @@ -1442,15 +1442,9 @@ public: StringRef Name; }; -typedef RecordIterator SymbolIterator; typedef CVRecord CVSymbol; typedef VarStreamArray CVSymbolArray; -inline iterator_range makeSymbolRange(ArrayRef Data, - bool *HadError) { - return make_range(SymbolIterator(Data, HadError), SymbolIterator()); -} - } // namespace codeview } // namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/TypeDumper.h b/include/llvm/DebugInfo/CodeView/TypeDumper.h index c74f5cffb91..670dcd70c13 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDumper.h +++ b/include/llvm/DebugInfo/CodeView/TypeDumper.h @@ -14,7 +14,6 @@ #include "llvm/ADT/StringSet.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" namespace llvm { class ScopedPrinter; @@ -38,7 +37,7 @@ public: /// Dumps the type records in Data. Returns false if there was a type stream /// parse error, and true otherwise. - bool dump(ArrayRef Data); + bool dump(const CVTypeArray &Types); /// Gets the type index for the next type record. unsigned getNextTypeIndex() const { diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index a53570f98f3..c2f1343756f 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -13,8 +13,10 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/ErrorOr.h" #include @@ -1398,6 +1400,9 @@ private: uint64_t VBPtrOffset; uint64_t VTableIndex; }; + +typedef CVRecord CVType; +typedef VarStreamArray CVTypeArray; } } diff --git a/include/llvm/DebugInfo/CodeView/TypeStream.h b/include/llvm/DebugInfo/CodeView/TypeStream.h deleted file mode 100644 index 5dc2df30f47..00000000000 --- a/include/llvm/DebugInfo/CodeView/TypeStream.h +++ /dev/null @@ -1,37 +0,0 @@ -//===- TypeStream.h ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H -#define LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator_range.h" -#include "llvm/DebugInfo/CodeView/RecordIterator.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/Support/Endian.h" -#include -#include - -namespace llvm { - -class APSInt; - -namespace codeview { - -typedef RecordIterator TypeIterator; - -inline iterator_range makeTypeRange(ArrayRef Data, bool *HadError) { - return make_range(TypeIterator(Data, HadError), TypeIterator()); -} - -} // end namespace codeview -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_TYPESTREAM_H diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h index 0dd49270c15..af396c79d07 100644 --- a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -18,8 +18,7 @@ namespace llvm { namespace codeview { /// Merges one type stream into another. Returns true on success. -bool mergeTypeStreams(TypeTableBuilder &DestStream, - ArrayRef SrcStream); +bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h b/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h index 864f8d44dd0..dd69694ee43 100644 --- a/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h @@ -27,14 +27,13 @@ class MappedBlockStream : public codeview::StreamInterface { public: MappedBlockStream(uint32_t StreamIdx, const PDBFile &File); - Error readBytes(uint32_t Offset, - MutableArrayRef Buffer) const override; Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const override; uint32_t getLength() const override { return StreamLength; } private: + Error readBytes(uint32_t Offset, MutableArrayRef Buffer) const; bool tryReadContiguously(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const; diff --git a/include/llvm/DebugInfo/PDB/Raw/ModInfo.h b/include/llvm/DebugInfo/PDB/Raw/ModInfo.h index c9050abe05f..cd7f2cf41a4 100644 --- a/include/llvm/DebugInfo/PDB/Raw/ModInfo.h +++ b/include/llvm/DebugInfo/PDB/Raw/ModInfo.h @@ -25,10 +25,11 @@ private: public: ModInfo(); - ModInfo(codeview::StreamRef Stream); ModInfo(const ModInfo &Info); ~ModInfo(); + static Error initialize(codeview::StreamRef Stream, ModInfo &Info); + bool hasECInfo() const; uint16_t getTypeServerIndex() const; uint16_t getModuleStreamIndex() const; @@ -51,7 +52,6 @@ private: }; struct ModuleInfoEx { - ModuleInfoEx(codeview::StreamRef Stream) : Info(Stream) {} ModuleInfoEx(const ModInfo &Info) : Info(Info) {} ModuleInfoEx(const ModuleInfoEx &Ex) : Info(Ex.Info), SourceFiles(Ex.SourceFiles) {} @@ -64,9 +64,12 @@ struct ModuleInfoEx { namespace codeview { template <> struct VarStreamArrayExtractor { - uint32_t operator()(const StreamInterface &Stream, pdb::ModInfo &Info) const { - Info = pdb::ModInfo(Stream); - return Info.getRecordLength(); + Error operator()(const StreamInterface &Stream, uint32_t &Length, + pdb::ModInfo &Info) const { + if (auto EC = pdb::ModInfo::initialize(Stream, Info)) + return EC; + Length = Info.getRecordLength(); + return Error::success(); } }; } diff --git a/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/include/llvm/DebugInfo/PDB/Raw/ModStream.h index 72869134b48..1460e829740 100644 --- a/include/llvm/DebugInfo/PDB/Raw/ModStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/ModStream.h @@ -11,7 +11,7 @@ #define LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H #include "llvm/ADT/iterator_range.h" -#include "llvm/DebugInfo/CodeView/RecordIterator.h" +#include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/StreamRef.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" @@ -29,7 +29,8 @@ public: Error reload(); - iterator_range symbols() const; + iterator_range + symbols(bool *HadError) const; private: const ModInfo &Mod; diff --git a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h index 10fd130858f..c2138be8478 100644 --- a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h @@ -12,7 +12,6 @@ #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" @@ -37,7 +36,8 @@ public: uint32_t getSymHash() const; uint32_t getAddrMap() const; uint32_t getNumBuckets() const { return NumBuckets; } - iterator_range getSymbols() const; + iterator_range + getSymbols(bool *HadError) const; codeview::FixedStreamArray getHashBuckets() const { return HashBuckets; } @@ -52,8 +52,6 @@ public: } private: - Error readSymbols(); - PDBFile &Pdb; uint32_t StreamNum; diff --git a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h b/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h index bb5f418b1d5..1f8598d4410 100644 --- a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h @@ -10,7 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PDBSYMBOLSTREAM_H -#include "llvm/DebugInfo/CodeView/ByteStream.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" @@ -26,10 +26,11 @@ public: ~SymbolStream(); Error reload(); - iterator_range getSymbols() const; + iterator_range + getSymbols(bool *HadError) const; private: - codeview::ByteStream Stream; + codeview::CVSymbolArray SymbolRecords; MappedBlockStream MappedStream; }; } diff --git a/include/llvm/DebugInfo/PDB/Raw/TpiStream.h b/include/llvm/DebugInfo/PDB/Raw/TpiStream.h index 4fb91103415..55c0e301f6e 100644 --- a/include/llvm/DebugInfo/PDB/Raw/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Raw/TpiStream.h @@ -10,9 +10,9 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H -#include "llvm/DebugInfo/CodeView/ByteStream.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamRef.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" @@ -41,14 +41,14 @@ public: uint16_t getTypeHashStreamIndex() const; uint16_t getTypeHashStreamAuxIndex() const; - iterator_range types(bool *HadError) const; + iterator_range types(bool *HadError) const; private: PDBFile &Pdb; MappedBlockStream Stream; HashFunctionType HashFunction; - codeview::ByteStream RecordsBuffer; + codeview::CVTypeArray TypeRecords; codeview::StreamRef TypeIndexOffsetBuffer; codeview::StreamRef HashValuesBuffer; codeview::StreamRef HashAdjBuffer; diff --git a/lib/DebugInfo/CodeView/ByteStream.cpp b/lib/DebugInfo/CodeView/ByteStream.cpp index 1ea976b6a26..c0ac0b7a8ff 100644 --- a/lib/DebugInfo/CodeView/ByteStream.cpp +++ b/lib/DebugInfo/CodeView/ByteStream.cpp @@ -17,41 +17,13 @@ using namespace llvm::codeview; ByteStream::ByteStream() {} -ByteStream::ByteStream(MutableArrayRef Data) : Data(Data) {} +ByteStream::ByteStream(ArrayRef Data) : Data(Data) {} ByteStream::~ByteStream() {} -void ByteStream::reset() { - Ownership.reset(); - Data = MutableArrayRef(); -} - -void ByteStream::load(uint32_t Length) { - reset(); - if (Length > 0) - Data = MutableArrayRef(new uint8_t[Length], Length); - Ownership.reset(Data.data()); -} - -Error ByteStream::load(StreamReader &Reader, uint32_t Length) { - load(Length); - auto EC = Reader.readBytes(Data); - if (EC) - reset(); - return EC; -} - -Error ByteStream::readBytes(uint32_t Offset, - MutableArrayRef Buffer) const { - if (Data.size() < Buffer.size() + Offset) - return make_error(cv_error_code::insufficient_buffer); - ::memcpy(Buffer.data() + Offset, Data.data(), Buffer.size()); - return Error::success(); -} - Error ByteStream::readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const { - if (Data.size() < Buffer.size() + Offset) + if (Data.size() < Size + Offset) return make_error(cv_error_code::insufficient_buffer); Buffer = Data.slice(Offset, Size); return Error::success(); diff --git a/lib/DebugInfo/CodeView/StreamReader.cpp b/lib/DebugInfo/CodeView/StreamReader.cpp index 64985bfd0e2..94a6183cd8a 100644 --- a/lib/DebugInfo/CodeView/StreamReader.cpp +++ b/lib/DebugInfo/CodeView/StreamReader.cpp @@ -17,20 +17,13 @@ using namespace llvm::codeview; StreamReader::StreamReader(const StreamInterface &S) : Stream(S), Offset(0) {} -Error StreamReader::readBytes(uint32_t Size, ArrayRef &Buffer) { +Error StreamReader::readBytes(ArrayRef &Buffer, uint32_t Size) { if (auto EC = Stream.readBytes(Offset, Size, Buffer)) return EC; Offset += Size; return Error::success(); } -Error StreamReader::readBytes(MutableArrayRef Buffer) { - if (auto EC = Stream.readBytes(Offset, Buffer)) - return EC; - Offset += Buffer.size(); - return Error::success(); -} - Error StreamReader::readInteger(uint16_t &Dest) { const support::ulittle16_t *P; if (auto EC = readObject(P)) @@ -63,7 +56,7 @@ Error StreamReader::readZeroString(StringRef &Dest) { setOffset(OriginalOffset); ArrayRef Data; - if (auto EC = readBytes(Length, Data)) + if (auto EC = readBytes(Data, Length)) return EC; Dest = StringRef(reinterpret_cast(Data.begin()), Data.size()); @@ -74,7 +67,7 @@ Error StreamReader::readZeroString(StringRef &Dest) { Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) { ArrayRef Bytes; - if (auto EC = readBytes(Length, Bytes)) + if (auto EC = readBytes(Bytes, Length)) return EC; Dest = StringRef(reinterpret_cast(Bytes.begin()), Bytes.size()); return Error::success(); diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp index 7d405ec2453..e2dc9d5b76d 100644 --- a/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -872,8 +872,8 @@ bool CVSymbolDumper::dump(const CVRecord &Record) { return !Dumper.hadError(); } -bool CVSymbolDumper::dump(ArrayRef Data) { +bool CVSymbolDumper::dump(const CVSymbolArray &Symbols) { CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes); - Dumper.visitSymbolStream(Data); + Dumper.visitSymbolStream(Symbols); return !Dumper.hadError(); } diff --git a/lib/DebugInfo/CodeView/TypeDumper.cpp b/lib/DebugInfo/CodeView/TypeDumper.cpp index 1db1e54f430..da3919a0773 100644 --- a/lib/DebugInfo/CodeView/TypeDumper.cpp +++ b/lib/DebugInfo/CodeView/TypeDumper.cpp @@ -12,7 +12,6 @@ #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/Support/ScopedPrinter.h" using namespace llvm; @@ -683,10 +682,10 @@ bool CVTypeDumper::dump(const CVRecord &Record) { return !Dumper.hadError(); } -bool CVTypeDumper::dump(ArrayRef Data) { +bool CVTypeDumper::dump(const CVTypeArray &Types) { assert(W && "printer should not be null"); CVTypeDumperImpl Dumper(*this, *W, PrintRecordBytes); - Dumper.visitTypeStream(Data); + Dumper.visitTypeStream(Types); return !Dumper.hadError(); } diff --git a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index 88211d0af95..d16e481e326 100644 --- a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -12,9 +12,9 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h" +#include "llvm/DebugInfo/CodeView/StreamRef.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/Support/ScopedPrinter.h" using namespace llvm; @@ -71,7 +71,7 @@ public: void visitFieldList(TypeLeafKind Leaf, ArrayRef FieldData); - bool mergeStream(ArrayRef SrcStream); + bool mergeStream(const CVTypeArray &Types); private: bool hadError() { return FoundBadTypeIndex || CVTypeVisitor::hadError(); } @@ -131,14 +131,14 @@ void TypeStreamMerger::visitUnknownMember(TypeLeafKind LF) { parseError(); } -bool TypeStreamMerger::mergeStream(ArrayRef SrcStream) { +bool TypeStreamMerger::mergeStream(const CVTypeArray &Types) { assert(IndexMap.empty()); - visitTypeStream(SrcStream); + visitTypeStream(Types); IndexMap.clear(); return !hadError(); } bool llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, - ArrayRef SrcStream) { - return TypeStreamMerger(DestStream).mergeStream(SrcStream); + const CVTypeArray &Types) { + return TypeStreamMerger(DestStream).mergeStream(Types); } diff --git a/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/lib/DebugInfo/PDB/Raw/ModInfo.cpp index 67dc81da63a..bae135f77bc 100644 --- a/lib/DebugInfo/PDB/Raw/ModInfo.cpp +++ b/lib/DebugInfo/PDB/Raw/ModInfo.cpp @@ -69,28 +69,25 @@ struct ModInfo::FileLayout { ModInfo::ModInfo() : Layout(nullptr) {} -ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) { - codeview::StreamReader Reader(Stream); - if (auto EC = Reader.readObject(Layout)) { - consumeError(std::move(EC)); - return; - } - if (auto EC = Reader.readZeroString(ModuleName)) { - consumeError(std::move(EC)); - return; - } - if (auto EC = Reader.readZeroString(ObjFileName)) { - consumeError(std::move(EC)); - return; - } -} - ModInfo::ModInfo(const ModInfo &Info) : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName), Layout(Info.Layout) {} ModInfo::~ModInfo() {} +Error ModInfo::initialize(codeview::StreamRef Stream, ModInfo &Info) { + codeview::StreamReader Reader(Stream); + if (auto EC = Reader.readObject(Info.Layout)) + return EC; + + if (auto EC = Reader.readZeroString(Info.ModuleName)) + return EC; + + if (auto EC = Reader.readZeroString(Info.ObjFileName)) + return EC; + return Error::success(); +} + bool ModInfo::hasECInfo() const { return (Layout->Flags & HasECFlagMask) != 0; } uint16_t ModInfo::getTypeServerIndex() const { diff --git a/lib/DebugInfo/PDB/Raw/ModStream.cpp b/lib/DebugInfo/PDB/Raw/ModStream.cpp index 404208a6487..88c6b7c2444 100644 --- a/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -9,7 +9,6 @@ #include "llvm/DebugInfo/PDB/Raw/ModStream.h" -#include "llvm/DebugInfo/CodeView/RecordIterator.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" @@ -58,6 +57,7 @@ Error ModStream::reload() { return Error::success(); } -iterator_range ModStream::symbols() const { +iterator_range +ModStream::symbols(bool *HadError) const { return llvm::make_range(SymbolsSubstream.begin(), SymbolsSubstream.end()); } diff --git a/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/lib/DebugInfo/PDB/Raw/PublicsStream.cpp index f51a8ef17a2..d3a7ffd7f93 100644 --- a/lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ b/lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -113,7 +113,7 @@ Error PublicsStream::reload() { // A bitmap of a fixed length follows. size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32); uint32_t NumBitmapEntries = BitmapSizeInBits / 8; - if (auto EC = Reader.readBytes(NumBitmapEntries, Bitmap)) + if (auto EC = Reader.readBytes(Bitmap, NumBitmapEntries)) return joinErrors(std::move(EC), make_error(raw_error_code::corrupt_file, "Could not read a bitmap.")); @@ -156,13 +156,14 @@ Error PublicsStream::reload() { return Error::success(); } -iterator_range PublicsStream::getSymbols() const { - using codeview::SymbolIterator; +iterator_range +PublicsStream::getSymbols(bool *HadError) const { auto SymbolS = Pdb.getPDBSymbolStream(); if (SymbolS.takeError()) { - return llvm::make_range(SymbolIterator(), SymbolIterator()); + codeview::CVSymbolArray::Iterator Iter; + return llvm::make_range(Iter, Iter); } SymbolStream &SS = SymbolS.get(); - return SS.getSymbols(); + return SS.getSymbols(HadError); } diff --git a/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/lib/DebugInfo/PDB/Raw/SymbolStream.cpp index ba4ea577d81..021e2299dbd 100644 --- a/lib/DebugInfo/PDB/Raw/SymbolStream.cpp +++ b/lib/DebugInfo/PDB/Raw/SymbolStream.cpp @@ -30,20 +30,13 @@ SymbolStream::~SymbolStream() {} Error SymbolStream::reload() { codeview::StreamReader Reader(MappedStream); - if (Stream.load(Reader, MappedStream.getLength())) - return make_error(raw_error_code::corrupt_file, - "Could not load symbol stream."); + if (auto EC = Reader.readArray(SymbolRecords, MappedStream.getLength())) + return EC; return Error::success(); } -iterator_range SymbolStream::getSymbols() const { - using codeview::SymbolIterator; - ArrayRef Data; - if (auto Error = Stream.readBytes(0, Stream.getLength(), Data)) { - consumeError(std::move(Error)); - return iterator_range(SymbolIterator(), SymbolIterator()); - } - - return codeview::makeSymbolRange(Data, nullptr); +iterator_range +SymbolStream::getSymbols(bool *HadError) const { + return llvm::make_range(SymbolRecords.begin(HadError), SymbolRecords.end()); } diff --git a/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/lib/DebugInfo/PDB/Raw/TpiStream.cpp index 3345ab27571..6478ad1f77f 100644 --- a/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ b/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -92,7 +92,7 @@ Error TpiStream::reload() { HashFunction = HashBufferV8; // The actual type records themselves come from this stream - if (auto EC = RecordsBuffer.load(Reader, Header->TypeRecordBytes)) + if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes)) return EC; // Hash indices, hash values, etc come from the hash stream. @@ -136,6 +136,7 @@ uint16_t TpiStream::getTypeHashStreamAuxIndex() const { return Header->HashAuxStreamIndex; } -iterator_range TpiStream::types(bool *HadError) const { - return codeview::makeTypeRange(RecordsBuffer.data(), /*HadError=*/HadError); +iterator_range +TpiStream::types(bool *HadError) const { + return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end()); } diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 50e212356a8..b81ba218ab1 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -354,7 +354,7 @@ static Error dumpStreamData(ScopedPrinter &P, PDBFile &File) { ArrayRef Data; uint32_t BytesToReadInBlock = std::min( R.bytesRemaining(), static_cast(File.getBlockSize())); - if (auto EC = R.readBytes(BytesToReadInBlock, Data)) + if (auto EC = R.readBytes(Data, BytesToReadInBlock)) return EC; P.printBinaryBlock( "Data", @@ -485,7 +485,8 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, return EC; codeview::CVSymbolDumper SD(P, TD, nullptr, false); - for (auto &S : ModS.symbols()) { + bool HadError = false; + for (auto &S : ModS.symbols(&HadError)) { DictScope DD(P, ""); if (opts::DumpModuleSyms) @@ -493,6 +494,9 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File, if (opts::DumpSymRecordBytes) P.printBinaryBlock("Bytes", S.Data); } + if (HadError) + return make_error(raw_error_code::corrupt_file, + "DBI stream contained corrupt record"); } } } @@ -509,7 +513,7 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File, StringRef VerLabel; if (StreamIdx == StreamTPI) { DumpRecordBytes = opts::DumpTpiRecordBytes; - DumpRecords = opts::DumpTpiRecordBytes; + DumpRecords = opts::DumpTpiRecords; Label = "Type Info Stream (TPI)"; VerLabel = "TPI Version"; } else if (StreamIdx == StreamIPI) { @@ -595,13 +599,19 @@ static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File, printSectionOffset); ListScope L(P, "Symbols"); codeview::CVSymbolDumper SD(P, TD, nullptr, false); - for (auto S : Publics.getSymbols()) { + bool HadError = false; + for (auto S : Publics.getSymbols(&HadError)) { DictScope DD(P, ""); SD.dump(S); if (opts::DumpSymRecordBytes) P.printBinaryBlock("Bytes", S.Data); } + if (HadError) + return make_error( + raw_error_code::corrupt_file, + "Public symbol stream contained corrupt record"); + return Error::success(); } diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 546387bd862..c890c9a68e6 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/DebugInfo/CodeView/ByteStream.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h" @@ -32,7 +33,6 @@ #include "llvm/DebugInfo/CodeView/TypeDumper.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeStream.h" #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" @@ -898,8 +898,16 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, SectionContents); CVSymbolDumper CVSD(W, CVTD, std::move(CODD), opts::CodeViewSubsectionBytes); + ByteStream Stream(BinaryData); + CVSymbolArray Symbols; + StreamReader Reader(Stream); + if (auto EC = Reader.readArray(Symbols, Reader.getLength())) { + consumeError(std::move(EC)); + W.flush(); + error(object_error::parse_failed); + } - if (!CVSD.dump(BinaryData)) { + if (!CVSD.dump(Symbols)) { W.flush(); error(object_error::parse_failed); } @@ -996,7 +1004,16 @@ void COFFDumper::mergeCodeViewTypes(MemoryTypeTableBuilder &CVTypes) { Data = Data.drop_front(4); ArrayRef Bytes(reinterpret_cast(Data.data()), Data.size()); - if (!mergeTypeStreams(CVTypes, Bytes)) + ByteStream Stream(Bytes); + CVTypeArray Types; + StreamReader Reader(Stream); + if (auto EC = Reader.readArray(Types, Reader.getLength())) { + consumeError(std::move(EC)); + W.flush(); + error(object_error::parse_failed); + } + + if (!mergeTypeStreams(CVTypes, Types)) return error(object_error::parse_failed); } } @@ -1020,7 +1037,16 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName, ArrayRef BinaryData(reinterpret_cast(Data.data()), Data.size()); - if (!CVTD.dump(BinaryData)) { + ByteStream Stream(BinaryData); + CVTypeArray Types; + StreamReader Reader(Stream); + if (auto EC = Reader.readArray(Types, Reader.getLength())) { + consumeError(std::move(EC)); + W.flush(); + error(object_error::parse_failed); + } + + if (!CVTD.dump(Types)) { W.flush(); error(object_error::parse_failed); } @@ -1472,7 +1498,16 @@ void llvm::dumpCodeViewMergedTypes( CVTypeDumper CVTD(Writer, opts::CodeViewSubsectionBytes); ArrayRef BinaryData(reinterpret_cast(Buf.data()), Buf.size()); - if (!CVTD.dump(BinaryData)) { + ByteStream Stream(BinaryData); + CVTypeArray Types; + StreamReader Reader(Stream); + if (auto EC = Reader.readArray(Types, Reader.getLength())) { + consumeError(std::move(EC)); + Writer.flush(); + error(object_error::parse_failed); + } + + if (!CVTD.dump(Types)) { Writer.flush(); error(object_error::parse_failed); } -- 2.11.0