[llvm] r269484 - pdbdump: Print "Publics" stream.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri May 13 14:21:54 PDT 2016


Author: ruiu
Date: Fri May 13 16:21:53 2016
New Revision: 269484

URL: http://llvm.org/viewvc/llvm-project?rev=269484&view=rev
Log:
pdbdump: Print "Publics" stream.

Publics stream seems to contain information as to public symbols.
It actually contains a serialized hash table along with fixed-sized
headers. This patch is not complete. It scans only till the end of
the stream and dump the header information. I'll write code to
de-serialize the hash table later.

Reviewers: zturner

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D20256

Added:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
    llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h

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=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStream.h Fri May 13 16:21:53 2016
@@ -33,6 +33,7 @@ public:
 
   PdbRaw_DbiVer getDbiVersion() const;
   uint32_t getAge() const;
+  uint16_t getPublicSymbolStreamIndex() const;
 
   bool isIncrementallyLinked() const;
   bool hasCTypes() const;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Fri May 13 16:21:53 2016
@@ -24,6 +24,7 @@ namespace pdb {
 struct PDBFileContext;
 class DbiStream;
 class InfoStream;
+class PublicsStream;
 class TpiStream;
 
 class PDBFile {
@@ -62,12 +63,14 @@ public:
   Expected<InfoStream &> getPDBInfoStream();
   Expected<DbiStream &> getPDBDbiStream();
   Expected<TpiStream &> getPDBTpiStream();
+  Expected<PublicsStream &> getPDBPublicsStream();
 
 private:
   std::unique_ptr<PDBFileContext> Context;
   std::unique_ptr<InfoStream> Info;
   std::unique_ptr<DbiStream> Dbi;
   std::unique_ptr<TpiStream> Tpi;
+  std::unique_ptr<PublicsStream> Publics;
 };
 }
 }

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h?rev=269484&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h Fri May 13 16:21:53 2016
@@ -0,0 +1,51 @@
+//===- PublicsStream.h - PDB Public Symbol Stream -------- ------*- 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_PDB_RAW_PUBLICSSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H
+
+#include "llvm/DebugInfo/CodeView/TypeStream.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/ByteStream.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace pdb {
+class PDBFile;
+
+class PublicsStream {
+  struct HeaderInfo;
+  struct GSIHashHeader;
+  struct HRFile;
+
+public:
+  PublicsStream(PDBFile &File, uint32_t StreamNum);
+  ~PublicsStream();
+  Error reload();
+
+  uint32_t getStreamNum() const { return StreamNum; }
+  uint32_t getSymHash() const;
+  uint32_t getAddrMap() const;
+  uint32_t getNumBuckets() const { return NumBuckets; }
+
+private:
+  uint32_t StreamNum;
+  MappedBlockStream Stream;
+  uint32_t NumBuckets = 0;
+
+  std::unique_ptr<HeaderInfo> Header;
+  std::unique_ptr<GSIHashHeader> HashHdr;
+};
+}
+}
+
+#endif

Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Fri May 13 16:21:53 2016
@@ -37,6 +37,7 @@ add_pdb_impl_folder(Raw
   Raw/NameHashTable.cpp
   Raw/NameMap.cpp
   Raw/PDBFile.cpp
+  Raw/PublicsStream.cpp
   Raw/RawError.cpp
   Raw/RawSession.cpp
   Raw/StreamReader.cpp

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=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStream.cpp Fri May 13 16:21:53 2016
@@ -52,17 +52,17 @@ const uint16_t BuildMajorShift = 8;
 struct DbiStream::HeaderInfo {
   little32_t VersionSignature;
   ulittle32_t VersionHeader;
-  ulittle32_t Age;                  // Should match InfoStream.
-  ulittle16_t GSSyms;               // Number of global symbols
-  ulittle16_t BuildNumber;          // See DbiBuildNo structure.
-  ulittle16_t PSSyms;               // Number of public symbols
-  ulittle16_t PdbDllVersion;        // version of mspdbNNN.dll
-  ulittle16_t SymRecords;           // Number of symbols
-  ulittle16_t PdbDllRbld;           // rbld number of mspdbNNN.dll
-  little32_t ModiSubstreamSize;     // Size of module info stream
-  little32_t SecContrSubstreamSize; // Size of sec. contribution stream
-  little32_t SectionMapSize;        // Size of sec. map substream
-  little32_t FileInfoSize;          // Size of file info substream
+  ulittle32_t Age;                     // Should match InfoStream.
+  ulittle16_t GSSyms;                  // Number of global symbols
+  ulittle16_t BuildNumber;             // See DbiBuildNo structure.
+  ulittle16_t PublicSymbolStreamIndex; // Number of public symbols
+  ulittle16_t PdbDllVersion;           // version of mspdbNNN.dll
+  ulittle16_t SymRecords;              // Number of symbols
+  ulittle16_t PdbDllRbld;              // rbld number of mspdbNNN.dll
+  little32_t ModiSubstreamSize;        // Size of module info stream
+  little32_t SecContrSubstreamSize;    // Size of sec. contribution stream
+  little32_t SectionMapSize;           // Size of sec. map substream
+  little32_t FileInfoSize;             // Size of file info substream
   little32_t TypeServerSize;      // Size of type server map
   ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server
   little32_t OptionalDbgHdrSize;  // Size of DbgHeader info
@@ -184,6 +184,10 @@ PdbRaw_DbiVer DbiStream::getDbiVersion()
 
 uint32_t DbiStream::getAge() const { return Header->Age; }
 
+uint16_t DbiStream::getPublicSymbolStreamIndex() const {
+  return Header->PublicSymbolStreamIndex;
+}
+
 bool DbiStream::isIncrementallyLinked() const {
   return (Header->Flags & FlagIncrementalMask) != 0;
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp?rev=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp Fri May 13 16:21:53 2016
@@ -11,6 +11,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/Support/Endian.h"
@@ -292,3 +293,17 @@ Expected<TpiStream &> PDBFile::getPDBTpi
   }
   return *Tpi;
 }
+
+Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
+  if (!Publics) {
+    auto DbiS = getPDBDbiStream();
+    if (auto EC = DbiS.takeError())
+      return std::move(EC);
+    uint32_t PublicsStreamNum = DbiS->getPublicSymbolStreamIndex();
+
+    Publics.reset(new PublicsStream(*this, PublicsStreamNum));
+    if (auto EC = Publics->reload())
+      return std::move(EC);
+  }
+  return *Publics;
+}

