[llvm-pdbutil] Dump more info about globals.
authorZachary Turner <zturner@google.com>
Fri, 6 Jul 2018 02:59:25 +0000 (02:59 +0000)
committerZachary Turner <zturner@google.com>
Fri, 6 Jul 2018 02:59:25 +0000 (02:59 +0000)
We add an option to dump the entire global / public symbol record
stream.  Previously we would dump globals or publics, but not both.
And when we did dump them, we would always dump them in the order
they were referenced by the corresponding hash streams, not in
the order they were serialized in.  This patch adds a lower level
mode that just dumps the whole stream in serialization order.

Additionally, when dumping global-extras, we now dump the hash
bitmap as well as the record offset instead of dumping all zeros
for the offsets.

llvm-svn: 336407

lld/test/COFF/pdb.test
llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
llvm/tools/llvm-pdbutil/DumpOutputStyle.h
llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
llvm/tools/llvm-pdbutil/llvm-pdbutil.h

index 5788b51..a7b2a21 100644 (file)
@@ -193,6 +193,25 @@ RAW-NEXT:            flags = function, addr = 0001:0000
 RAW-NEXT:        0 | S_PUB32 [size = 20] `foo`
 RAW-NEXT:            flags = function, addr = 0001:0016
 RAW-NOT:             S_PUB32
+RAW-NEXT:     Hash Bitmap (
+RAW-NEXT:     0000: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0040: 00000000 20000000 00000000 00000000 00000000 00000000 00000000 00000000  |.... ...........................|
+RAW-NEXT:     0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0080: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     00A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     00C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     00E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0160: 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     01A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     01C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     01E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
+RAW-NEXT:     0200: 00000000                                                                 |....|
+RAW-NEXT:   )
 RAW-NEXT:   Hash Entries
 RAW-NEXT:     off = 21, refcnt = 1
 RAW-NEXT:     off = 1, refcnt = 1
index 5ecb9be..9e59adc 100644 (file)
@@ -151,6 +151,11 @@ Error DumpOutputStyle::dump() {
     }
   }
 
+  if (opts::dump::DumpGSIRecords) {
+    if (auto EC = dumpGSIRecords())
+      return EC;
+  }
+
   if (opts::dump::DumpGlobals) {
     if (auto EC = dumpGlobals())
       return EC;
@@ -1357,6 +1362,39 @@ Error DumpOutputStyle::dumpModuleSymsForPdb() {
   return Error::success();
 }
 
+Error DumpOutputStyle::dumpGSIRecords() {
+  printHeader(P, "GSI Records");
+  AutoIndent Indent(P);
+
+  if (File.isObj()) {
+    P.formatLine("Dumping Globals is not supported for object files");
+    return Error::success();
+  }
+
+  if (!getPdb().hasPDBSymbolStream()) {
+    P.formatLine("GSI Common Symbol Stream not present");
+    return Error::success();
+  }
+
+  auto &Records = cantFail(getPdb().getPDBSymbolStream());
+  auto &Types = File.types();
+  auto &Ids = File.ids();
+
+  P.printLine("Records");
+  SymbolVisitorCallbackPipeline Pipeline;
+  SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
+  MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Ids, Types);
+
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(Dumper);
+  CVSymbolVisitor Visitor(Pipeline);
+
+  BinaryStreamRef SymStream = Records.getSymbolArray().getUnderlyingStream();
+  if (auto E = Visitor.visitSymbolStream(Records.getSymbolArray(), 0))
+    return E;
+  return Error::success();
+}
+
 Error DumpOutputStyle::dumpGlobals() {
   printHeader(P, "Global Symbols");
   AutoIndent Indent(P);
@@ -1462,6 +1500,7 @@ Error DumpOutputStyle::dumpSymbolsFromGSI(const GSIHashTable &Table,
     Pipeline.addCallbackToPipeline(Dumper);
     CVSymbolVisitor Visitor(Pipeline);
 
+
     BinaryStreamRef SymStream =
         ExpectedSyms->getSymbolArray().getUnderlyingStream();
     for (uint32_t PubSymOff : Table) {
@@ -1474,24 +1513,23 @@ Error DumpOutputStyle::dumpSymbolsFromGSI(const GSIHashTable &Table,
   }
 
   // Return early if we aren't dumping public hash table and address map info.
-  if (!HashExtras)
-    return Error::success();
-
-  P.formatLine("Hash Entries");
-  {
-    AutoIndent Indent2(P);
-    for (const PSHashRecord &HR : Table.HashRecords)
-      P.formatLine("off = {0}, refcnt = {1}", uint32_t(HR.Off),
-                   uint32_t(HR.CRef));
-  }
+  if (HashExtras) {
+    P.formatBinary("Hash Bitmap", Table.HashBitmap, 0);
 
-  // FIXME: Dump the bitmap.
+    P.formatLine("Hash Entries");
+    {
+      AutoIndent Indent2(P);
+      for (const PSHashRecord &HR : Table.HashRecords)
+        P.formatLine("off = {0}, refcnt = {1}", uint32_t(HR.Off),
+          uint32_t(HR.CRef));
+    }
 
-  P.formatLine("Hash Buckets");
-  {
-    AutoIndent Indent2(P);
-    for (uint32_t Hash : Table.HashBuckets)
-      P.formatLine("{0:x8}", Hash);
+    P.formatLine("Hash Buckets");
+    {
+      AutoIndent Indent2(P);
+      for (uint32_t Hash : Table.HashBuckets)
+        P.formatLine("{0:x8}", Hash);
+    }
   }
 
   return Error::success();
index 36d8b13..e7e9252 100644 (file)
@@ -88,6 +88,7 @@ private:
   Error dumpModuleFiles();
   Error dumpModuleSymsForPdb();
   Error dumpModuleSymsForObj();
+  Error dumpGSIRecords();
   Error dumpGlobals();
   Error dumpPublics();
   Error dumpSymbolsFromGSI(const GSIHashTable &Table, bool HashExtras);
index 74c8305..0088d30 100644 (file)
@@ -458,6 +458,10 @@ cl::opt<bool> DumpPublics("publics", cl::desc("dump Publics stream data"),
 cl::opt<bool> DumpPublicExtras("public-extras",
                                cl::desc("dump Publics hashes and address maps"),
                                cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
+cl::opt<bool>
+    DumpGSIRecords("gsi-records",
+                   cl::desc("dump public / global common record stream"),
+                   cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
 cl::opt<bool> DumpSymbols("symbols", cl::desc("dump module symbols"),
                           cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
 
index 811faf6..8dad5e8 100644 (file)
@@ -160,6 +160,7 @@ extern llvm::cl::opt<uint32_t> DumpModi;
 extern llvm::cl::opt<bool> JustMyCode;
 extern llvm::cl::opt<bool> DumpSymbols;
 extern llvm::cl::opt<bool> DumpSymRecordBytes;
+extern llvm::cl::opt<bool> DumpGSIRecords;
 extern llvm::cl::opt<bool> DumpGlobals;
 extern llvm::cl::opt<bool> DumpGlobalExtras;
 extern llvm::cl::opt<bool> DumpPublics;