[llvm] r328348 - [PDB] Make our PDBs look more like MS PDBs.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 23 11:43:40 PDT 2018


Author: zturner
Date: Fri Mar 23 11:43:39 2018
New Revision: 328348

URL: http://llvm.org/viewvc/llvm-project?rev=328348&view=rev
Log:
[PDB] Make our PDBs look more like MS PDBs.

When investigating bugs in PDB generation, the first step is
often to do the same link with link.exe and then compare PDBs.

But comparing PDBs is hard because two completely different byte
sequences can both be correct, so it hampers the investigation when
you also have to spend time figuring out not just which bytes are
different, but also if the difference is meaningful.

This patch fixes a couple of cases related to string table emission,
hash table emission, and the order in which we emit strings that
makes more of our bytes the same as the bytes generated by MS PDBs.

Differential Revision: https://reviews.llvm.org/D44810

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
    llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
    llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h Fri Mar 23 11:43:39 2018
@@ -82,6 +82,8 @@ public:
 
   StringMap<uint32_t>::const_iterator end() const { return StringToId.end(); }
 
+  std::vector<uint32_t> sortedIds() const;
+
 private:
   DenseMap<uint32_t, StringRef> IdToString;
   StringMap<uint32_t> StringToId;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h Fri Mar 23 11:43:39 2018
@@ -121,7 +121,7 @@ private:
   MutableBinaryByteStream FileInfoBuffer;
   std::vector<SectionContrib> SectionContribs;
   ArrayRef<SecMapEntry> SectionMap;
-  llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams;
+  std::array<Optional<DebugStream>, (int)DbgHeaderType::Max> DbgStreams;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/HashTable.h Fri Mar 23 11:43:39 2018
@@ -304,12 +304,12 @@ private:
 
   void grow() {
     uint32_t S = size();
+    uint32_t MaxLoad = maxLoad(capacity());
     if (S < maxLoad(capacity()))
       return;
     assert(capacity() != UINT32_MAX && "Can't grow Hash table!");
 
-    uint32_t NewCapacity =
-        (capacity() <= INT32_MAX) ? capacity() * 2 : UINT32_MAX;
+    uint32_t NewCapacity = (capacity() <= INT32_MAX) ? MaxLoad * 2 : UINT32_MAX;
 
     // Growing requires rebuilding the table and re-hashing every item.  Make a
     // copy with a larger capacity, insert everything into the copy, then swap

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h Fri Mar 23 11:43:39 2018
@@ -54,10 +54,11 @@ public:
   Error commit(StringRef Filename);
 
   Expected<uint32_t> getNamedStreamIndex(StringRef Name) const;
-  Error addNamedStream(StringRef Name, uint32_t Size);
+  Error addNamedStream(StringRef Name, StringRef Data);
 
 private:
   Expected<msf::MSFLayout> finalizeMsfLayout();
+  Expected<uint32_t> allocateNamedStream(StringRef Name, uint32_t Size);
 
   void commitFpm(WritableBinaryStream &MsfBuffer, const msf::MSFLayout &Layout);
 
@@ -72,6 +73,7 @@ private:
 
   PDBStringTableBuilder Strings;
   NamedStreamMap NamedStreams;
+  DenseMap<uint32_t, std::string> NamedStreamData;
 };
 }
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp Fri Mar 23 11:43:39 2018
@@ -86,6 +86,15 @@ Error DebugStringTableSubsection::commit
 
 uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
 
+std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {
+  std::vector<uint32_t> Result;
+  Result.reserve(IdToString.size());
+  for (const auto &Entry : IdToString)
+    Result.push_back(Entry.first);
+  std::sort(Result.begin(), Result.end());
+  return Result;
+}
+
 uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
   auto Iter = StringToId.find(S);
   assert(Iter != StringToId.end());

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp Fri Mar 23 11:43:39 2018
@@ -27,7 +27,7 @@ using namespace llvm::pdb;
 DbiStreamBuilder::DbiStreamBuilder(msf::MSFBuilder &Msf)
     : Msf(Msf), Allocator(Msf.getAllocator()), Age(1), BuildNumber(0),
       PdbDllVersion(0), PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86),