Added: llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp?rev=269484&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PublicsStream.cpp Fri May 13 16:21:53 2016
@@ -0,0 +1,132 @@
+//===- PublicsStream.cpp - PDB Public Symbol Stream -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The data structures defined in this file are based on the reference
+// implementation which is available at
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
+//
+// When you are reading the reference source code, you'd find the
+// information below useful.
+//
+//  - ppdb1->m_fMinimalDbgInfo seems to be always true.
+//  - SMALLBUCKETS macro is defined.
+//
+// The reference doesn't compile, so I learned just by reading code.
+// It's not guaranteed to be correct.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace llvm;
+using namespace llvm::support;
+using namespace llvm::pdb;
+
+
+static const unsigned IPHR_HASH = 4096;
+
+// This is PSGSIHDR struct defined in
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
+struct PublicsStream::HeaderInfo {
+  ulittle32_t SymHash;
+  ulittle32_t AddrMap;
+  ulittle32_t NumThunks;
+  ulittle32_t SizeOfThunk;
+  ulittle16_t ISectThunkTable;
+  char Padding[2];
+  ulittle32_t OffThunkTable;
+  ulittle32_t NumSects;
+};
+
+
+// This is GSIHashHdr struct defined in
+struct PublicsStream::GSIHashHeader {
+  enum {
+    HdrSignature = -1,
+    HdrVersion = 0xeffe0000 + 19990810,
+  };
+  ulittle32_t VerSignature;
+  ulittle32_t VerHdr;
+  ulittle32_t HrSize;
+  ulittle32_t NumBuckets;
+};
+
+struct PublicsStream::HRFile {
+  ulittle32_t Off;
+  ulittle32_t CRef;
+};
+
+PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)
+    : StreamNum(StreamNum), Stream(StreamNum, File) {}
+
+PublicsStream::~PublicsStream() {}
+
+uint32_t PublicsStream::getSymHash() const { return Header->SymHash; }
+uint32_t PublicsStream::getAddrMap() const { return Header->AddrMap; }
+
+// Publics stream contains fixed-size headers and a serialized hash table.
+// This implementation is not complete yet. It reads till the end of the
+// stream so that we verify the stream is at least not corrupted. However,
+// we skip over the hash table which we believe contains information about
+// public symbols.
+Error PublicsStream::reload() {
+  StreamReader Reader(Stream);
+
+  // Check stream size.
+  if (Reader.bytesRemaining() < sizeof(HeaderInfo) + sizeof(GSIHashHeader))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Publics Stream does not contain a header.");
+
+  // Read PSGSIHDR and GSIHashHdr structs.
+  Header.reset(new HeaderInfo());
+  if (Reader.readObject(Header.get()))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Publics Stream does not contain a header.");
+  HashHdr.reset(new GSIHashHeader());
+  if (Reader.readObject(HashHdr.get()))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Publics Stream does not contain a header.");
+
+  // An array of HRFile follows. Read them.
+  if (HashHdr->HrSize % sizeof(HRFile))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Invalid HR array size.");
+  std::vector<HRFile> HRs(HashHdr->HrSize / sizeof(HRFile));
+  if (auto EC = Reader.readArray<HRFile>(HRs))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Could not read an HR array");
+
+  // A bitmap of a fixed length follows.
+  size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
+  std::vector<uint8_t> Bitmap(BitmapSizeInBits / 8);
+  if (auto EC = Reader.readArray<uint8_t>(Bitmap))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Could not read a bitmap.");
+  for (uint8_t B : Bitmap)
+    NumBuckets += countPopulation(B);
+
+  // Buckets follow.
+  if (Reader.bytesRemaining() < NumBuckets * sizeof(uint32_t))
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Hash buckets corrupted.");
+
+  return Error::success();
+}

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=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Fri May 13 16:21:53 2016
@@ -1,5 +1,5 @@
 ; RUN: llvm-pdbdump --dump-headers -dump-tpi-records -dump-tpi-record-bytes -dump-module-syms \
