Index: lld/COFF/PDB.cpp =================================================================== --- lld/COFF/PDB.cpp +++ lld/COFF/PDB.cpp @@ -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: llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h +++ llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h @@ -37,6 +37,8 @@ uint32_t getAge() const; PDB_UniqueId getGuid() const; + const NamedStreamMap &getNamedStreams() const; + uint32_t getNamedStreamIndex(llvm::StringRef Name) const; iterator_range> named_streams() const; Index: llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h +++ llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h @@ -25,10 +25,11 @@ } 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 @@ void setAge(uint32_t A); void setGuid(PDB_UniqueId G); - NamedStreamMap &getNamedStreamsBuilder(); - uint32_t finalize(); Error finalizeMsfLayout(); @@ -54,7 +53,7 @@ uint32_t Age; PDB_UniqueId Guid; - NamedStreamMap NamedStreams; + NamedStreamMap &NamedStreams; }; } } Index: llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h +++ llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h @@ -13,8 +13,10 @@ #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 @@ DbiStreamBuilder &getDbiBuilder(); TpiStreamBuilder &getTpiBuilder(); TpiStreamBuilder &getIpiBuilder(); + StringTableBuilder &getStringTableBuilder(); Error commit(StringRef Filename); private: - Expected finalizeMsfLayout() const; + Error addNamedStream(StringRef Name, uint32_t Size); + Expected finalizeMsfLayout(); BumpPtrAllocator &Allocator; @@ -57,6 +61,9 @@ std::unique_ptr Dbi; std::unique_ptr Tpi; std::unique_ptr Ipi; + + StringTableBuilder Strings; + NamedStreamMap NamedStreams; }; } } Index: llvm/include/llvm/DebugInfo/PDB/Raw/StringTableBuilder.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Raw/StringTableBuilder.h +++ llvm/include/llvm/DebugInfo/PDB/Raw/StringTableBuilder.h @@ -31,7 +31,7 @@ // 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: llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp +++ llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp @@ -75,3 +75,7 @@ uint32_t InfoStream::getAge() const { return Age; } PDB_UniqueId InfoStream::getGuid() const { return Guid; } + +const NamedStreamMap &InfoStream::getNamedStreams() const { + return NamedStreams; +} Index: llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp +++ llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp @@ -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::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::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: llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp +++ llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp @@ -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 @@ InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() { if (!Info) - Info = llvm::make_unique(*Msf); + Info = llvm::make_unique(*Msf, NamedStreams); return *Info; } @@ -66,7 +67,26 @@ return *Ipi; } -Expected 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 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 @@ return EC; } + uint32_t StringTableStreamNo = 0; + if (!NamedStreams.get("/names", StringTableStreamNo)) + return llvm::make_error(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: llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp +++ llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp @@ -38,16 +38,17 @@ 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: llvm/test/DebugInfo/PDB/pdbdump-headers.test =================================================================== --- llvm/test/DebugInfo/PDB/pdbdump-headers.test +++ llvm/test/DebugInfo/PDB/pdbdump-headers.test @@ -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 \ @@ -61,11 +61,21 @@ ; 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 @@ -1692,6 +1702,11 @@ ; 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: llvm/test/DebugInfo/PDB/pdbdump-readwrite.test =================================================================== --- llvm/test/DebugInfo/PDB/pdbdump-readwrite.test +++ llvm/test/DebugInfo/PDB/pdbdump-readwrite.test @@ -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: 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: llvm/test/DebugInfo/PDB/pdbdump-write.test =================================================================== --- llvm/test/DebugInfo/PDB/pdbdump-write.test +++ llvm/test/DebugInfo/PDB/pdbdump-write.test @@ -10,8 +10,11 @@ ; 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: llvm/test/DebugInfo/PDB/pdbdump-yaml.test =================================================================== --- llvm/test/DebugInfo/PDB/pdbdump-yaml.test +++ llvm/test/DebugInfo/PDB/pdbdump-yaml.test @@ -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 @@ -36,21 +36,18 @@ ; 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: --- ; NO-HEADERS-NOT: MSF: ; NO-HEADERS-NOT: SuperBlock: ; NO-HEADERS: ... \ No newline at end of file Index: llvm/tools/llvm-pdbdump/LLVMOutputStyle.h =================================================================== --- llvm/tools/llvm-pdbdump/LLVMOutputStyle.h +++ llvm/tools/llvm-pdbdump/LLVMOutputStyle.h @@ -34,6 +34,7 @@ Error dumpGlobalsStream(); Error dumpStreamBytes(); Error dumpStreamBlocks(); + Error dumpStringTable(); Error dumpInfoStream(); Error dumpTpiStream(uint32_t StreamIdx); Error dumpDbiStream(); Index: llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp =================================================================== --- llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -113,6 +113,9 @@ if (auto EC = dumpStreamBytes()) return EC; + if (auto EC = dumpStringTable()) + return EC; + if (auto EC = dumpInfoStream()) return EC; @@ -456,6 +459,28 @@ 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 @@ 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: llvm/tools/llvm-pdbdump/PdbYaml.h =================================================================== --- llvm/tools/llvm-pdbdump/PdbYaml.h +++ llvm/tools/llvm-pdbdump/PdbYaml.h @@ -107,6 +107,8 @@ Optional TpiStream; Optional IpiStream; + Optional> StringTable; + BumpPtrAllocator &Allocator; }; } Index: llvm/tools/llvm-pdbdump/PdbYaml.cpp =================================================================== --- llvm/tools/llvm-pdbdump/PdbYaml.cpp +++ llvm/tools/llvm-pdbdump/PdbYaml.cpp @@ -140,6 +140,7 @@ 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 @@ IO.mapRequired("Guid", Obj.Guid); IO.mapRequired("Signature", Obj.Signature); IO.mapRequired("Version", Obj.Version); - IO.mapRequired("NamedStreams", Obj.NamedStreams); } void MappingTraits::mapping(IO &IO, PdbDbiStream &Obj) { Index: llvm/tools/llvm-pdbdump/YAMLOutputStyle.h =================================================================== --- llvm/tools/llvm-pdbdump/YAMLOutputStyle.h +++ llvm/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -26,6 +26,7 @@ Error dump() override; private: + Error dumpStringTable(); Error dumpFileHeaders(); Error dumpStreamMetadata(); Error dumpStreamDirectory(); Index: llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp =================================================================== --- llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -45,6 +45,9 @@ if (auto EC = dumpStreamDirectory()) return EC; + if (auto EC = dumpStringTable()) + return EC; + if (auto EC = dumpPDBStream()) return EC; @@ -83,6 +86,24 @@ 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 @@ 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: llvm/tools/llvm-pdbdump/llvm-pdbdump.h =================================================================== --- llvm/tools/llvm-pdbdump/llvm-pdbdump.h +++ llvm/tools/llvm-pdbdump/llvm-pdbdump.h @@ -64,12 +64,14 @@ extern llvm::cl::opt DumpSymRecordBytes; extern llvm::cl::opt DumpSectionHeaders; extern llvm::cl::opt DumpFpo; +extern llvm::cl::opt DumpStringTable; } namespace pdb2yaml { extern llvm::cl::opt NoFileHeaders; extern llvm::cl::opt StreamMetadata; extern llvm::cl::opt StreamDirectory; +extern llvm::cl::opt StringTable; extern llvm::cl::opt PdbStream; extern llvm::cl::opt DbiStream; extern llvm::cl::opt DbiModuleInfo; Index: llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp =================================================================== --- llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -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::cat(SymbolOptions), cl::sub(RawSubcommand)); // MISCELLANEOUS OPTIONS +cl::opt DumpStringTable("string-table", cl::desc("dump PDB String Table"), + cl::cat(MiscOptions), cl::sub(RawSubcommand)); + cl::opt DumpSectionContribs("section-contribs", cl::desc("dump section contributions"), cl::cat(MiscOptions), cl::sub(RawSubcommand)); @@ -279,6 +283,10 @@ cl::opt PdbStream("pdb-stream", cl::desc("Dump the PDB Stream (Stream 1)"), cl::sub(PdbToYamlSubcommand), cl::init(false)); + +cl::opt StringTable("string-table", cl::desc("Dump the PDB String Table"), + cl::sub(PdbToYamlSubcommand), cl::init(false)); + cl::opt DbiStream("dbi-stream", cl::desc("Dump the DBI Stream (Stream 2)"), cl::sub(PdbToYamlSubcommand), cl::init(false)); @@ -345,14 +353,18 @@ 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 @@ opts::raw::DumpSectionContribs = true; opts::raw::DumpLineInfo = true; opts::raw::DumpFpo = true; + opts::raw::DumpStringTable = true; } if (opts::raw::CompactRecords && Index: llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp =================================================================== --- llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp +++ llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp @@ -32,7 +32,7 @@ EXPECT_EQ(1U, Builder.insert("foo")); EXPECT_EQ(9U, Builder.insert("baz")); - std::vector Buffer(Builder.calculateSerializedLength()); + std::vector Buffer(Builder.finalize()); msf::MutableByteStream OutStream(Buffer); msf::StreamWriter Writer(OutStream); EXPECT_NO_ERROR(Builder.commit(Writer));