-      Header(nullptr), DbgStreams((int)DbgHeaderType::Max) {}
+      Header(nullptr) {}
 
 DbiStreamBuilder::~DbiStreamBuilder() {}
 
@@ -63,15 +63,8 @@ void DbiStreamBuilder::setPublicsStreamI
 
 Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
                                      ArrayRef<uint8_t> Data) {
-  if (DbgStreams[(int)Type].StreamNumber != kInvalidStreamIndex)
-    return make_error<RawError>(raw_error_code::duplicate_entry,
-                                "The specified stream type already exists");
-  auto ExpectedIndex = Msf.addStream(Data.size());
-  if (!ExpectedIndex)
-    return ExpectedIndex.takeError();
-  uint32_t Index = std::move(*ExpectedIndex);
-  DbgStreams[(int)Type].Data = Data;
-  DbgStreams[(int)Type].StreamNumber = Index;
+  DbgStreams[(int)Type].emplace();
+  DbgStreams[(int)Type]->Data = Data;
   return Error::success();
 }
 
@@ -266,6 +259,15 @@ Error DbiStreamBuilder::finalize() {
 }
 
 Error DbiStreamBuilder::finalizeMsfLayout() {
+  for (auto &S : DbgStreams) {
+    if (!S.hasValue())
+      continue;
+    auto ExpectedIndex = Msf.addStream(S->Data.size());
+    if (!ExpectedIndex)
+      return ExpectedIndex.takeError();
+    S->StreamNumber = *ExpectedIndex;
+  }
+
   for (auto &MI : ModiList) {
     if (auto EC = MI->finalizeMsfLayout())
       return EC;
@@ -375,17 +377,23 @@ Error DbiStreamBuilder::commit(const msf
   if (auto EC = ECNamesBuilder.commit(Writer))
     return EC;
 
-  for (auto &Stream : DbgStreams)
-    if (auto EC = Writer.writeInteger(Stream.StreamNumber))
+  for (auto &Stream : DbgStreams) {
+    uint16_t StreamNumber = kInvalidStreamIndex;
+    if (Stream.hasValue())
+      StreamNumber = Stream->StreamNumber;
+    if (auto EC = Writer.writeInteger(StreamNumber))
       return EC;
+  }
 
   for (auto &Stream : DbgStreams) {
-    if (Stream.StreamNumber == kInvalidStreamIndex)
+    if (!Stream.hasValue())
       continue;
+    assert(Stream->StreamNumber != kInvalidStreamIndex);
+
     auto WritableStream = WritableMappedBlockStream::createIndexedStream(
-        Layout, MsfBuffer, Stream.StreamNumber, Allocator);
+        Layout, MsfBuffer, Stream->StreamNumber, Allocator);
     BinaryStreamWriter DbgStreamWriter(*WritableStream);
-    if (auto EC = DbgStreamWriter.writeArray(Stream.Data))
+    if (auto EC = DbgStreamWriter.writeArray(Stream->Data))
       return EC;
   }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp Fri Mar 23 11:43:39 2018
@@ -150,14 +150,14 @@ Error GSIStreamBuilder::finalizeMsfLayou
   PSH->finalizeBuckets(PSHZero);
   GSH->finalizeBuckets(GSHZero);
 
-  Expected<uint32_t> Idx = Msf.addStream(calculatePublicsHashStreamSize());
+  Expected<uint32_t> Idx = Msf.addStream(calculateGlobalsHashStreamSize());
   if (!Idx)
     return Idx.takeError();
-  PSH->StreamIndex = *Idx;
-  Idx = Msf.addStream(calculateGlobalsHashStreamSize());
+  GSH->StreamIndex = *Idx;
+  Idx = Msf.addStream(calculatePublicsHashStreamSize());
   if (!Idx)
     return Idx.takeError();
-  GSH->StreamIndex = *Idx;
+  PSH->StreamIndex = *Idx;
 
   uint32_t RecordBytes =
       GSH->calculateRecordByteSize() + PSH->calculateRecordByteSize();

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp Fri Mar 23 11:43:39 2018
@@ -73,5 +73,6 @@ Error InfoStreamBuilder::commit(const ms
     if (auto EC = Writer.writeEnum(E))
       return EC;
   }
+  assert(Writer.bytesRemaining() == 0);
   return Error::success();
 }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp Fri Mar 23 11:43:39 2018
@@ -47,7 +47,7 @@ uint32_t NamedStreamMapTraits::lookupKey
 }
 
 NamedStreamMap::NamedStreamMap()