-; RUN:              %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
+; RUN:              --dump-publics %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
 
@@ -308,6 +308,13 @@
 ; EMPTY-NEXT:       )
 ; EMPTY-NEXT:     }
 
+; EMPTY:      Publics Stream {
+; EMPTY-NEXT:   Stream number: 7
+; EMPTY-NEXT:   SymHash: 556
+; EMPTY-NEXT:   AddrMap: 8
+; EMPTY-NEXT:   Number of buckets: 2
+; EMPTY-NEXT: }
+
 ; BIG:      FileHeaders {
 ; BIG-NEXT:   BlockSize: 4096
 ; BIG-NEXT:   Unknown0: 2

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=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri May 13 16:21:53 2016
@@ -44,6 +44,7 @@
 #include "llvm/DebugInfo/PDB/Raw/ModStream.h"
 #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/RawSession.h"
 #include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
@@ -122,6 +123,9 @@ cl::opt<std::string> DumpStreamData("dum
 cl::opt<bool> DumpModuleSyms("dump-module-syms",
                              cl::desc("dump module symbols"),
                              cl::cat(NativeOtions));
+cl::opt<bool> DumpPublics("dump-publics",
+                          cl::desc("dump Publics stream data"),
+                          cl::cat(NativeOtions));
 
 cl::list<std::string>
     ExcludeTypes("exclude-types",
@@ -394,6 +398,22 @@ static Error dumpTpiStream(ScopedPrinter
   return Error::success();
 }
 
+static Error dumpPublicsStream(ScopedPrinter &P, PDBFile &File) {
+  if (!opts::DumpPublics)
+    return Error::success();
+
+  DictScope D(P, "Publics Stream");
+  auto PublicsS = File.getPDBPublicsStream();
+  if (auto EC = PublicsS.takeError())
+    return EC;
+  PublicsStream &Publics = PublicsS.get();
+  P.printNumber("Stream number", Publics.getStreamNum());
+  P.printNumber("SymHash", Publics.getSymHash());
+  P.printNumber("AddrMap", Publics.getAddrMap());
+  P.printNumber("Number of buckets", Publics.getNumBuckets());
+  return Error::success();
+}
+
 static Error dumpStructure(RawSession &RS) {
   PDBFile &File = RS.getPDBFile();
   ScopedPrinter P(outs());
@@ -421,7 +441,10 @@ static Error dumpStructure(RawSession &R
 
   if (auto EC = dumpTpiStream(P, File))
     return EC;
-  return Error::success();
+
+  if (auto EC = dumpPublicsStream(P, File))
+    return EC;
+return Error::success();
 }
 
 static void dumpInput(StringRef Path) {

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h?rev=269484&r1=269483&r2=269484&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h Fri May 13 16:21:53 2016
@@ -32,4 +32,4 @@ extern llvm::cl::list<std::string> Inclu
 extern llvm::cl::list<std::string> IncludeCompilands;
 }
 
-#endif
\ No newline at end of file
+#endif




More information about the llvm-commits mailing list