[llvm] r271025 - [pdb] Allow zero-copy read support for symbol streams.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri May 27 11:21:12 PDT 2016


Author: zturner
Date: Fri May 27 13:20:20 2016
New Revision: 271025

URL: http://llvm.org/viewvc/llvm-project?rev=271025&view=rev
Log:
[pdb] Allow zero-copy read support for symbol streams.

This reduces the amount of memory used by llvm-pdbdump by roughly
1/3 of the size of the PDB file.

Differential Revision: http://reviews.llvm.org/D20724
Reviewed By: ruiu

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h
    llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h Fri May 27 13:20:20 2016
@@ -46,7 +46,7 @@ public:
 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "CVSymbolTypes.def"
 
-  void visitSymbolRecord(const SymbolIterator::Record &Record) {
+  void visitSymbolRecord(const CVRecord<SymbolKind> &Record) {
     ArrayRef<uint8_t> Data = Record.Data;
     auto *DerivedThis = static_cast<Derived *>(this);
     DerivedThis->visitSymbolBegin(Record.Type, Data);

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Fri May 27 13:20:20 2016
@@ -51,7 +51,7 @@ public:
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "TypeRecords.def"
 
-  void visitTypeRecord(const TypeIterator::Record &Record) {
+  void visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
     ArrayRef<uint8_t> LeafData = Record.Data;
     ArrayRef<uint8_t> RecordData = LeafData;
     auto *DerivedThis = static_cast<Derived *>(this);

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/RecordIterator.h Fri May 27 13:20:20 2016
@@ -13,19 +13,41 @@
 #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 <typename Kind> struct CVRecord {
+  uint32_t Length;
+  Kind Type;
+  ArrayRef<uint8_t> Data;
+};
+
+template <typename Kind> struct VarStreamArrayExtractor<CVRecord<Kind>> {
+  uint32_t operator()(const StreamInterface &Stream,
+                      CVRecord<Kind> &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<Kind>(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 <typename Kind> class RecordIterator {
 public:
-  struct Record {
-    std::size_t Length;
-    Kind Type;
-    ArrayRef<uint8_t> Data;
-  };
 
   explicit RecordIterator(const ArrayRef<uint8_t> &RecordBytes, bool *HadError)
       : HadError(HadError), Data(RecordBytes), AtEnd(false) {
@@ -46,12 +68,12 @@ public:
     return !(lhs == rhs);
   }
 
-  const Record &operator*() const {
+  const CVRecord<Kind> &operator*() const {
     assert(!AtEnd);
     return Current;
   }
 
-  const Record *operator->() const {
+  const CVRecord<Kind> *operator->() const {
     assert(!AtEnd);
     return &Current;
   }
@@ -106,7 +128,7 @@ private:
 
   bool *HadError;
   ArrayRef<uint8_t> Data;
-  Record Current;
+  CVRecord<Kind> Current;
   bool AtEnd;
 };
 

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamArray.h Fri May 27 13:20:20 2016
@@ -18,6 +18,19 @@
 namespace llvm {
 namespace codeview {
 
+/// VarStreamArrayExtractor is intended to be specialized to provide customized
+/// extraction logic.  It should return the total number of bytes of the next
+/// record (so that the array knows how much data to skip to get to the next
+/// record, and it should initialize the second parameter with the desired
+/// value type.
+template <typename T> struct VarStreamArrayExtractor {
+  uint32_t operator()(const StreamInterface &Stream, T &t) const {
+    static_assert(false, "You must either provide a specialization of "
+                         "VarStreamArrayExtractor or a custom extractor");
+    return 0;
+  }
+};
+
 /// VarStreamArray represents an array of variable length records backed by a
 /// stream.  This could be a contiguous sequence of bytes in memory, it could
 /// be a file on disk, or it could be a PDB stream where bytes are stored as
@@ -27,33 +40,39 @@ namespace codeview {
 /// re-ordering of stream data to be contiguous before iterating over it.  By
 /// abstracting this out, we need not duplicate this memory, and we can
 /// iterate over arrays in arbitrarily formatted streams.
-class VarStreamArrayIterator;
+template <typename ValueType, typename Extractor> class VarStreamArrayIterator;
 
+template <typename ValueType,
+          typename Extractor = VarStreamArrayExtractor<ValueType>>
 class VarStreamArray {
-  friend class VarStreamArrayIterator;
-  typedef std::function<uint32_t(const StreamInterface &)> LengthFuncType;
+  friend class VarStreamArrayIterator<ValueType, Extractor>;
 
 public:
-  template <typename LengthFunc>
-  VarStreamArray(StreamRef Stream, const LengthFunc &Len)
-      : Stream(Stream), Len(Len) {}
+  typedef VarStreamArrayIterator<ValueType, Extractor> Iterator;
+
+  VarStreamArray() {}
+
+  VarStreamArray(StreamRef Stream) : Stream(Stream) {}
 
-  VarStreamArrayIterator begin() const;
-  VarStreamArrayIterator end() const;
+  Iterator begin() const { return Iterator(*this); }
+
+  Iterator end() const { return Iterator(); }
 
 private:
   StreamRef Stream;
-  LengthFuncType Len; // Function used to calculate legth of a record
 };
 
-class VarStreamArrayIterator {
+template <typename ValueType, typename Extractor> class VarStreamArrayIterator {
+  typedef VarStreamArrayIterator<ValueType, Extractor> IterType;
+  typedef VarStreamArray<ValueType, Extractor> ArrayType;
+
 public:
-  VarStreamArrayIterator(const VarStreamArray &Array)
+  VarStreamArrayIterator(const ArrayType &Array)
       : Array(&Array), IterRef(Array.Stream) {
-    ThisLen = Array.Len(IterRef);
+    ThisLen = Extract(IterRef, ThisValue);
   }
   VarStreamArrayIterator() : Array(nullptr), IterRef() {}
-  bool operator==(const VarStreamArrayIterator &R) const {
+  bool operator==(const IterType &R) const {
     if (Array && R.Array) {
       // Both have a valid array, make sure they're same.
       assert(Array == R.Array);
@@ -68,45 +87,37 @@ public:
     return false;
   }
 
-  bool operator!=(const VarStreamArrayIterator &R) { return !(*this == R); }
+  bool operator!=(const IterType &R) { return !(*this == R); }
 
-  StreamRef operator*() const {
-    ArrayRef<uint8_t> Result;
-    return IterRef.keep_front(ThisLen);
-  }
+  const ValueType &operator*() const { return ThisValue; }
 
-  VarStreamArrayIterator &operator++() {
-    if (!Array || IterRef.getLength() == 0)
+  IterType &operator++() {
+    if (!Array || IterRef.getLength() == 0 || ThisLen == 0)
       return *this;
     IterRef = IterRef.drop_front(ThisLen);
     if (IterRef.getLength() == 0) {
       Array = nullptr;
       ThisLen = 0;
     } else {
-      ThisLen = Array->Len(IterRef);
+      ThisLen = Extract(IterRef, ThisValue);
     }
     return *this;
   }
 
-  VarStreamArrayIterator operator++(int) {
-    VarStreamArrayIterator Original = *this;
+  IterType operator++(int) {
+    IterType Original = *this;
     ++*this;
     return Original;
   }
 
 private:
-  const VarStreamArray *Array;
+  const ArrayType *Array;
   uint32_t ThisLen;
+  ValueType ThisValue;
   StreamRef IterRef;
+  Extractor Extract;
 };
 
-inline VarStreamArrayIterator VarStreamArray::begin() const {
-  return VarStreamArrayIterator(*this);
-}
-inline VarStreamArrayIterator VarStreamArray::end() const {
-  return VarStreamArrayIterator();
-}
-
 template <typename T> class FixedStreamArrayIterator;
 
 template <typename T> class FixedStreamArray {

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StreamReader.h Fri May 27 13:20:20 2016
@@ -46,6 +46,15 @@ public:
   }
 
   template <typename T>
+  Error readArray(VarStreamArray<T> &Array, uint32_t Size) {
+    StreamRef S;
+    if (auto EC = readStreamRef(S, Size))
+      return EC;
+    Array = VarStreamArray<T>(S);
+    return Error::success();
+  }
+
+  template <typename T>
   Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
     if (NumItems == 0) {
       Array = FixedStreamArray<T>();

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h Fri May 27 13:20:20 2016
@@ -35,7 +35,7 @@ public:
   /// and true otherwise.  This should be called in order, since the dumper
   /// maintains state about previous records which are necessary for cross
   /// type references.
-  bool dump(const SymbolIterator::Record &Record);
+  bool dump(const CVRecord<SymbolKind> &Record);
 
   /// Dumps the type records in Data. Returns false if there was a type stream
   /// parse error, and true otherwise.

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h Fri May 27 13:20:20 2016
@@ -15,6 +15,8 @@
 #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"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
@@ -1441,6 +1443,8 @@ public:
 };
 
 typedef RecordIterator<SymbolKind> SymbolIterator;
+typedef CVRecord<SymbolKind> CVSymbol;
+typedef VarStreamArray<CVSymbol> CVSymbolArray;
 
 inline iterator_range<SymbolIterator> makeSymbolRange(ArrayRef<uint8_t> Data,
                                                       bool *HadError) {

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h Fri May 27 13:20:20 2016
@@ -34,7 +34,7 @@ public:
   /// and true otherwise.  This should be called in order, since the dumper
   /// maintains state about previous records which are necessary for cross
   /// type references.
-  bool dump(const TypeIterator::Record &Record);
+  bool dump(const CVRecord<TypeLeafKind> &Record);
 
   /// Dumps the type records in Data. Returns false if there was a type stream
   /// parse error, and true otherwise.

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Fri May 27 13:20:20 2016
@@ -10,7 +10,6 @@
 #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
 #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
 
-#include "llvm/DebugInfo/CodeView/ByteStream.h"
 #include "llvm/DebugInfo/CodeView/StreamArray.h"
 #include "llvm/DebugInfo/CodeView/StreamRef.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModInfo.h Fri May 27 13:20:20 2016
@@ -11,6 +11,7 @@
 #define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
 #include "llvm/DebugInfo/CodeView/StreamRef.h"
 #include <cstdint>
 #include <vector>
@@ -23,6 +24,7 @@ private:
   struct FileLayout;
 
 public:
+  ModInfo();
   ModInfo(codeview::StreamRef Stream);
   ModInfo(const ModInfo &Info);
   ~ModInfo();
@@ -50,6 +52,7 @@ 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) {}
 
@@ -57,11 +60,17 @@ struct ModuleInfoEx {
   std::vector<StringRef> SourceFiles;
 };
 
-inline uint32_t ModInfoRecordLength(const codeview::StreamInterface &Stream) {
-  return ModInfo(Stream).getRecordLength();
+} // end namespace pdb
+
+namespace codeview {
+template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
+  uint32_t operator()(const StreamInterface &Stream, pdb::ModInfo &Info) const {
+    Info = pdb::ModInfo(Stream);
+    return Info.getRecordLength();
+  }
+};
 }
 
-} // end namespace pdb
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ModStream.h Fri May 27 13:20:20 2016
@@ -11,7 +11,7 @@
 #define LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H
 
 #include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/ByteStream.h"
+#include "llvm/DebugInfo/CodeView/RecordIterator.h"
 #include "llvm/DebugInfo/CodeView/StreamRef.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
@@ -29,14 +29,14 @@ public:
 
   Error reload();
 
-  iterator_range<codeview::SymbolIterator> symbols() const;
+  iterator_range<codeview::CVSymbolArray::Iterator> symbols() const;
 
 private:
   const ModInfo &Mod;
 
   MappedBlockStream Stream;
 
-  codeview::ByteStream SymbolsSubstream;
+  codeview::CVSymbolArray SymbolsSubstream;
   codeview::StreamRef LinesSubstream;
   codeview::StreamRef C13LinesSubstream;
   codeview::StreamRef GlobalRefsSubstream;

Modified: llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp Fri May 27 13:20:20 2016
@@ -866,7 +866,7 @@ void CVSymbolDumperImpl::visitUnknownSym
   W.printNumber("Length", uint32_t(Data.size()));
 }
 
-bool CVSymbolDumper::dump(const SymbolIterator::Record &Record) {
+bool CVSymbolDumper::dump(const CVRecord<SymbolKind> &Record) {
   CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
   Dumper.visitSymbolRecord(Record);
   return !Dumper.hadError();

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Fri May 27 13:20:20 2016
@@ -676,7 +676,7 @@ void CVTypeDumper::printTypeIndex(String
     W->printHex(FieldName, TI.getIndex());
 }
 
-bool CVTypeDumper::dump(const TypeIterator::Record &Record) {
+bool CVTypeDumper::dump(const CVRecord<TypeLeafKind> &Record) {
   assert(W && "printer should not be null");
   CVTypeDumperImpl Dumper(*this, *W, PrintRecordBytes);
   Dumper.visitTypeRecord(Record);

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Fri May 27 13:20:20 2016
@@ -136,14 +136,12 @@ Error DbiStream::reload() {
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "DBI type server substream not aligned.");
 
-  if (auto EC =
-          Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))
-    return EC;
-
   // Since each ModInfo in the stream is a variable length, we have to iterate
   // them to know how many there actually are.
-  codeview::VarStreamArray ModInfoArray(ModInfoSubstream, ModInfoRecordLength);
-  for (auto Info : ModInfoArray) {
+  codeview::VarStreamArray<ModInfo> ModInfoArray;
+  if (auto EC = Reader.readArray(ModInfoArray, Header->ModiSubstreamSize))
+    return EC;
+  for (auto &Info : ModInfoArray) {
     ModuleInfos.emplace_back(Info);
   }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModInfo.cpp Fri May 27 13:20:20 2016
@@ -67,6 +67,8 @@ struct ModInfo::FileLayout {
                              // Null terminated Obj File Name
 };
 
+ModInfo::ModInfo() : Layout(nullptr) {}
+
 ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) {
   codeview::StreamReader Reader(Stream);
   if (auto EC = Reader.readObject(Layout)) {

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp?rev=271025&r1=271024&r2=271025&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/ModStream.cpp Fri May 27 13:20:20 2016
@@ -9,6 +9,7 @@
 
 #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"
@@ -32,8 +33,14 @@ Error ModStream::reload() {
     return llvm::make_error<RawError>(raw_error_code::corrupt_file,
                                       "Module has both C11 and C13 line info");
 
-  if (auto EC = SymbolsSubstream.load(Reader, SymbolSize))
+  codeview::StreamRef S;
+
+  uint32_t SymbolSubstreamSig = 0;
+  if (auto EC = Reader.readInteger(SymbolSubstreamSig))
+    return EC;
+  if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
     return EC;
+
   if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))
     return EC;
   if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
@@ -51,6 +58,6 @@ Error ModStream::reload() {
   return Error::success();
 }
 
-iterator_range<codeview::SymbolIterator> ModStream::symbols() const {
-  return codeview::makeSymbolRange(SymbolsSubstream.data().slice(4), nullptr);
+iterator_range<codeview::CVSymbolArray::Iterator> ModStream::symbols() const {
+  return llvm::make_range(SymbolsSubstream.begin(), SymbolsSubstream.end());
 }




More information about the llvm-commits mailing list