-    : HashTraits(*this), OffsetIndexMap(HashTraits) {}
+    : HashTraits(*this), OffsetIndexMap(1, HashTraits) {}
 
 Error NamedStreamMap::load(BinaryStreamReader &Stream) {
   uint32_t StringBufferSize;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp Fri Mar 23 11:43:39 2018
@@ -80,11 +80,20 @@ GSIStreamBuilder &PDBFileBuilder::getGsi
   return *Gsi;
 }
 
-Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
+Expected<uint32_t> PDBFileBuilder::allocateNamedStream(StringRef Name,
+                                                       uint32_t Size) {
   auto ExpectedStream = Msf->addStream(Size);
-  if (!ExpectedStream)
-    return ExpectedStream.takeError();
-  NamedStreams.set(Name, *ExpectedStream);
+  if (ExpectedStream)
+    NamedStreams.set(Name, *ExpectedStream);
+  return ExpectedStream;
+}
+
+Error PDBFileBuilder::addNamedStream(StringRef Name, StringRef Data) {
+  Expected<uint32_t> ExpectedIndex = allocateNamedStream(Name, Data.size());
+  if (!ExpectedIndex)
+    return ExpectedIndex.takeError();
+  assert(NamedStreamData.count(*ExpectedIndex) == 0);
+  NamedStreamData[*ExpectedIndex] = Data;
   return Error::success();
 }
 
@@ -101,35 +110,41 @@ Expected<msf::MSFLayout> PDBFileBuilder:
 
   uint32_t StringsLen = Strings.calculateSerializedSize();
 
-  if (auto EC = addNamedStream("/names", StringsLen))
-    return std::move(EC);
-  if (auto EC = addNamedStream("/LinkInfo", 0))
-    return std::move(EC);
+  Expected<uint32_t> SN = allocateNamedStream("/LinkInfo", 0);
+  if (!SN)
+    return SN.takeError();
 
-  if (Info) {
-    if (auto EC = Info->finalizeMsfLayout())
-      return std::move(EC);
-  }
-  if (Dbi) {
-    if (auto EC = Dbi->finalizeMsfLayout())
+  if (Gsi) {
+    if (auto EC = Gsi->finalizeMsfLayout())
       return std::move(EC);
+    if (Dbi) {
+      Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex());
+      Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());
+      Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIdx());
+    }
   }
   if (Tpi) {
     if (auto EC = Tpi->finalizeMsfLayout())
       return std::move(EC);
   }
+  if (Dbi) {
+    if (auto EC = Dbi->finalizeMsfLayout())
+      return std::move(EC);
+  }
+  SN = allocateNamedStream("/names", StringsLen);
+  if (!SN)
+    return SN.takeError();
+
   if (Ipi) {
     if (auto EC = Ipi->finalizeMsfLayout())
       return std::move(EC);
   }
