[llvm] r306167 - [llvm-pdbutil] Dump raw bytes of type and id records.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 23 14:50:55 PDT 2017


Author: zturner
Date: Fri Jun 23 16:50:54 2017
New Revision: 306167

URL: http://llvm.org/viewvc/llvm-project?rev=306167&view=rev
Log:
[llvm-pdbutil] Dump raw bytes of type and id records.

Added:
    llvm/trunk/test/DebugInfo/PDB/tpi-bytes.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h
    llvm/trunk/include/llvm/Support/BinaryStreamRef.h
    llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
    llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h Fri Jun 23 16:50:54 2017
@@ -61,6 +61,8 @@ public:
   void reset(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
   void reset(StringRef Data, uint32_t RecordCountHint);
 
+  uint32_t getOffsetOfType(TypeIndex Index);
+
   CVType getType(TypeIndex Index) override;
   StringRef getTypeName(TypeIndex Index) override;
   bool contains(TypeIndex Index) override;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h Fri Jun 23 16:50:54 2017
@@ -16,6 +16,7 @@
 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include "llvm/Support/Error.h"
@@ -57,6 +58,8 @@ public:
 
   codeview::LazyRandomTypeCollection &typeCollection() { return *Types; }
 
+  BinarySubstreamRef getTypeRecordsSubstream() const;
+
   Error commit();
 
 private:
@@ -65,6 +68,8 @@ private:
 
   std::unique_ptr<codeview::LazyRandomTypeCollection> Types;
 
+  BinarySubstreamRef TypeRecordsSubstream;
+
   codeview::CVTypeArray TypeRecords;
 
   std::unique_ptr<BinaryStream> HashStream;

Modified: llvm/trunk/include/llvm/Support/BinaryStreamRef.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/BinaryStreamRef.h?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/BinaryStreamRef.h (original)
+++ llvm/trunk/include/llvm/Support/BinaryStreamRef.h Fri Jun 23 16:50:54 2017
@@ -170,6 +170,10 @@ struct BinarySubstreamRef {
   uint32_t Offset;            // Offset in the parent stream
   BinaryStreamRef StreamData; // Stream Data
 
+  BinarySubstreamRef slice(uint32_t Off, uint32_t Size) const {
+    BinaryStreamRef SubSub = StreamData.slice(Off, Size);
+    return {Off + Offset, SubSub};
+  }
   uint32_t size() const { return StreamData.getLength(); }
   bool empty() const { return size() == 0; }
 };

Modified: llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp Fri Jun 23 16:50:54 2017
@@ -67,6 +67,13 @@ void LazyRandomTypeCollection::reset(Arr
   reset(toStringRef(Data), RecordCountHint);
 }
 
+uint32_t LazyRandomTypeCollection::getOffsetOfType(TypeIndex Index) {
+  error(ensureTypeExists(Index));
+  assert(contains(Index));
+
+  return Records[Index.toArrayIndex()].Offset;
+}
+
 CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
   error(ensureTypeExists(Index));
   assert(contains(Index));

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp Fri Jun 23 16:50:54 2017
@@ -66,7 +66,13 @@ Error TpiStream::reload() {
                                 "TPI Stream Invalid number of hash buckets.");
 
   // The actual type records themselves come from this stream
-  if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
+  if (auto EC =
+          Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
+    return EC;
+
+  BinaryStreamReader RecordReader(TypeRecordsSubstream.StreamData);
+  if (auto EC =
+          RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
     return EC;
 
   // Hash indices, hash values, etc come from the hash stream.
@@ -135,6 +141,10 @@ uint16_t TpiStream::getTypeHashStreamAux
 uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
 uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
 
+BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
+  return TypeRecordsSubstream;
+}
+
 FixedStreamArray<support::ulittle32_t> TpiStream::getHashValues() const {
   return HashValues;
 }

Added: llvm/trunk/test/DebugInfo/PDB/tpi-bytes.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/tpi-bytes.test?rev=306167&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/tpi-bytes.test (added)
+++ llvm/trunk/test/DebugInfo/PDB/tpi-bytes.test Fri Jun 23 16:50:54 2017
@@ -0,0 +1,27 @@
+; RUN: llvm-pdbutil bytes -type=0x1002 %p/Inputs/empty.pdb | FileCheck --check-prefix=TYPE %s
+; RUN: llvm-pdbutil bytes -id=0x1007 %p/Inputs/empty.pdb | FileCheck --check-prefix=ID %s
+; RUN: llvm-pdbutil bytes -type=0x2000 %p/Inputs/empty.pdb | FileCheck --check-prefix=INVALID-TYPE %s
+; RUN: llvm-pdbutil bytes -id=0x2000 %p/Inputs/empty.pdb | FileCheck --check-prefix=INVALID-ID %s
+
+TYPE:                           Type (TPI) Records
+TYPE-NEXT: ============================================================
+TYPE-NEXT:   Type 0x1002 (
+TYPE-NEXT:     12050: 4A000312 02150300 01006170 6172746D 656E7400 02150300 02007369 6E676C65  |J.........apartment.......single|
+TYPE-NEXT:     12070: 00F3F2F1 02150300 03006672 656500F1 02150300 04006E65 75747261 6C00F2F1  |..........free........neutral...|
+TYPE-NEXT:     12090: 02150300 0500626F 746800F1                                               |......both..|
+TYPE-NEXT:   )
+
+ID:                          Index (IPI) Records
+ID-NEXT: ============================================================
+ID-NEXT:   Type 0x1007 (
+ID-NEXT:     140C4: 2E000516 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E  |........d:\src\llvm\test\DebugIn|
+ID-NEXT:     140E4: 666F5C50 44425C49 6E707574 7300F2F1                                      |fo\PDB\Inputs...|
+ID-NEXT:   )
+
+INVALID-TYPE:                           Type (TPI) Records
+INVALID-TYPE-NEXT: ============================================================
+INVALID-TYPE-NEXT: Error: TypeIndex 0x2000 does not exist
+
+INVALID-ID:                           Index (IPI) Records
+INVALID-ID-NEXT: ============================================================
+INVALID-ID-NEXT: Error: TypeIndex 0x2000 does not exist

Modified: llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp Fri Jun 23 16:50:54 2017
@@ -12,16 +12,20 @@
 #include "StreamUtil.h"
 #include "llvm-pdbutil.h"
 
+#include "llvm/DebugInfo/CodeView/Formatters.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/Support/BinaryStreamReader.h"
 #include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 
 using namespace llvm;
+using namespace llvm::codeview;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
@@ -154,6 +158,16 @@ Error BytesOutputStyle::dump() {
     P.NewLine();
   }
 
+  if (!opts::bytes::TypeIndex.empty()) {
+    dumpTypeIndex(StreamTPI, opts::bytes::TypeIndex);
+    P.NewLine();
+  }
+
+  if (!opts::bytes::IdIndex.empty()) {
+    dumpTypeIndex(StreamIPI, opts::bytes::IdIndex);
+    P.NewLine();
+  }
+
   return Error::success();
 }
 
@@ -253,6 +267,36 @@ void BytesOutputStyle::dumpECData() {
   P.formatMsfStreamData("Edit and Continue Data", File, Layout, NS);
 }
 
+void BytesOutputStyle::dumpTypeIndex(uint32_t StreamIdx,
+                                     ArrayRef<uint32_t> Indices) {
+  assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
+  assert(!Indices.empty());
+
+  bool IsTpi = (StreamIdx == StreamTPI);
+
+  StringRef Label = IsTpi ? "Type (TPI) Records" : "Index (IPI) Records";
+  printHeader(P, Label);
+  auto &Stream = Err(IsTpi ? File.getPDBTpiStream() : File.getPDBIpiStream());
+
+  AutoIndent Indent(P);
+
+  auto Substream = Stream.getTypeRecordsSubstream();
+  auto &Types = Err(initializeTypes(StreamIdx));
+  auto Layout = File.getStreamLayout(StreamIdx);
+  for (const auto &Id : Indices) {
+    TypeIndex TI(Id);
+    if (TI.toArrayIndex() >= Types.capacity()) {
+      P.formatLine("Error: TypeIndex {0} does not exist", TI);
+      continue;
+    }
+
+    auto Type = Types.getType(TI);
+    uint32_t Offset = Types.getOffsetOfType(TI);
+    auto OneType = Substream.slice(Offset, Type.length());
+    P.formatMsfStreamData(formatv("Type {0}", TI).str(), File, Layout, OneType);
+  }
+}
+
 void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) {
   printHeader(P, "MSF Bytes");
 
@@ -268,6 +312,26 @@ void BytesOutputStyle::dumpByteRanges(ui
   P.formatBinary("Bytes", Data, Min);
 }
 
+Expected<codeview::LazyRandomTypeCollection &>
+BytesOutputStyle::initializeTypes(uint32_t StreamIdx) {
+  auto &TypeCollection = (StreamIdx == StreamTPI) ? TpiTypes : IpiTypes;
+  if (TypeCollection)
+    return *TypeCollection;
+
+  auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
+                                      : File.getPDBIpiStream();
+  if (!Tpi)
+    return Tpi.takeError();
+
+  auto &Types = Tpi->typeArray();
+  uint32_t Count = Tpi->getNumTypeRecords();
+  auto Offsets = Tpi->getTypeIndexOffsets();
+  TypeCollection =
+      llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
+
+  return *TypeCollection;
+}
+
 void BytesOutputStyle::dumpStreamBytes() {
   if (StreamPurposes.empty())
     discoverStreamPurposes(File, StreamPurposes);

Modified: llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h Fri Jun 23 16:50:54 2017
@@ -17,6 +17,10 @@
 
 namespace llvm {
 
+namespace codeview {
+class LazyRandomTypeCollection;
+}
+
 namespace pdb {
 
 class PDBFile;
@@ -40,6 +44,14 @@ private:
   void dumpTypeServerMap();
   void dumpECData();
 
+  void dumpTypeIndex(uint32_t StreamIdx, ArrayRef<uint32_t> Indices);
+
+  Expected<codeview::LazyRandomTypeCollection &>
+  initializeTypes(uint32_t StreamIdx);
+
+  std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes;
+  std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes;
+
   PDBFile &File;
   LinePrinter P;
   ExitOnError Err;

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Fri Jun 23 16:50:54 2017
@@ -270,6 +270,7 @@ namespace bytes {
 cl::OptionCategory MsfBytes("MSF File Options");
 cl::OptionCategory DbiBytes("Dbi Stream Options");
 cl::OptionCategory PdbBytes("PDB Stream Options");
+cl::OptionCategory Types("Type Options");
 
 llvm::Optional<NumberRange> DumpBlockRange;
 llvm::Optional<NumberRange> DumpByteRange;
@@ -306,6 +307,16 @@ cl::opt<bool> TypeServerMap("type-server
 cl::opt<bool> ECData("ec", cl::desc("Dump edit and continue map"),
                      cl::sub(BytesSubcommand), cl::cat(DbiBytes));
 
+cl::list<uint32_t>
+    TypeIndex("type",
+              cl::desc("Dump the type record with the given type index"),
+              cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand),
+              cl::cat(TypeCategory));
+cl::list<uint32_t>
+    IdIndex("id", cl::desc("Dump the id record with the given type index"),
+            cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand),
+            cl::cat(TypeCategory));
+
 cl::list<std::string> InputFilenames(cl::Positional,
                                      cl::desc("<input PDB files>"),
                                      cl::OneOrMore, cl::sub(BytesSubcommand));

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h?rev=306167&r1=306166&r2=306167&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Fri Jun 23 16:50:54 2017
@@ -110,6 +110,9 @@ extern llvm::cl::opt<bool> FileInfo;
 extern llvm::cl::opt<bool> TypeServerMap;
 extern llvm::cl::opt<bool> ECData;
 
+extern llvm::cl::list<uint32_t> TypeIndex;
+extern llvm::cl::list<uint32_t> IdIndex;
+
 } // namespace bytes
 
 namespace dump {




More information about the llvm-commits mailing list