]> granicus.if.org Git - llvm/commitdiff
[PDB] Dump extra info about the publics stream
authorReid Kleckner <rnk@google.com>
Fri, 21 Jul 2017 18:28:55 +0000 (18:28 +0000)
committerReid Kleckner <rnk@google.com>
Fri, 21 Jul 2017 18:28:55 +0000 (18:28 +0000)
This includes the hash table, the address map, and the thunk table and
section offset table. The last two are only used for incremental
linking, which LLD doesn't support, so they are less interesting. The
hash table is particularly important to get right, since this is the one
of the streams that debuggers use to translate addresses to symbols.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308764 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/PDB/Native/PublicsStream.h
lib/DebugInfo/PDB/Native/GSI.cpp
lib/DebugInfo/PDB/Native/GSI.h
lib/DebugInfo/PDB/Native/PublicsStream.cpp
tools/llvm-pdbutil/DumpOutputStyle.cpp
tools/llvm-pdbutil/llvm-pdbutil.cpp
tools/llvm-pdbutil/llvm-pdbutil.h

index 9ace826bd8f71e114616cc52a87626e6f0437300..bf1950c90052a74c2e63669a4cfca6df64d50374 100644 (file)
@@ -36,6 +36,8 @@ public:
   Expected<const codeview::CVSymbolArray &> getSymbolArray() const;
   iterator_range<codeview::CVSymbolArray::Iterator>
   getSymbols(bool *HadError) const;
+  FixedStreamArray<PSHashRecord> getHashRecords() const { return HashRecords; }
+  FixedStreamArray<PSHashRecord> getHashBitmap() const { return HashBitmap; }
   FixedStreamArray<support::ulittle32_t> getHashBuckets() const {
     return HashBuckets;
   }
@@ -56,8 +58,8 @@ private:
 
   std::unique_ptr<msf::MappedBlockStream> Stream;
   uint32_t NumBuckets = 0;
-  ArrayRef<uint8_t> Bitmap;
   FixedStreamArray<PSHashRecord> HashRecords;
+  ArrayRef<uint8_t> HashBitmap;
   FixedStreamArray<support::ulittle32_t> HashBuckets;
   FixedStreamArray<support::ulittle32_t> AddressMap;
   FixedStreamArray<support::ulittle32_t> ThunkMap;
index b219fe275f73577c63b0f553e966bc6b421644c0..d77676dbd1ce0ca34208dc60d077aa0edafe9ca6 100644 (file)
@@ -29,6 +29,7 @@ static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
 }
 
 Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