-  if (Gsi) {
-    if (auto EC = Gsi->finalizeMsfLayout())
+
+  // Do this last, since it relies on the named stream map being complete, and
+  // that can be updated by previous steps in the finalization.
+  if (Info) {
+    if (auto EC = Info->finalizeMsfLayout())
       return std::move(EC);
-    if (Dbi) {
-      Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex());
-      Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());
-      Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIdx());
-    }
   }
 
   return Msf->build();
@@ -219,6 +234,17 @@ Error PDBFileBuilder::commit(StringRef F
   if (auto EC = Strings.commit(NSWriter))
     return EC;
 
+  for (const auto &NSE : NamedStreamData) {
+    if (NSE.second.empty())
+      continue;
+
+    auto NS = WritableMappedBlockStream::createIndexedStream(
+        Layout, Buffer, NSE.first, Allocator);
+    BinaryStreamWriter NSW(*NS);
+    if (auto EC = NSW.writeBytes(arrayRefFromStringRef(NSE.second)))
+      return EC;
+  }
+
   if (Info) {
     if (auto EC = Info->commit(Layout, Buffer))
       return EC;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp Fri Mar 23 11:43:39 2018
@@ -15,6 +15,8 @@
 #include "llvm/Support/BinaryStreamWriter.h"
 #include "llvm/Support/Endian.h"
 
+#include <map>
+
 using namespace llvm;
 using namespace llvm::msf;
 using namespace llvm::support;
@@ -33,13 +35,66 @@ StringRef PDBStringTableBuilder::getStri
   return Strings.getStringForId(Id);
 }
 
+// This is a precomputed list of Buckets given the specified number of
+// strings.  Matching the reference algorithm exactly is not strictly
+// necessary for correctness, but it helps when comparing LLD's PDBs with
+// Microsoft's PDBs so as to eliminate superfluous differences.
+static std::map<uint32_t, uint32_t> StringsToBuckets = {
+    {1, 2},
+    {2, 4},
+    {4, 7},
+    {6, 11},
+    {9, 17},
+    {13, 26},
+    {20, 40},
+    {31, 61},
+    {46, 92},
+    {70, 139},
+    {105, 209},
+    {157, 314},
+    {236, 472},
+    {355, 709},
+    {532, 1064},
+    {799, 1597},
+    {1198, 2396},
+    {1798, 3595},
+    {2697, 5393},
+    {4045, 8090},
+    {6068, 12136},
+    {9103, 18205},
+    {13654, 27308},
+    {20482, 40963},
+    {30723, 61445},
+    {46084, 92168},
+    {69127, 138253},
+    {103690, 207380},
+    {155536, 311071},
+    {233304, 466607},
+    {349956, 699911},
+    {524934, 1049867},
+    {787401, 1574801},
+    {1181101, 2362202},
+    {1771652, 3543304},
+    {2657479, 5314957},
+    {3986218, 7972436},
+    {5979328, 11958655},
+    {8968992, 17937983},
+    {13453488, 26906975},
+    {20180232, 40360463},
+    {30270348, 60540695},
+    {45405522, 90811043},
+    {68108283, 136216565},
+    {102162424, 204324848},
+    {153243637, 306487273},
+    {229865455, 459730910},
+    {344798183, 689596366},
+    {517197275, 1034394550},
+    {775795913, 1551591826}};
+
 static uint32_t computeBucketCount(uint32_t NumStrings) {
-  // The /names stream is basically an on-disk open-addressing hash table.
-  // Hash collisions are resolved by linear probing. We cannot make
-  // utilization 100% because it will make the linear probing extremely
-  // slow. But lower utilization wastes disk space. As a reasonable
-  // load factor, we choose 80%. We need +1 because slot 0 is reserved.
-  return (NumStrings + 1) * 1.25;
+  auto Entry = StringsToBuckets.lower_bound(NumStrings);
+  assert(Entry != StringsToBuckets.end());
+  return Entry->second;
 }
 
 uint32_t PDBStringTableBuilder::calculateHashTableSize() const {

Modified: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp Fri Mar 23 11:43:39 2018
@@ -90,7 +90,13 @@ Error DumpOutputStyle::dump() {
     P.NewLine();
   }
 
-  if (opts::dump::DumpStringTable) {
+  if (opts::dump::DumpNamedStreams) {
+    if (auto EC = dumpNamedStreams())
+      return EC;
+    P.NewLine();
+  }
+
+  if (opts::dump::DumpStringTable || opts::dump::DumpStringTableDetails) {
     if (auto EC = dumpStringTable())
       return EC;
     P.NewLine();
@@ -857,33 +863,64 @@ Error DumpOutputStyle::dumpStringTableFr
     return Error::success();
   }
 
-  if (IS->name_ids().empty()) {
-    P.formatLine("Empty");
-    return Error::success();
-  }
-
-  auto MaxID = std::max_element(IS->name_ids().begin(), IS->name_ids().end());
-  uint32_t Digits = NumDigits(*MaxID);
+  if (opts::dump::DumpStringTable) {
+    if (IS->name_ids().empty())
+      P.formatLine("Empty");
+    else {
+      auto MaxID =
+          std::max_element(IS->name_ids().begin(), IS->name_ids().end());
+      uint32_t Digits = NumDigits(*MaxID);
+
+      P.formatLine("{0} | {1}", fmt_align("ID", AlignStyle::Right, Digits),
+                   "String");
+
+      std::vector<uint32_t> SortedIDs(IS->name_ids().begin(),
+                                      IS->name_ids().end());
+      std::sort(SortedIDs.begin(), SortedIDs.end());
+      for (uint32_t I : SortedIDs) {
+        auto ES = IS->getStringForID(I);
+        llvm::SmallString<32> Str;
+        if (!ES) {
+          consumeError(ES.takeError());
+          Str = "Error reading string";
+        } else if (!ES->empty()) {
+          Str.append("'");
+          Str.append(*ES);
+          Str.append("'");
+        }
 
-  P.formatLine("{0} | {1}", fmt_align("ID", AlignStyle::Right, Digits),
-               "String");
+        if (!Str.empty())
+          P.formatLine("{0} | {1}", fmt_align(I, AlignStyle::Right, Digits),
+                       Str);
+      }
+    }
+  }
 
-  std::vector<uint32_t> SortedIDs(IS->name_ids().begin(), IS->name_ids().end());
-  std::sort(SortedIDs.begin(), SortedIDs.end());
-  for (uint32_t I : SortedIDs) {
-    auto ES = IS->getStringForID(I);
-    llvm::SmallString<32> Str;
-    if (!ES) {
-      consumeError(ES.takeError());
-      Str = "Error reading string";
-    } else if (!ES->empty()) {
-      Str.append("'");
-      Str.append(*ES);
-      Str.append("'");
+  if (opts::dump::DumpStringTableDetails) {
+    P.NewLine();
+    {
+      P.printLine("String Table Header:");
+      AutoIndent Indent(P);
+      P.formatLine("Signature: {0}", IS->getSignature());
+      P.formatLine("Hash Version: {0}", IS->getHashVersion());
+      P.formatLine("Name Buffer Size: {0}", IS->getByteSize());
+      P.NewLine();
     }
 
-    if (!Str.empty())
-      P.formatLine("{0} | {1}", fmt_align(I, AlignStyle::Right, Digits), Str);
+    BinaryStreamRef NameBuffer = IS->getStringTable().getBuffer();
+    ArrayRef<uint8_t> Contents;
+    cantFail(NameBuffer.readBytes(0, NameBuffer.getLength(), Contents));
+    P.formatBinary("Name Buffer", Contents, 0);
+    P.NewLine();
+    {
+      P.printLine("Hash Table:");
+      AutoIndent Indent(P);
+      P.formatLine("Bucket Count: {0}", IS->name_ids().size());
+      for (const auto &Entry : enumerate(IS->name_ids()))
+        P.formatLine("Bucket[{0}] : {1}", Entry.index(),
+                     uint32_t(Entry.value()));
+      P.formatLine("Name Count: {0}", IS->getNameCount());
+    }
   }
   return Error::success();
 }
@@ -909,6 +946,29 @@ Error DumpOutputStyle::dumpStringTableFr
   return Error::success();
 }
 
+Error DumpOutputStyle::dumpNamedStreams() {
+  printHeader(P, "Named Streams");
+  AutoIndent Indent(P, 2);
+
+  if (File.isObj()) {
+    P.formatLine("Dumping Named Streams is only supported for PDB files.");
+    return Error::success();
+  }
+  ExitOnError Err("Invalid PDB File: ");
+
+  auto &IS = Err(File.pdb().getPDBInfoStream());
+  const NamedStreamMap &NS = IS.getNamedStreams();
+  for (const auto &Entry : NS.entries()) {
+    P.printLine(Entry.getKey());
+    AutoIndent Indent2(P, 2);
+    P.formatLine("Index: {0}", Entry.getValue());
+    P.formatLine("Size in bytes: {0}",
+                 File.pdb().getStreamByteSize(Entry.getValue()));
+  }
+
+  return Error::success();
+}
+
 Error DumpOutputStyle::dumpStringTable() {
   printHeader(P, "String Table");
 

Modified: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h?rev=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h Fri Mar 23 11:43:39 2018
@@ -74,6 +74,7 @@ private:
   Error dumpStreamSummary();
   Error dumpSymbolStats();
   Error dumpUdtStats();
+  Error dumpNamedStreams();
   Error dumpStringTable();
   Error dumpStringTableFromPdb();
   Error dumpStringTableFromObj();

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=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Fri Mar 23 11:43:39 2018
@@ -534,8 +534,16 @@ cl::opt<bool> JustMyCode("jmc", cl::Opti
                          cl::cat(FileOptions), cl::sub(DumpSubcommand));
 
 // MISCELLANEOUS OPTIONS
+cl::opt<bool> DumpNamedStreams("named-streams",
+                               cl::desc("dump PDB named stream table"),
+                               cl::cat(MiscOptions), cl::sub(DumpSubcommand));
+
 cl::opt<bool> DumpStringTable("string-table", cl::desc("dump PDB String Table"),
                               cl::cat(MiscOptions), cl::sub(DumpSubcommand));
+cl::opt<bool> DumpStringTableDetails("string-table-details",
+                                     cl::desc("dump PDB String Table Details"),
+                                     cl::cat(MiscOptions),
+                                     cl::sub(DumpSubcommand));
 
 cl::opt<bool> DumpSectionContribs("section-contribs",
                                   cl::desc("dump section contributions"),
@@ -1199,6 +1207,7 @@ int main(int argc_, const char *argv_[])
       opts::dump::DumpStreams = true;
       opts::dump::DumpStreamBlocks = true;
       opts::dump::DumpStringTable = true;
+      opts::dump::DumpStringTableDetails = true;
       opts::dump::DumpSummary = true;
       opts::dump::DumpSymbols = true;
       opts::dump::DumpSymbolStats = true;

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=328348&r1=328347&r2=328348&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Fri Mar 23 11:43:39 2018
@@ -142,7 +142,9 @@ extern llvm::cl::opt<bool> DumpLines;
 extern llvm::cl::opt<bool> DumpInlineeLines;
 extern llvm::cl::opt<bool> DumpXmi;
 extern llvm::cl::opt<bool> DumpXme;
+extern llvm::cl::opt<bool> DumpNamedStreams;
 extern llvm::cl::opt<bool> DumpStringTable;
+extern llvm::cl::opt<bool> DumpStringTableDetails;
 extern llvm::cl::opt<bool> DumpTypes;
 extern llvm::cl::opt<bool> DumpTypeData;
 extern llvm::cl::opt<bool> DumpTypeExtras;




More information about the llvm-commits mailing list