[pdb] Write the Named Stream mapping to Yaml and binary.
authorZachary Turner <zturner@google.com>
Fri, 20 Jan 2017 22:42:09 +0000 (22:42 +0000)
committerZachary Turner <zturner@google.com>
Fri, 20 Jan 2017 22:42:09 +0000 (22:42 +0000)
Differential Revision: https://reviews.llvm.org/D28919

llvm-svn: 292665

22 files changed:
lld/COFF/PDB.cpp
llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h
llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
llvm/include/llvm/DebugInfo/PDB/Raw/StringTableBuilder.h
llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp
llvm/test/DebugInfo/PDB/pdbdump-headers.test
llvm/test/DebugInfo/PDB/pdbdump-readwrite.test
llvm/test/DebugInfo/PDB/pdbdump-write.test
llvm/test/DebugInfo/PDB/pdbdump-yaml.test
llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
llvm/tools/llvm-pdbdump/PdbYaml.cpp
llvm/tools/llvm-pdbdump/PdbYaml.h
llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
llvm/tools/llvm-pdbdump/llvm-pdbdump.h
llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp

index 923fc64..b76dc22 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
+#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
 #include "llvm/Object/COFF.h"
index 11c7715..99109ad 100644 (file)
@@ -37,6 +37,8 @@ public:
   uint32_t getAge() const;
   PDB_UniqueId getGuid() const;
 
+  const NamedStreamMap &getNamedStreams() const;
+
   uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
   iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
 
index 1992492..768de09 100644 (file)
@@ -25,10 +25,11 @@ class StreamWriter;
 }
 namespace pdb {
 class PDBFile;
+class NamedStreamMap;
 
 class InfoStreamBuilder {
 public:
-  InfoStreamBuilder(msf::MSFBuilder &Msf);
+  InfoStreamBuilder(msf::MSFBuilder &Msf, NamedStreamMap &NamedStreams);
   InfoStreamBuilder(const InfoStreamBuilder &) = delete;
   InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
 
@@ -37,8 +38,6 @@ public:
   void setAge(uint32_t A);
   void setGuid(PDB_UniqueId G);
 
-  NamedStreamMap &getNamedStreamsBuilder();
-
   uint32_t finalize();
 
   Error finalizeMsfLayout();
@@ -54,7 +53,7 @@ private:
   uint32_t Age;
   PDB_UniqueId Guid;
 
-  NamedStreamMap NamedStreams;
+  NamedStreamMap &NamedStreams;
 };
 }
 }
index 27fc4b5..bc48b54 100644 (file)
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/PDB/Raw/NamedStreamMap.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
@@ -44,11 +46,13 @@ public:
   DbiStreamBuilder &getDbiBuilder();
   TpiStreamBuilder &getTpiBuilder();
   TpiStreamBuilder &getIpiBuilder();
+  StringTableBuilder &getStringTableBuilder();
 
   Error commit(StringRef Filename);
 
 private:
-  Expected<msf::MSFLayout> finalizeMsfLayout() const;
+  Error addNamedStream(StringRef Name, uint32_t Size);
+  Expected<msf::MSFLayout> finalizeMsfLayout();
 
   BumpPtrAllocator &Allocator;
 
@@ -57,6 +61,9 @@ private:
   std::unique_ptr<DbiStreamBuilder> Dbi;
   std::unique_ptr<TpiStreamBuilder> Tpi;
   std::unique_ptr<TpiStreamBuilder> Ipi;
+
+  StringTableBuilder Strings;
+  NamedStreamMap NamedStreams;
 };
 }
 }
index d16ac2c..d6a2083 100644 (file)
@@ -31,7 +31,7 @@ public:
   // Returns the ID for S.
   uint32_t insert(StringRef S);
 
-  uint32_t calculateSerializedLength() const;
+  uint32_t finalize();
   Error commit(msf::StreamWriter &Writer) const;
 
 private:
index 9334d2a..9abcfbf 100644 (file)
@@ -75,3 +75,7 @@ uint32_t InfoStream::getSignature() const { return Signature; }
 uint32_t InfoStream::getAge() const { return Age; }
 
 PDB_UniqueId InfoStream::getGuid() const { return Guid; }
+
+const NamedStreamMap &InfoStream::getNamedStreams() const {
+  return NamedStreams;
+}
index 4485c83..4d8eb85 100644 (file)
@@ -13,6 +13,8 @@
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/MSF/StreamWriter.h"
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Raw/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
 
@@ -21,8 +23,10 @@ using namespace llvm::codeview;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
-InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf)
-    : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0) {}
+InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
+                                     NamedStreamMap &NamedStreams)
+    : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0),
+      NamedStreams(NamedStreams) {}
 
 void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
 
@@ -32,10 +36,6 @@ void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
 
 void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
 
-NamedStreamMap &InfoStreamBuilder::getNamedStreamsBuilder() {
-  return NamedStreams;
-}
-
 Error InfoStreamBuilder::finalizeMsfLayout() {
   uint32_t Length = sizeof(InfoStreamHeader) + NamedStreams.finalize();
   if (auto EC = Msf.setStreamSize(StreamPDB, Length))
index 6fec0e3..cfd5ba6 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
 
@@ -44,7 +45,7 @@ MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
 
 InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
   if (!Info)
-    Info = llvm::make_unique<InfoStreamBuilder>(*Msf);
+    Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
   return *Info;
 }
 
@@ -66,7 +67,26 @@ TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
   return *Ipi;
 }
 
-Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
+StringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; }
+
+Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
+  auto ExpectedStream = Msf->addStream(Size);
+  if (!ExpectedStream)
+    return ExpectedStream.takeError();
+  NamedStreams.set(Name, *ExpectedStream);
+  return Error::success();
+}
+
+Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
+  uint32_t StringTableSize = Strings.finalize();
+
+  if (auto EC = addNamedStream("/names", StringTableSize))
+    return std::move(EC);
+  if (auto EC = addNamedStream("/LinkInfo", 0))
+    return std::move(EC);
+  if (auto EC = addNamedStream("/src/headerblock", 0))
+    return std::move(EC);
+
   if (Info) {
     if (auto EC = Info->finalizeMsfLayout())
       return std::move(EC);
@@ -124,6 +144,16 @@ Error PDBFileBuilder::commit(StringRef Filename) {
       return EC;
   }
 
+  uint32_t StringTableStreamNo = 0;
+  if (!NamedStreams.get("/names", StringTableStreamNo))
+    return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
+
+  auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
+                                                           StringTableStreamNo);
+  StreamWriter NSWriter(*NS);
+  if (auto EC = Strings.commit(NSWriter))
+    return EC;
+
   if (Info) {
     if (auto EC = Info->commit(Layout, Buffer))
       return EC;
index 7284582..5ae7447 100644 (file)
@@ -38,16 +38,17 @@ static uint32_t computeBucketCount(uint32_t NumStrings) {
   return (NumStrings + 1) * 1.25;
 }
 
-uint32_t StringTableBuilder::calculateSerializedLength() const {
+uint32_t StringTableBuilder::finalize() {
   uint32_t Size = 0;
   Size += sizeof(StringTableHeader);
   Size += StringSize;
-  Size += 4; // Hash table begins with 4-byte size field.
+  Size += sizeof(uint32_t); // Hash table begins with 4-byte size field.
 
   uint32_t BucketCount = computeBucketCount(Strings.size());
-  Size += BucketCount * 4;
+  Size += BucketCount * sizeof(uint32_t);
 
-  Size += 4; // The /names stream ends with the number of strings.
+  Size +=
+      sizeof(uint32_t); // The /names stream ends with the number of strings.
   return Size;
 }
 
index edbaedb..565d311 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llvm-pdbdump raw -headers -tpi-records -tpi-record-bytes -module-syms \
+; RUN: llvm-pdbdump raw -headers -string-table -tpi-records -tpi-record-bytes -module-syms \
 ; RUN:              -sym-record-bytes -globals -publics -module-files \
 ; RUN:              -stream-summary -stream-blocks -ipi-records -ipi-record-bytes \
 ; RUN:              -section-contribs -section-map -section-headers -line-info \
 ; EMPTY-NEXT:   Stream 15: [21]
 ; EMPTY-NEXT:   Stream 16: [22]
 ; EMPTY-NEXT: ]
+; EMPTY-NEXT: String Table {
+; EMPTY-NEXT:   'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
+; EMPTY-NEXT:   'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
+; EMPTY-NEXT:   '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
+; EMPTY-NEXT: }
 ; EMPTY-NEXT: PDB Stream {
 ; EMPTY-NEXT:   Version: 20000404
 ; EMPTY-NEXT:   Signature: 0x54E507E2
 ; EMPTY-NEXT:   Age: 1
 ; EMPTY-NEXT:   Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
+; EMPTY-NEXT:   Named Streams {
+; EMPTY-NEXT:     /names: 13
+; EMPTY-NEXT:     /LinkInfo: 5
+; EMPTY-NEXT:     /src/headerblock: 9
+; EMPTY-NEXT:   }
 ; EMPTY-NEXT: }
 ; EMPTY-NEXT: Type Info Stream (TPI) {
 ; EMPTY-NEXT:   TPI Version: 20040203
 ; BIG-NEXT:   Signature: 0x571FFE67
 ; BIG-NEXT:   Age: 1
 ; BIG-NEXT:   Guid: {880ECC89-DF81-0B4F-839C-58CBD052E937}
+; BIG-NEXT:   Named Streams {
+; BIG-NEXT:     /names: 13
+; BIG-NEXT:     /LinkInfo: 5
+; BIG-NEXT:     /src/headerblock: 61
+; BIG-NEXT:   }
 ; BIG-NEXT: }
 ; BIG-NEXT: DBI Stream {
 ; BIG-NEXT:   Dbi Version: 19990903
index b2f1deb..780612a 100644 (file)
@@ -1,10 +1,10 @@
 RUN: llvm-pdbdump pdb2yaml -dbi-module-info -dbi-module-source-info \
-RUN:   -dbi-stream -pdb-stream -tpi-stream -stream-directory \
+RUN:   -dbi-stream -pdb-stream -string-table -tpi-stream -stream-directory \
 RUN:   -stream-metadata %p/Inputs/empty.pdb > %t.1
 RUN: llvm-pdbdump yaml2pdb -pdb=%t.2 %t.1
 
-RUN: llvm-pdbdump raw -headers -tpi-records %p/Inputs/empty.pdb | FileCheck %s
-RUN: llvm-pdbdump raw -headers -tpi-records %t.2 | FileCheck %s
+RUN: llvm-pdbdump raw -headers -string-table -tpi-records %p/Inputs/empty.pdb | FileCheck %s
+RUN: llvm-pdbdump raw -headers -string-table -tpi-records %t.2 | FileCheck %s
 
 CHECK:      FileHeaders {
 CHECK-NEXT:   BlockSize: 4096
@@ -17,11 +17,19 @@ CHECK-NEXT:   NumDirectoryBlocks: 1
 CHECK-NEXT:   DirectoryBlocks:
 CHECK-NEXT:   NumStreams:
 CHECK-NEXT: }
+CHECK:      String Table {
+CHECK-DAG:   'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
+CHECK-DAG:   'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
+CHECK-DAG:   '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
+CHECK-NEXT: }
 CHECK:      PDB Stream {
 CHECK-NEXT:   Version: 20000404
 CHECK-NEXT:   Signature: 0x54E507E2
 CHECK-NEXT:   Age: 1
 CHECK-NEXT:   Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
+CHECK-NEXT:   Named Streams {
+CHECK:          /names: 
+CHECK:        }
 CHECK-NEXT: }
 CHECK:      Type Info Stream (TPI) {
 CHECK-NEXT:   TPI Version: 20040203
index 6e29bdb..f56b4fb 100644 (file)
 ; stream metadata, since the layout of the MSF file might be different
 ; (for example if we don't write the entire stream)
 ;
-; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream -tpi-stream %p/Inputs/empty.pdb > %t.1
+; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory \
+; RUN:   -pdb-stream -tpi-stream %p/Inputs/empty.pdb > %t.1
 ; RUN: llvm-pdbdump yaml2pdb -pdb=%t.2 %t.1
-; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream -no-file-headers %p/Inputs/empty.pdb > %t.3
-; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream -no-file-headers %t.2 > %t.4
+; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream \
+; RUN:   -no-file-headers %p/Inputs/empty.pdb > %t.3
+; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream \
+; RUN:   -no-file-headers %t.2 > %t.4
 ; RUN: diff %t.3 %t.4
index 7d0c429..e4cb5f5 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream %p/Inputs/empty.pdb \
-; RUN:   | FileCheck -check-prefix=YAML %s
+; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -string-table -pdb-stream \
+; RUN: %p/Inputs/empty.pdb | FileCheck -check-prefix=YAML %s
 ; RUN: llvm-pdbdump pdb2yaml -no-file-headers -stream-metadata -stream-directory -pdb-stream \
 ; RUN:   %p/Inputs/empty.pdb | FileCheck -check-prefix=NO-HEADERS %s
 
 ; YAML-NEXT:   - Stream: [ 7 ]
 ; YAML-NEXT:   - Stream: [ 21 ]
 ; YAML-NEXT:   - Stream: [ 22 ]
+; YAML-NEXT: StringTable:
+; YAML-NEXT:   - 'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
+; YAML-NEXT:   - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
+; YAML-NEXT:   - '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
 ; YAML-NEXT: PdbStream:
 ; YAML-NEXT:   Age:             1
 ; YAML-NEXT:   Guid:            '{0B355641-86A0-A249-896F-9988FAE52FF0}'
 ; YAML-NEXT:   Signature:       1424295906
 ; YAML-NEXT:   Version:         VC70
-; YAML-NEXT:     NamedStreams:
-; YAML-NEXT:       - Name:            /names
-; YAML-NEXT:         StreamNum:       13
-; YAML-NEXT:       - Name:            /LinkInfo
-; YAML-NEXT:         StreamNum:       5
-; YAML-NEXT:       - Name:            /src/headerblock
-; YAML-NEXT:         StreamNum:       9
 ; YAML-NEXT: ...
 
 ; NO-HEADERS: ---
index f3508d6..62c6fb4 100644 (file)
@@ -113,6 +113,9 @@ Error LLVMOutputStyle::dump() {
   if (auto EC = dumpStreamBytes())
     return EC;
 
+  if (auto EC = dumpStringTable())
+    return EC;
+
   if (auto EC = dumpInfoStream())
     return EC;
 
@@ -456,6 +459,28 @@ Error LLVMOutputStyle::dumpStreamBytes() {
   return Error::success();
 }
 
+Error LLVMOutputStyle::dumpStringTable() {
+  if (!opts::raw::DumpStringTable)
+    return Error::success();
+
+  auto IS = File.getStringTable();
+  if (!IS)
+    return IS.takeError();
+
+  DictScope D(P, "String Table");
+  for (uint32_t I : IS->name_ids()) {
+    StringRef S = IS->getStringForID(I);
+    if (!S.empty()) {
+      llvm::SmallString<32> Str;
+      Str.append("'");
+      Str.append(S);
+      Str.append("'");
+      P.printString(Str);
+    }
+  }
+  return Error::success();
+}
+
 Error LLVMOutputStyle::dumpInfoStream() {
   if (!opts::raw::DumpHeaders)
     return Error::success();
@@ -472,6 +497,11 @@ Error LLVMOutputStyle::dumpInfoStream() {
   P.printHex("Signature", IS->getSignature());
   P.printNumber("Age", IS->getAge());
   P.printObject("Guid", IS->getGuid());
+  {
+    DictScope DD(P, "Named Streams");
+    for (const auto &S : IS->getNamedStreams().entries())
+      P.printObject(S.getKey(), S.getValue());
+  }
   return Error::success();
 }
 
index 816d591..4aef78d 100644 (file)
@@ -34,6 +34,7 @@ private:
   Error dumpGlobalsStream();
   Error dumpStreamBytes();
   Error dumpStreamBlocks();
+  Error dumpStringTable();
   Error dumpInfoStream();
   Error dumpTpiStream(uint32_t StreamIdx);
   Error dumpDbiStream();
index 34e0611..6a32080 100644 (file)
@@ -140,6 +140,7 @@ void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
   IO.mapOptional("MSF", Obj.Headers);
   IO.mapOptional("StreamSizes", Obj.StreamSizes);
   IO.mapOptional("StreamMap", Obj.StreamMap);
+  IO.mapOptional("StringTable", Obj.StringTable);
   IO.mapOptional("PdbStream", Obj.PdbStream);
   IO.mapOptional("DbiStream", Obj.DbiStream);
   IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Obj.Allocator);
@@ -176,7 +177,6 @@ void MappingTraits<PdbInfoStream>::mapping(IO &IO, PdbInfoStream &Obj) {
   IO.mapRequired("Guid", Obj.Guid);
   IO.mapRequired("Signature", Obj.Signature);
   IO.mapRequired("Version", Obj.Version);
-  IO.mapRequired("NamedStreams", Obj.NamedStreams);
 }
 
 void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
index 398186f..4bb9e89 100644 (file)
@@ -107,6 +107,8 @@ struct PdbObject {
   Optional<PdbTpiStream> TpiStream;
   Optional<PdbTpiStream> IpiStream;
 
+  Optional<std::vector<StringRef>> StringTable;
+
   BumpPtrAllocator &Allocator;
 };
 }
index 3f2733d..f7ad328 100644 (file)
@@ -45,6 +45,9 @@ Error YAMLOutputStyle::dump() {
   if (auto EC = dumpStreamDirectory())
     return EC;
 
+  if (auto EC = dumpStringTable())
+    return EC;
+
   if (auto EC = dumpPDBStream())
     return EC;
 
@@ -83,6 +86,24 @@ Error YAMLOutputStyle::dumpFileHeaders() {
   return Error::success();
 }
 
+Error YAMLOutputStyle::dumpStringTable() {
+  if (!opts::pdb2yaml::StringTable)
+    return Error::success();
+
+  Obj.StringTable.emplace();
+  auto ExpectedST = File.getStringTable();
+  if (!ExpectedST)
+    return ExpectedST.takeError();
+
+  const auto &ST = ExpectedST.get();
+  for (auto ID : ST.name_ids()) {
+    StringRef S = ST.getStringForID(ID);
+    if (!S.empty())
+      Obj.StringTable->push_back(S);
+  }
+  return Error::success();
+}
+
 Error YAMLOutputStyle::dumpStreamMetadata() {
   if (!opts::pdb2yaml::StreamMetadata)
     return Error::success();
@@ -122,12 +143,6 @@ Error YAMLOutputStyle::dumpPDBStream() {
   Obj.PdbStream->Guid = InfoS.getGuid();
   Obj.PdbStream->Signature = InfoS.getSignature();
   Obj.PdbStream->Version = InfoS.getVersion();
-  for (auto &NS : InfoS.named_streams()) {
-    yaml::NamedStreamMapping Mapping;
-    Mapping.StreamName = NS.getKey();
-    Mapping.StreamNumber = NS.getValue();
-    Obj.PdbStream->NamedStreams.push_back(Mapping);
-  }
 
   return Error::success();
 }
index 3cd603a..db9868d 100644 (file)
@@ -26,6 +26,7 @@ public:
   Error dump() override;
 
 private:
+  Error dumpStringTable();
   Error dumpFileHeaders();
   Error dumpStreamMetadata();
   Error dumpStreamDirectory();
index 762af6d..ccab7fe 100644 (file)
@@ -50,6 +50,7 @@
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/RawSession.h"
+#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
 #include "llvm/Support/COM.h"
@@ -232,6 +233,9 @@ cl::opt<bool>
                        cl::cat(SymbolOptions), cl::sub(RawSubcommand));
 
 // MISCELLANEOUS OPTIONS
+cl::opt<bool> DumpStringTable("string-table", cl::desc("dump PDB String Table"),
+                              cl::cat(MiscOptions), cl::sub(RawSubcommand));
+
 cl::opt<bool> DumpSectionContribs("section-contribs",
                                   cl::desc("dump section contributions"),
                                   cl::cat(MiscOptions), cl::sub(RawSubcommand));
@@ -279,6 +283,10 @@ cl::opt<bool> StreamDirectory(
 cl::opt<bool> PdbStream("pdb-stream",
                         cl::desc("Dump the PDB Stream (Stream 1)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
+
+cl::opt<bool> StringTable("string-table", cl::desc("Dump the PDB String Table"),
+                          cl::sub(PdbToYamlSubcommand), cl::init(false));
+
 cl::opt<bool> DbiStream("dbi-stream",
                         cl::desc("Dump the DBI Stream (Stream 2)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
@@ -345,14 +353,18 @@ static void yamlToPdb(StringRef Path) {
   for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
     ExitOnErr(Builder.getMsfBuilder().addStream(0));
 
+  if (YamlObj.StringTable.hasValue()) {
+    auto &Strings = Builder.getStringTableBuilder();
+    for (auto S : *YamlObj.StringTable)
+      Strings.insert(S);
+  }
+
   if (YamlObj.PdbStream.hasValue()) {
     auto &InfoBuilder = Builder.getInfoBuilder();
     InfoBuilder.setAge(YamlObj.PdbStream->Age);
     InfoBuilder.setGuid(YamlObj.PdbStream->Guid);
     InfoBuilder.setSignature(YamlObj.PdbStream->Signature);
     InfoBuilder.setVersion(YamlObj.PdbStream->Version);
-    for (auto &NM : YamlObj.PdbStream->NamedStreams)
-      InfoBuilder.getNamedStreamsBuilder().set(NM.StreamName, NM.StreamNumber);
   }
 
   if (YamlObj.DbiStream.hasValue()) {
@@ -579,6 +591,7 @@ int main(int argc_, const char *argv_[]) {
       opts::raw::DumpSectionContribs = true;
       opts::raw::DumpLineInfo = true;
       opts::raw::DumpFpo = true;
+      opts::raw::DumpStringTable = true;
     }
 
     if (opts::raw::CompactRecords &&
index 869ebf2..d4f082c 100644 (file)
@@ -64,12 +64,14 @@ extern llvm::cl::opt<bool> DumpSectionMap;
 extern llvm::cl::opt<bool> DumpSymRecordBytes;
 extern llvm::cl::opt<bool> DumpSectionHeaders;
 extern llvm::cl::opt<bool> DumpFpo;
+extern llvm::cl::opt<bool> DumpStringTable;
 }
 
 namespace pdb2yaml {
 extern llvm::cl::opt<bool> NoFileHeaders;
 extern llvm::cl::opt<bool> StreamMetadata;
 extern llvm::cl::opt<bool> StreamDirectory;
+extern llvm::cl::opt<bool> StringTable;
 extern llvm::cl::opt<bool> PdbStream;
 extern llvm::cl::opt<bool> DbiStream;
 extern llvm::cl::opt<bool> DbiModuleInfo;
index aa4ab66..653acf7 100644 (file)
@@ -32,7 +32,7 @@ TEST_F(StringTableBuilderTest, Simple) {
   EXPECT_EQ(1U, Builder.insert("foo"));
   EXPECT_EQ(9U, Builder.insert("baz"));
 
-  std::vector<uint8_t> Buffer(Builder.calculateSerializedLength());
+  std::vector<uint8_t> Buffer(Builder.finalize());
   msf::MutableByteStream OutStream(Buffer);
   msf::StreamWriter Writer(OutStream);
   EXPECT_NO_ERROR(Builder.commit(Writer));