[llvm] r268808 - Make llvm-pdbdump print CV type records

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri May 6 15:15:42 PDT 2016


Author: zturner
Date: Fri May  6 17:15:42 2016
New Revision: 268808

URL: http://llvm.org/viewvc/llvm-project?rev=268808&view=rev
Log:
Make llvm-pdbdump print CV type records

This reuses the CVTypeDumper from libcodeview to dump full
information about type records within a PDB file.

Differential Revision: http://reviews.llvm.org/D20022
Reviewed By: rnk

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/PDB/LLVMBuild.txt
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

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=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Fri May  6 17:15:42 2016
@@ -51,36 +51,38 @@ public:
 #define MEMBER_RECORD_ALIAS(ClassName, LeafEnum)
 #include "TypeRecords.def"
 
-  /// Visits the type records in Data and returns remaining data. Sets the
-  /// error flag on parse failures.
-  void visitTypeStream(ArrayRef<uint8_t> Data) {
-    for (const auto &I : makeTypeRange(Data)) {
-      ArrayRef<uint8_t> LeafData = I.LeafData;
-      ArrayRef<uint8_t> RecordData = LeafData;
-      auto *DerivedThis = static_cast<Derived *>(this);
-      DerivedThis->visitTypeBegin(I.Leaf, RecordData);
-      switch (I.Leaf) {
-      default:
-        DerivedThis->visitUnknownType(I.Leaf);
-        break;
-      case LF_FIELDLIST:
-        DerivedThis->visitFieldList(I.Leaf, LeafData);
-        break;
-      case LF_METHODLIST:
-        DerivedThis->visitMethodList(I.Leaf, LeafData);
-        break;
+  void visitTypeRecord(const TypeIterator::TypeRecord &Record) {
+    ArrayRef<uint8_t> LeafData = Record.LeafData;
+    ArrayRef<uint8_t> RecordData = LeafData;
+    auto *DerivedThis = static_cast<Derived *>(this);
+    DerivedThis->visitTypeBegin(Record.Leaf, RecordData);
+    switch (Record.Leaf) {
+    default:
+      DerivedThis->visitUnknownType(Record.Leaf);
+      break;
+    case LF_FIELDLIST:
+      DerivedThis->visitFieldList(Record.Leaf, LeafData);
+      break;
+    case LF_METHODLIST:
+      DerivedThis->visitMethodList(Record.Leaf, LeafData);
+      break;
 #define TYPE_RECORD(ClassName, LeafEnum)                                       \
   case LeafEnum: {                                                             \
     const ClassName *Rec;                                                      \
     if (!CVTypeVisitor::consumeObject(LeafData, Rec))                          \
       return;                                                                  \
-    DerivedThis->visit##ClassName(I.Leaf, Rec, LeafData);     \
+    DerivedThis->visit##ClassName(Record.Leaf, Rec, LeafData);                 \
     break;                                                                     \
   }
 #include "TypeRecords.def"
       }
-      DerivedThis->visitTypeEnd(I.Leaf, RecordData);
-    }
+      DerivedThis->visitTypeEnd(Record.Leaf, RecordData);
+  }
+
+  /// 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))
+      visitTypeRecord(I);
   }
 
   /// Action to take on unknown types. By default, they are ignored.

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=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h Fri May  6 17:15:42 2016
@@ -14,6 +14,7 @@
 #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;
@@ -29,6 +30,12 @@ public:
   StringRef getTypeName(TypeIndex TI);
   void printTypeIndex(StringRef FieldName, TypeIndex TI);
 
+  /// Dumps one type record.  Returns false if there was a type parsing error,
+  /// 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::TypeRecord &Record);
+
   /// Dumps the type records in Data. Returns false if there was a type stream
   /// parse error, and true otherwise.
   bool dump(ArrayRef<uint8_t> Data);

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Fri May  6 17:15:42 2016
@@ -755,6 +755,12 @@ void CVTypeDumper::printTypeIndex(String
     W.printHex(FieldName, TI.getIndex());
 }
 
+bool CVTypeDumper::dump(const TypeIterator::TypeRecord &Record) {
+  CVTypeDumperImpl Dumper(*this, W, PrintRecordBytes);
+  Dumper.visitTypeRecord(Record);
+  return !Dumper.hadError();
+}
+
 bool CVTypeDumper::dump(ArrayRef<uint8_t> Data) {
   CVTypeDumperImpl Dumper(*this, W, PrintRecordBytes);
   Dumper.visitTypeStream(Data);

Modified: llvm/trunk/lib/DebugInfo/PDB/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/LLVMBuild.txt?rev=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/LLVMBuild.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/LLVMBuild.txt Fri May  6 17:15:42 2016
@@ -19,5 +19,5 @@
 type = Library
 name = DebugInfoPDB
 parent = DebugInfo
-required_libraries = Object Support
+required_libraries = Object Support DebugInfoCodeView
 

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Fri May  6 17:15:42 2016
@@ -1,4 +1,5 @@
-; RUN: llvm-pdbdump --dump-headers -dump-tpi-stream -dump-tpi-record-bytes %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
+; RUN: llvm-pdbdump --dump-headers -dump-tpi-records -dump-tpi-record-bytes \
+; RUN:              %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
 ; RUN: llvm-pdbdump --dump-headers %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s
 ; RUN: llvm-pdbdump --dump-headers %p/Inputs/bad-block-size.pdb | FileCheck -check-prefix=BAD-BLOCK-SIZE %s
 
@@ -78,28 +79,71 @@
 ; EMPTY-NEXT:   TPI Version: 20040203
 ; EMPTY-NEXT:   Record count: 75
 ; EMPTY-NEXT:   Records [
-; EMPTY-NEXT:   {
-; EMPTY-NEXT:     Kind: 0x1201
-; EMPTY-NEXT:     Bytes (
-; EMPTY-NEXT:       0000: 00000000                             |....|
-; EMPTY-NEXT:     )
-; EMPTY-NEXT:   }
-; EMPTY-NEXT:   {
-; EMPTY-NEXT:     Kind: 0x1008
-; EMPTY-NEXT:     Bytes (
-; EMPTY-NEXT:       0000: 74000000 00000000 00100000           |t...........|
-; EMPTY-NEXT:     )
-; EMPTY-NEXT:   }
-; EMPTY-NEXT:   {
-; EMPTY-NEXT:     Kind: 0x1203
-; EMPTY-NEXT:     Bytes (
-; EMPTY-NEXT:       0000: 02150300 01006170 6172746D 656E7400  |......apartment.|
-; EMPTY-NEXT:       0010: 02150300 02007369 6E676C65 00F3F2F1  |......single....|
-; EMPTY-NEXT:       0020: 02150300 03006672 656500F1 02150300  |......free......|
-; EMPTY-NEXT:       0030: 04006E65 75747261 6C00F2F1 02150300  |..neutral.......|
-; EMPTY-NEXT:       0040: 0500626F 746800F1                    |..both..|
-; EMPTY-NEXT:     )
-; EMPTY-NEXT:   }
+; EMPTY-NEXT:     {
+; EMPTY-NEXT:       ArgList {
+; EMPTY-NEXT:         TypeLeafKind: LF_ARGLIST (0x1201)
+; EMPTY-NEXT:         TypeIndex: 0x1000
+; EMPTY-NEXT:         NumArgs: 0
+; EMPTY-NEXT:         Arguments [
+; EMPTY-NEXT:         ]
+; EMPTY-NEXT:       }
+; EMPTY-NEXT:       Bytes (
+; EMPTY-NEXT:         0000: 00000000                             |....|
+; EMPTY-NEXT:       )
+; EMPTY-NEXT:     }
+; EMPTY-NEXT:     {
+; EMPTY-NEXT:       ProcedureType {
+; EMPTY-NEXT:         TypeLeafKind: LF_PROCEDURE (0x1008)
+; EMPTY-NEXT:         TypeIndex: 0x1001
+; EMPTY-NEXT:         ReturnType: int (0x74)
+; EMPTY-NEXT:         CallingConvention: NearC (0x0)
+; EMPTY-NEXT:         FunctionOptions [ (0x0)
+; EMPTY-NEXT:         ]
+; EMPTY-NEXT:         NumParameters: 0
+; EMPTY-NEXT:         ArgListType: () (0x1000)
+; EMPTY-NEXT:       }
+; EMPTY-NEXT:       Bytes (
+; EMPTY-NEXT:         0000: 74000000 00000000 00100000           |t...........|
+; EMPTY-NEXT:       )
+; EMPTY-NEXT:     }
+; EMPTY-NEXT:     {
+; EMPTY-NEXT:       UnknownLeaf {
+; EMPTY-NEXT:         TypeLeafKind: LF_FIELDLIST (0x1203)
+; EMPTY-NEXT:         TypeIndex: 0x1002
+; EMPTY-NEXT:         Enumerator {
+; EMPTY-NEXT:           AccessSpecifier: Public (0x3)
+; EMPTY-NEXT:           EnumValue: 1
+; EMPTY-NEXT:           Name: apartment
+; EMPTY-NEXT:         }
+; EMPTY-NEXT:         Enumerator {
+; EMPTY-NEXT:           AccessSpecifier: Public (0x3)
+; EMPTY-NEXT:           EnumValue: 2
+; EMPTY-NEXT:           Name: single
+; EMPTY-NEXT:         }
+; EMPTY-NEXT:         Enumerator {
+; EMPTY-NEXT:           AccessSpecifier: Public (0x3)
+; EMPTY-NEXT:           EnumValue: 3
+; EMPTY-NEXT:           Name: free
+; EMPTY-NEXT:         }
+; EMPTY-NEXT:         Enumerator {
+; EMPTY-NEXT:           AccessSpecifier: Public (0x3)
+; EMPTY-NEXT:           EnumValue: 4
+; EMPTY-NEXT:           Name: neutral
+; EMPTY-NEXT:         }
+; EMPTY-NEXT:         Enumerator {
+; EMPTY-NEXT:           AccessSpecifier: Public (0x3)
+; EMPTY-NEXT:           EnumValue: 5
+; EMPTY-NEXT:           Name: both
+; EMPTY-NEXT:         }
+; EMPTY-NEXT:       }
+; EMPTY-NEXT:       Bytes (
+; EMPTY-NEXT:         0000: 02150300 01006170 6172746D 656E7400  |......apartment.|
+; EMPTY-NEXT:         0010: 02150300 02007369 6E676C65 00F3F2F1  |......single....|
+; EMPTY-NEXT:         0020: 02150300 03006672 656500F1 02150300  |......free......|
+; EMPTY-NEXT:         0030: 04006E65 75747261 6C00F2F1 02150300  |..neutral.......|
+; EMPTY-NEXT:         0040: 0500626F 746800F1                    |..both..|
+; EMPTY-NEXT:       )
+; EMPTY-NEXT:     }
 
 ; BIG:      FileHeaders {
 ; BIG-NEXT:   BlockSize: 4096
@@ -1238,4 +1282,4 @@
 ; BIG-NEXT:   ]
 ; BIG-NEXT: }
 
-; BAD-BLOCK-SIZE: The PDB file is corrupt. Does not contain superblock
+; BAD-BLOCK-SIZE: Native PDB Error: The PDB file is corrupt. Does not contain superblock

Modified: llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt?rev=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt Fri May  6 17:15:42 2016
@@ -1,4 +1,5 @@
 set(LLVM_LINK_COMPONENTS
+  DebugInfoCodeView
   DebugInfoPDB
   Object
   Support

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=268808&r1=268807&r2=268808&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri May  6 17:15:42 2016
@@ -26,6 +26,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Config/config.h"
+#include "llvm/DebugInfo/CodeView/TypeDumper.h"
 #include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
 #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
@@ -106,8 +107,8 @@ cl::opt<bool> DumpStreamSizes("dump-stre
 cl::opt<bool> DumpStreamBlocks("dump-stream-blocks",
                                cl::desc("dump PDB stream blocks"),
                                cl::cat(OtherOptions));
-cl::opt<bool> DumpTypeStream("dump-tpi-stream",
-                             cl::desc("dump PDB TPI (Type Info) stream"),
+cl::opt<bool> DumpTpiRecords("dump-tpi-records",
+                             cl::desc("dump CodeView type records"),
                              cl::cat(OtherOptions));
 cl::opt<bool>
     DumpTpiRecordBytes("dump-tpi-record-bytes",
@@ -338,7 +339,7 @@ static Error dumpDbiStream(ScopedPrinter
 }
 
 static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File) {
-  if (!opts::DumpTypeStream)
+  if (!opts::DumpTpiRecordBytes && !opts::DumpTpiRecords)
     return Error::success();
 
   DictScope D(P, "Type Info Stream");
@@ -351,14 +352,19 @@ static Error dumpTpiStream(ScopedPrinter
   P.printNumber("TPI Version", Tpi.getTpiVersion());
   P.printNumber("Record count", Tpi.NumTypeRecords());
 
-  if (!opts::DumpTpiRecordBytes)
-    return Error::success();
+  if (opts::DumpTpiRecordBytes || opts::DumpTpiRecords) {
+    ListScope L(P, "Records");
+    codeview::CVTypeDumper TD(P, false);
+
+    for (auto &Type : Tpi.types()) {
+      DictScope DD(P, "");
 
-  ListScope L(P, "Records");
-  for (auto &Type : Tpi.types()) {
-    DictScope DD(P, "");
-    P.printHex("Kind", unsigned(Type.Leaf));
-    P.printBinaryBlock("Bytes", Type.LeafData);
+      if (opts::DumpTpiRecords)
+        TD.dump(Type);
+
+      if (opts::DumpTpiRecordBytes)
+        P.printBinaryBlock("Bytes", Type.LeafData);
+    }
   }
   return Error::success();
 }




More information about the llvm-commits mailing list