+                         ArrayRef<uint8_t> &HashBitmap,
                          const GSIHashHeader *HashHdr,
                          BinaryStreamReader &Reader) {
   if (auto EC = checkHashHdrVersion(HashHdr))
@@ -36,15 +37,14 @@ Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
 
   // Before the actual hash buckets, there is a bitmap of length determined by
   // IPHR_HASH.
-  ArrayRef<uint8_t> Bitmap;
   size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
   uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
-  if (auto EC = Reader.readBytes(Bitmap, NumBitmapEntries))
+  if (auto EC = Reader.readBytes(HashBitmap, NumBitmapEntries))
     return joinErrors(std::move(EC),
                       make_error<RawError>(raw_error_code::corrupt_file,
                                            "Could not read a bitmap."));
   uint32_t NumBuckets = 0;
-  for (uint8_t B : Bitmap)
+  for (uint8_t B : HashBitmap)
     NumBuckets += countPopulation(B);
 
   // Hash buckets follow.
index 9e63bc83548fb547bc18abcde88ffc9794482012..ce2b301b3ccb53a2f19a737796437c159f5911b5 100644 (file)
@@ -41,7 +41,7 @@ namespace pdb {
 static const unsigned IPHR_HASH = 4096;
 
 /// Header of the hash tables found in the globals and publics sections.
-/// Based on GSIHashHeader in
+/// Based on GSIHashHdr in
 /// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
 struct GSIHashHeader {
   enum : unsigned {
index 9c3e654f808ba283d0b468020a3f6dce9f8378c7..3b4e18de8f93d1147fb3584155856df6858db276 100644 (file)
@@ -75,7 +75,7 @@ Error PublicsStream::reload() {
   if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader))
     return EC;
 
-  if (auto EC = readGSIHashBuckets(HashBuckets, HashHdr, Reader))
+  if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr, Reader))
     return EC;
   NumBuckets = HashBuckets.size();
 
index 01c7481c30865825d54770da3a701c57a6e32b2e..07fc38d44067dca05bd342877b78a69f8228558c 100644 (file)
@@ -882,6 +882,52 @@ Error DumpOutputStyle::dumpPublics() {
     P.formatLine("Error while processing public symbol records.  {0}",
                  toString(std::move(EC)));
 
+  // Return early if we aren't dumping public hash table and address map info.
+  if (!opts::dump::DumpPublicExtras)
+    return Error::success();
+
+  P.formatLine("Hash Records");
+  {
+    AutoIndent Indent2(P);
+    for (const PSHashRecord &HR : Publics.getHashRecords())
+      P.formatLine("off = {0}, refcnt = {1}", uint32_t(HR.Off),
+                   uint32_t(HR.CRef));
+  }
+
+  // FIXME: Dump the bitmap.
+
+  P.formatLine("Hash Buckets");
+  {
+    AutoIndent Indent2(P);
+    for (uint32_t Hash : Publics.getHashBuckets())
+      P.formatLine("{0:x8}", Hash);
+  }
+
+  P.formatLine("Address Map");
+  {
+    // These are offsets into the publics stream sorted by secidx:secrel.
+    AutoIndent Indent2(P);
+    for (uint32_t Addr : Publics.getAddressMap())
+      P.formatLine("off = {0}", Addr);
+  }
+
+  // The thunk map is optional debug info used for ILT thunks.
+  if (!Publics.getThunkMap().empty()) {
+    P.formatLine("Thunk Map");
+    AutoIndent Indent2(P);
+    for (uint32_t Addr : Publics.getThunkMap())
+      P.formatLine("{0:x8}", Addr);
+  }
+
+  // The section offsets table appears to be empty when incremental linking
+  // isn't in use.
+  if (!Publics.getSectionOffsets().empty()) {
+    P.formatLine("Section Offsets");
+    AutoIndent Indent2(P);
+    for (const SectionOffset &SO : Publics.getSectionOffsets())
+      P.formatLine("{0:x4}:{1:x8}", uint16_t(SO.Isect), uint32_t(SO.Off));
+  }
+
   return Error::success();
 }
 
index f2bd194622ed74f186714c84e67e63d30b64ad43..338e4ee9250128e7cf07c5adbcf4c424f7976cd6 100644 (file)
@@ -452,6 +452,9 @@ cl::opt<bool> DumpTypeDependents(
 // SYMBOL OPTIONS
 cl::opt<bool> DumpPublics("publics", cl::desc("dump Publics stream data"),
                           cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
+cl::opt<bool> DumpPublicExtras("public-extras",
+                               cl::desc("dump Publics hashes and address maps"),
+                               cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
 cl::opt<bool> DumpSymbols("symbols", cl::desc("dump module symbols"),
                           cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
 
index 4e92e639a12780a73aba9737ab91e414ba2220e3..4aeff99d6c7c48ed17dbd9920a3e12bd3a02414c 100644 (file)
@@ -144,6 +144,7 @@ extern llvm::cl::list<uint32_t> DumpIdIndex;
 extern llvm::cl::opt<bool> DumpSymbols;
 extern llvm::cl::opt<bool> DumpSymRecordBytes;
 extern llvm::cl::opt<bool> DumpPublics;
+extern llvm::cl::opt<bool> DumpPublicExtras;
 extern llvm::cl::opt<bool> DumpSectionContribs;
 extern llvm::cl::opt<bool> DumpSectionMap;
 extern llvm::cl::opt<bool> DumpModules;