diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h index e5994ad66884..6ab3c8067558 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h @@ -29,11 +29,36 @@ struct coff_section; } namespace pdb { +class DbiStreamBuilder; class PDBFile; class ISectionContribVisitor; class DbiStream { - struct HeaderInfo; + friend class DbiStreamBuilder; + + struct HeaderInfo { + support::little32_t VersionSignature; + support::ulittle32_t VersionHeader; + support::ulittle32_t Age; // Should match InfoStream. + support::ulittle16_t GlobalSymbolStreamIndex; // Global symbol stream # + support::ulittle16_t BuildNumber; // See DbiBuildNo structure. + support::ulittle16_t PublicSymbolStreamIndex; // Public symbols stream # + support::ulittle16_t PdbDllVersion; // version of mspdbNNN.dll + support::ulittle16_t SymRecordStreamIndex; // Symbol records stream # + support::ulittle16_t PdbDllRbld; // rbld number of mspdbNNN.dll + support::little32_t ModiSubstreamSize; // Size of module info stream + support::little32_t SecContrSubstreamSize; // Size of sec. contrib stream + support::little32_t SectionMapSize; // Size of sec. map substream + support::little32_t FileInfoSize; // Size of file info substream + support::little32_t TypeServerSize; // Size of type server map + support::ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server + support::little32_t OptionalDbgHdrSize; // Size of DbgHeader info + support::little32_t ECSubstreamSize; // Size of EC stream (what is EC?) + support::ulittle16_t Flags; // See DbiFlags enum. + support::ulittle16_t MachineType; // See PDB_MachineType enum. + + support::ulittle32_t Reserved; // Pad to 64 bytes + }; public: DbiStream(PDBFile &File, std::unique_ptr Stream); @@ -45,13 +70,16 @@ public: uint16_t getPublicSymbolStreamIndex() const; uint16_t getGlobalSymbolStreamIndex() const; + uint16_t getFlags() const; bool isIncrementallyLinked() const; bool hasCTypes() const; bool isStripped() const; + uint16_t getBuildNumber() const; uint16_t getBuildMajorVersion() const; uint16_t getBuildMinorVersion() const; + uint16_t getPdbDllRbld() const; uint32_t getPdbDllVersion() const; uint32_t getSymRecordStreamIndex() const; diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h new file mode 100644 index 000000000000..ab4300858cec --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h @@ -0,0 +1,55 @@ +//===- DbiStreamBuilder.h - PDB Dbi Stream Creation -------------*- 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_PDBDBISTREAMBUILDER_H +#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAMBUILDER_H + +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Error.h" + +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" + +namespace llvm { +namespace pdb { +class DbiStream; +class PDBFile; + +class DbiStreamBuilder { +public: + DbiStreamBuilder(PDBFile &File); + + DbiStreamBuilder(const DbiStreamBuilder &) = delete; + DbiStreamBuilder &operator=(const DbiStreamBuilder &) = delete; + + void setVersionHeader(PdbRaw_DbiVer V); + void setAge(uint32_t A); + void setBuildNumber(uint16_t B); + void setPdbDllVersion(uint16_t V); + void setPdbDllRbld(uint16_t R); + void setFlags(uint16_t F); + void setMachineType(PDB_Machine M); + + Expected> build(); + +private: + PDBFile &File; + Optional VerHeader; + uint32_t Age; + uint16_t BuildNumber; + uint16_t PdbDllVersion; + uint16_t PdbDllRbld; + uint16_t Flags; + PDB_Machine MachineType; +}; +} +} + +#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h index d774e1ba4393..9cca48777097 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStream.h @@ -21,28 +21,33 @@ namespace llvm { namespace pdb { +class InfoStreamBuilder; class PDBFile; + class InfoStream { + friend class InfoStreamBuilder; + + struct Header { + support::ulittle32_t Version; + support::ulittle32_t Signature; + support::ulittle32_t Age; + PDB_UniqueId Guid; + }; + public: InfoStream(std::unique_ptr Stream); Error reload(); + Error commit(); PdbRaw_ImplVer getVersion() const; uint32_t getSignature() const; uint32_t getAge() const; PDB_UniqueId getGuid() const; - void setVersion(PdbRaw_ImplVer Ver); - void setSignature(uint32_t Sig); - void setAge(uint32_t Age); - void setGuid(PDB_UniqueId Guid); - uint32_t getNamedStreamIndex(llvm::StringRef Name) const; iterator_range> named_streams() const; - Error commit(); - private: std::unique_ptr Stream; diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h new file mode 100644 index 000000000000..e8ee572c1a05 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h @@ -0,0 +1,50 @@ +//===- InfoStreamBuilder.h - PDB Info Stream Creation -----------*- 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_PDBINFOSTREAMBUILDER_H +#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAMBUILDER_H + +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Error.h" + +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/DebugInfo/PDB/Raw/NameMap.h" +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" + +namespace llvm { +namespace pdb { +class NameMap; +class PDBFile; + +class InfoStreamBuilder { +public: + InfoStreamBuilder(IPDBFile &File); + InfoStreamBuilder(const InfoStreamBuilder &) = delete; + InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete; + + void setVersion(PdbRaw_ImplVer V); + void setSignature(uint32_t S); + void setAge(uint32_t A); + void setGuid(PDB_UniqueId G); + + Expected> build(); + +private: + IPDBFile &File; + Optional Ver; + Optional Sig; + Optional Age; + Optional Guid; + Optional NamedStreams; +}; +} +} + +#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h index ccb6478e280f..36424c0d16ab 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h @@ -14,6 +14,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/CodeView/StreamInterface.h" +#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -24,7 +25,6 @@ namespace llvm { namespace pdb { class IPDBFile; -class IPDBStreamData; class PDBFile; class MappedBlockStream : public codeview::StreamInterface { @@ -45,6 +45,8 @@ public: static Expected> createDirectoryStream(const PDBFile &File); + llvm::BumpPtrAllocator &getAllocator() { return Pool; } + protected: MappedBlockStream(std::unique_ptr Data, const IPDBFile &File); diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h index 11ddb2e63eb0..71d7c6144c3e 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamInterface.h" #include "llvm/DebugInfo/PDB/Raw/IPDBFile.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/MathExtras.h" @@ -31,6 +32,7 @@ class DbiStream; class InfoStream; class MappedBlockStream; class NameHashTable; +class PDBFileBuilder; class PublicsStream; class SymbolStream; class TpiStream; @@ -41,6 +43,8 @@ static const char MsfMagic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'}; class PDBFile : public IPDBFile { + friend PDBFileBuilder; + public: // The superblock is overlaid at the beginning of the file (offset 0). // It starts with a magic header and is followed by information which @@ -107,8 +111,6 @@ public: return BlockNumber * BlockSize; } - Expected emplacePDBInfoStream(); - Expected getPDBInfoStream(); Expected getPDBDbiStream(); Expected getPDBTpiStream(); @@ -117,14 +119,13 @@ public: Expected getPDBSymbolStream(); Expected getStringTable(); - Error setSuperBlock(const SuperBlock *Block); - void setStreamSizes(ArrayRef Sizes); - void setDirectoryBlocks(ArrayRef Directory); - void setStreamMap(std::vector> &Streams); - Error generateSimpleStreamMap(); Error commit(); private: + Error setSuperBlock(const SuperBlock *Block); + + BumpPtrAllocator Allocator; + std::unique_ptr Buffer; const PDBFile::SuperBlock *SB; ArrayRef StreamSizes; diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h new file mode 100644 index 000000000000..ba7ca935e5fa --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h @@ -0,0 +1,60 @@ +//===- PDBFileBuilder.h - PDB File Creation ---------------------*- 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_PDBFILEBUILDER_H +#define LLVM_DEBUGINFO_PDB_RAW_PDBFILEBUILDER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" + +#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" + +#include +#include + +namespace llvm { +namespace codeview { +class StreamInterface; +} +namespace pdb { +class DbiStreamBuilder; +class InfoStreamBuilder; +class PDBFile; + +class PDBFileBuilder { +public: + explicit PDBFileBuilder( + std::unique_ptr PdbFileBuffer); + PDBFileBuilder(const PDBFileBuilder &) = delete; + PDBFileBuilder &operator=(const PDBFileBuilder &) = delete; + + Error setSuperBlock(const PDBFile::SuperBlock &B); + void setStreamSizes(ArrayRef S); + void setDirectoryBlocks(ArrayRef D); + void setStreamMap(const std::vector> &S); + Error generateSimpleStreamMap(); + + InfoStreamBuilder &getInfoBuilder(); + DbiStreamBuilder &getDbiBuilder(); + + Expected> build(); + +private: + std::unique_ptr PdbFileBuffer; + std::unique_ptr Info; + std::unique_ptr Dbi; + + std::unique_ptr File; +}; +} +} + +#endif diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index ffeb56c28edd..669298952f20 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -29,16 +29,19 @@ endif() add_pdb_impl_folder(Raw Raw/DbiStream.cpp + Raw/DbiStreamBuilder.cpp Raw/EnumTables.cpp Raw/Hash.cpp Raw/IndexedStreamData.cpp Raw/InfoStream.cpp + Raw/InfoStreamBuilder.cpp Raw/MappedBlockStream.cpp Raw/ModInfo.cpp Raw/ModStream.cpp Raw/NameHashTable.cpp Raw/NameMap.cpp Raw/PDBFile.cpp + Raw/PDBFileBuilder.cpp Raw/PublicsStream.cpp Raw/RawError.cpp Raw/RawSession.cpp diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index ec807a29a037..bfe0251f4ce4 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -11,6 +11,7 @@ #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h" #include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" @@ -53,31 +54,16 @@ const uint16_t BuildMinorShift = 0; const uint16_t BuildMajorMask = 0x7F00; const uint16_t BuildMajorShift = 8; -} -struct DbiStream::HeaderInfo { - little32_t VersionSignature; - ulittle32_t VersionHeader; - ulittle32_t Age; // Should match InfoStream. - ulittle16_t GlobalSymbolStreamIndex; // Global symbol stream # - ulittle16_t BuildNumber; // See DbiBuildNo structure. - ulittle16_t PublicSymbolStreamIndex; // Public symbols stream # - ulittle16_t PdbDllVersion; // version of mspdbNNN.dll - ulittle16_t SymRecordStreamIndex; // Symbol records stream # - 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 - little32_t ECSubstreamSize; // Size of EC stream (what is EC?) - ulittle16_t Flags; // See DbiFlags enum. - ulittle16_t MachineType; // See PDB_MachineType enum. - - ulittle32_t Reserved; // Pad to 64 bytes +struct FileInfoSubstreamHeader { + ulittle16_t NumModules; // Total # of modules, should match number of + // records in the ModuleInfo substream. + ulittle16_t NumSourceFiles; // Total # of source files. This value is not + // accurate because PDB actually supports more + // than 64k source files, so we ignore it and + // compute the value from other stream fields. }; +} template static Error loadSectionContribs(FixedStreamArray &Output, @@ -218,6 +204,8 @@ uint16_t DbiStream::getGlobalSymbolStreamIndex() const { return Header->GlobalSymbolStreamIndex; } +uint16_t DbiStream::getFlags() const { return Header->Flags; } + bool DbiStream::isIncrementallyLinked() const { return (Header->Flags & FlagIncrementalMask) != 0; } @@ -230,6 +218,8 @@ bool DbiStream::isStripped() const { return (Header->Flags & FlagStrippedMask) != 0; } +uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; } + uint16_t DbiStream::getBuildMajorVersion() const { return (Header->BuildNumber & BuildMajorMask) >> BuildMajorShift; } @@ -238,6 +228,8 @@ uint16_t DbiStream::getBuildMinorVersion() const { return (Header->BuildNumber & BuildMinorMask) >> BuildMinorShift; } +uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; } + uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; } uint32_t DbiStream::getSymRecordStreamIndex() const { @@ -353,15 +345,6 @@ Error DbiStream::initializeSectionMapData() { } Error DbiStream::initializeFileInfo() { - struct FileInfoSubstreamHeader { - ulittle16_t NumModules; // Total # of modules, should match number of - // records in the ModuleInfo substream. - ulittle16_t NumSourceFiles; // Total # of source files. This value is not - // accurate because PDB actually supports more - // than 64k source files, so we ignore it and - // compute the value from other stream fields. - }; - // The layout of the FileInfoSubstream is like this: // struct { // ulittle16_t NumModules; diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp new file mode 100644 index 000000000000..ff5ce61c2129 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp @@ -0,0 +1,76 @@ +//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" + +#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +DbiStreamBuilder::DbiStreamBuilder(PDBFile &File) + : File(File), Age(1), BuildNumber(0), PdbDllVersion(0), PdbDllRbld(0), + Flags(0), MachineType(PDB_Machine::x86) {} + +void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; } + +void DbiStreamBuilder::setAge(uint32_t A) { Age = A; } + +void DbiStreamBuilder::setBuildNumber(uint16_t B) { BuildNumber = B; } + +void DbiStreamBuilder::setPdbDllVersion(uint16_t V) { PdbDllVersion = V; } + +void DbiStreamBuilder::setPdbDllRbld(uint16_t R) { PdbDllRbld = R; } + +void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; } + +void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; } + +Expected> DbiStreamBuilder::build() { + if (!VerHeader.hasValue()) + return make_error(raw_error_code::unspecified, + "Missing DBI Stream Version"); + + auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, File); + if (!DbiS) + return DbiS.takeError(); + auto DS = std::move(*DbiS); + DbiStream::HeaderInfo *H = + static_cast(DS->getAllocator().Allocate( + sizeof(DbiStream::HeaderInfo), + llvm::AlignOf::Alignment)); + H->VersionHeader = *VerHeader; + H->VersionSignature = -1; + H->Age = Age; + H->BuildNumber = BuildNumber; + H->Flags = Flags; + H->PdbDllRbld = PdbDllRbld; + H->PdbDllVersion = PdbDllVersion; + H->MachineType = static_cast(MachineType); + + H->ECSubstreamSize = 0; + H->FileInfoSize = 0; + H->ModiSubstreamSize = 0; + H->OptionalDbgHdrSize = 0; + H->SecContrSubstreamSize = 0; + H->SectionMapSize = 0; + H->TypeServerSize = 0; + H->SymRecordStreamIndex = DbiStream::InvalidStreamIndex; + H->PublicSymbolStreamIndex = DbiStream::InvalidStreamIndex; + H->MFCTypeServerIndex = DbiStream::InvalidStreamIndex; + H->GlobalSymbolStreamIndex = DbiStream::InvalidStreamIndex; + + auto Dbi = llvm::make_unique(File, std::move(DS)); + Dbi->Header = H; + return std::move(Dbi); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp index 5273118f7c22..e2f85ab880f2 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp @@ -21,15 +21,6 @@ using namespace llvm; using namespace llvm::codeview; using namespace llvm::pdb; -namespace { -struct Header { - support::ulittle32_t Version; - support::ulittle32_t Signature; - support::ulittle32_t Age; - PDB_UniqueId Guid; -}; -} - InfoStream::InfoStream(std::unique_ptr Stream) : Stream(std::move(Stream)) {} @@ -84,16 +75,6 @@ uint32_t InfoStream::getAge() const { return Age; } PDB_UniqueId InfoStream::getGuid() const { return Guid; } -void InfoStream::setVersion(PdbRaw_ImplVer Ver) { - Version = static_cast(Ver); -} - -void InfoStream::setSignature(uint32_t Sig) { Signature = Sig; } - -void InfoStream::setAge(uint32_t Age) { this->Age = Age; } - -void InfoStream::setGuid(PDB_UniqueId Guid) { this->Guid = Guid; } - Error InfoStream::commit() { StreamWriter Writer(*Stream); @@ -106,4 +87,4 @@ Error InfoStream::commit() { return EC; return NamedStreams.commit(Writer); -} +} \ No newline at end of file diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp new file mode 100644 index 000000000000..21042e9a5346 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp @@ -0,0 +1,54 @@ +//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h" + +#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +InfoStreamBuilder::InfoStreamBuilder(IPDBFile &File) : File(File) {} + +void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; } + +void InfoStreamBuilder::setSignature(uint32_t S) { Sig = S; } + +void InfoStreamBuilder::setAge(uint32_t A) { Age = A; } + +void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; } + +Expected> InfoStreamBuilder::build() { + if (!Ver.hasValue()) + return make_error(raw_error_code::unspecified, + "Missing PDB Stream Version"); + if (!Sig.hasValue()) + return make_error(raw_error_code::unspecified, + "Missing PDB Stream Signature"); + if (!Age.hasValue()) + return make_error(raw_error_code::unspecified, + "Missing PDB Stream Age"); + if (!Guid.hasValue()) + return make_error(raw_error_code::unspecified, + "Missing PDB Stream Guid"); + + auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, File); + if (!InfoS) + return InfoS.takeError(); + auto Info = llvm::make_unique(std::move(*InfoS)); + Info->Version = *Ver; + Info->Signature = *Sig; + Info->Age = *Age; + Info->Guid = *Guid; + return std::move(Info); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index ce2446cba808..2aa4d4c426fe 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -173,17 +173,6 @@ llvm::ArrayRef PDBFile::getDirectoryBlockArray() const { return DirectoryBlocks; } -Expected PDBFile::emplacePDBInfoStream() { - if (Info) - Info.reset(); - - auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this); - if (!InfoS) - return InfoS.takeError(); - Info = llvm::make_unique(std::move(*InfoS)); - return *Info; -} - Expected PDBFile::getPDBInfoStream() { if (!Info) { auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this); @@ -352,64 +341,6 @@ Error PDBFile::setSuperBlock(const SuperBlock *Block) { return Error::success(); } -void PDBFile::setStreamSizes(ArrayRef Sizes) { - StreamSizes = Sizes; -} - -void PDBFile::setStreamMap( - std::vector> &Streams) { - StreamMap = Streams; -} - -void PDBFile::setDirectoryBlocks(ArrayRef Directory) { - DirectoryBlocks = Directory; -} - -Error PDBFile::generateSimpleStreamMap() { - if (StreamSizes.empty()) - return Error::success(); - - static std::vector> StaticMap; - StreamMap.clear(); - StaticMap.clear(); - - // Figure out how many blocks are needed for all streams, and set the first - // used block to the highest block so that we can write the rest of the - // blocks contiguously. - uint32_t TotalFileBlocks = getBlockCount(); - std::vector ReservedBlocks; - ReservedBlocks.push_back(support::ulittle32_t(0)); - ReservedBlocks.push_back(SB->BlockMapAddr); - ReservedBlocks.insert(ReservedBlocks.end(), DirectoryBlocks.begin(), - DirectoryBlocks.end()); - - uint32_t BlocksNeeded = 0; - for (auto Size : StreamSizes) - BlocksNeeded += bytesToBlocks(Size, getBlockSize()); - - support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded - - ReservedBlocks.size()); - - StaticMap.resize(StreamSizes.size()); - for (uint32_t S = 0; S < StreamSizes.size(); ++S) { - uint32_t Size = StreamSizes[S]; - uint32_t NumBlocks = bytesToBlocks(Size, getBlockSize()); - auto &ThisStream = StaticMap[S]; - for (uint32_t I = 0; I < NumBlocks;) { - NextBlock += 1; - if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) != - ReservedBlocks.end()) - continue; - - ++I; - assert(NextBlock < getBlockCount()); - ThisStream.push_back(NextBlock); - } - StreamMap.push_back(ThisStream); - } - return Error::success(); -} - Error PDBFile::commit() { StreamWriter Writer(*Buffer); diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp new file mode 100644 index 000000000000..f859c1fcc2e4 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp @@ -0,0 +1,127 @@ +//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h" + +#include "llvm/DebugInfo/CodeView/StreamInterface.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +PDBFileBuilder::PDBFileBuilder( + std::unique_ptr PdbFileBuffer) + : File(llvm::make_unique(std::move(PdbFileBuffer))) {} + +Error PDBFileBuilder::setSuperBlock(const PDBFile::SuperBlock &B) { + auto SB = static_cast( + File->Allocator.Allocate(sizeof(PDBFile::SuperBlock), + llvm::AlignOf::Alignment)); + ::memcpy(SB, &B, sizeof(PDBFile::SuperBlock)); + return File->setSuperBlock(SB); +} + +void PDBFileBuilder::setStreamSizes(ArrayRef S) { + File->StreamSizes = S; +} + +void PDBFileBuilder::setDirectoryBlocks(ArrayRef D) { + File->DirectoryBlocks = D; +} + +void PDBFileBuilder::setStreamMap( + const std::vector> &S) { + File->StreamMap = S; +} + +Error PDBFileBuilder::generateSimpleStreamMap() { + if (File->StreamSizes.empty()) + return Error::success(); + + static std::vector> StaticMap; + File->StreamMap.clear(); + StaticMap.clear(); + + // Figure out how many blocks are needed for all streams, and set the first + // used block to the highest block so that we can write the rest of the + // blocks contiguously. + uint32_t TotalFileBlocks = File->getBlockCount(); + std::vector ReservedBlocks; + ReservedBlocks.push_back(support::ulittle32_t(0)); + ReservedBlocks.push_back(File->SB->BlockMapAddr); + ReservedBlocks.insert(ReservedBlocks.end(), File->DirectoryBlocks.begin(), + File->DirectoryBlocks.end()); + + uint32_t BlocksNeeded = 0; + for (auto Size : File->StreamSizes) + BlocksNeeded += File->bytesToBlocks(Size, File->getBlockSize()); + + support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded - + ReservedBlocks.size()); + + StaticMap.resize(File->StreamSizes.size()); + for (uint32_t S = 0; S < File->StreamSizes.size(); ++S) { + uint32_t Size = File->StreamSizes[S]; + uint32_t NumBlocks = File->bytesToBlocks(Size, File->getBlockSize()); + auto &ThisStream = StaticMap[S]; + for (uint32_t I = 0; I < NumBlocks;) { + NextBlock += 1; + if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) != + ReservedBlocks.end()) + continue; + + ++I; + assert(NextBlock < File->getBlockCount()); + ThisStream.push_back(NextBlock); + } + File->StreamMap.push_back(ThisStream); + } + return Error::success(); +} + +InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() { + if (!Info) + Info = llvm::make_unique(*File); + return *Info; +} + +DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() { + if (!Dbi) + Dbi = llvm::make_unique(*File); + return *Dbi; +} + +Expected> PDBFileBuilder::build() { + if (Info) { + auto ExpectedInfo = Info->build(); + if (!ExpectedInfo) + return ExpectedInfo.takeError(); + File->Info = std::move(*ExpectedInfo); + } + + if (Dbi) { + auto ExpectedDbi = Dbi->build(); + if (!ExpectedDbi) + return ExpectedDbi.takeError(); + File->Dbi = std::move(*ExpectedDbi); + } + + if (File->Info && File->Dbi && File->Info->getAge() != File->Dbi->getAge()) + return llvm::make_error( + raw_error_code::corrupt_file, + "PDB Stream Age doesn't match Dbi Stream Age!"); + + return std::move(File); +} diff --git a/llvm/test/DebugInfo/PDB/pdbdump-yaml.test b/llvm/test/DebugInfo/PDB/pdbdump-yaml.test index 3ccc6c25be1b..a7394beb8cc8 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-yaml.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-yaml.test @@ -74,7 +74,7 @@ ; YAML-NEXT: Age: 1 ; YAML-NEXT: Guid: '{0B355641-86A0-A249-896F-9988FAE52FF0}' ; YAML-NEXT: Signature: 1424295906 -; YAML-NEXT: Version: 20000404 +; YAML-NEXT: Version: VC70 ; YAML-NEXT: ... ; NO-HEADERS: --- diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.cpp b/llvm/tools/llvm-pdbdump/PdbYaml.cpp index b43316a601de..a341ab073081 100644 --- a/llvm/tools/llvm-pdbdump/PdbYaml.cpp +++ b/llvm/tools/llvm-pdbdump/PdbYaml.cpp @@ -53,9 +53,74 @@ template <> struct ScalarTraits { static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } }; + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, llvm::pdb::PDB_Machine &Value) { + io.enumCase(Value, "Invalid", PDB_Machine::Invalid); + io.enumCase(Value, "Am33", PDB_Machine::Am33); + io.enumCase(Value, "Amd64", PDB_Machine::Amd64); + io.enumCase(Value, "Arm", PDB_Machine::Arm); + io.enumCase(Value, "ArmNT", PDB_Machine::ArmNT); + io.enumCase(Value, "Ebc", PDB_Machine::Ebc); + io.enumCase(Value, "x86", PDB_Machine::x86); + io.enumCase(Value, "Ia64", PDB_Machine::Ia64); + io.enumCase(Value, "M32R", PDB_Machine::M32R); + io.enumCase(Value, "Mips16", PDB_Machine::Mips16); + io.enumCase(Value, "MipsFpu", PDB_Machine::MipsFpu); + io.enumCase(Value, "MipsFpu16", PDB_Machine::MipsFpu16); + io.enumCase(Value, "PowerPCFP", PDB_Machine::PowerPCFP); + io.enumCase(Value, "R4000", PDB_Machine::R4000); + io.enumCase(Value, "SH3", PDB_Machine::SH3); + io.enumCase(Value, "SH3DSP", PDB_Machine::SH3DSP); + io.enumCase(Value, "Thumb", PDB_Machine::Thumb); + io.enumCase(Value, "WceMipsV2", PDB_Machine::WceMipsV2); + } +}; + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, llvm::pdb::PdbRaw_DbiVer &Value) { + io.enumCase(Value, "V41", llvm::pdb::PdbRaw_DbiVer::PdbDbiVC41); + io.enumCase(Value, "V50", llvm::pdb::PdbRaw_DbiVer::PdbDbiV50); + io.enumCase(Value, "V60", llvm::pdb::PdbRaw_DbiVer::PdbDbiV60); + io.enumCase(Value, "V70", llvm::pdb::PdbRaw_DbiVer::PdbDbiV70); + io.enumCase(Value, "V110", llvm::pdb::PdbRaw_DbiVer::PdbDbiV110); + } +}; + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, llvm::pdb::PdbRaw_ImplVer &Value) { + io.enumCase(Value, "VC2", llvm::pdb::PdbRaw_ImplVer::PdbImplVC2); + io.enumCase(Value, "VC4", llvm::pdb::PdbRaw_ImplVer::PdbImplVC4); + io.enumCase(Value, "VC41", llvm::pdb::PdbRaw_ImplVer::PdbImplVC41); + io.enumCase(Value, "VC50", llvm::pdb::PdbRaw_ImplVer::PdbImplVC50); + io.enumCase(Value, "VC98", llvm::pdb::PdbRaw_ImplVer::PdbImplVC98); + io.enumCase(Value, "VC70Dep", llvm::pdb::PdbRaw_ImplVer::PdbImplVC70Dep); + io.enumCase(Value, "VC70", llvm::pdb::PdbRaw_ImplVer::PdbImplVC70); + io.enumCase(Value, "VC80", llvm::pdb::PdbRaw_ImplVer::PdbImplVC80); + io.enumCase(Value, "VC110", llvm::pdb::PdbRaw_ImplVer::PdbImplVC110); + io.enumCase(Value, "VC140", llvm::pdb::PdbRaw_ImplVer::PdbImplVC140); + } +}; } } +void MappingTraits::mapping(IO &IO, PdbObject &Obj) { + IO.mapOptional("MSF", Obj.Headers); + IO.mapOptional("StreamSizes", Obj.StreamSizes); + IO.mapOptional("StreamMap", Obj.StreamMap); + IO.mapOptional("PdbStream", Obj.PdbStream); + IO.mapOptional("DbiStream", Obj.DbiStream); +} + +void MappingTraits::mapping(IO &IO, MsfHeaders &Obj) { + IO.mapRequired("SuperBlock", Obj.SuperBlock); + IO.mapRequired("NumDirectoryBlocks", Obj.NumDirectoryBlocks); + IO.mapRequired("BlockMapOffset", Obj.BlockMapOffset); + IO.mapRequired("DirectoryBlocks", Obj.DirectoryBlocks); + IO.mapRequired("NumStreams", Obj.NumStreams); + IO.mapRequired("FileSize", Obj.FileSize); +} + void MappingTraits::mapping(IO &IO, PDBFile::SuperBlock &SB) { if (!IO.outputting()) { @@ -74,25 +139,19 @@ void MappingTraits::mapping(IO &IO, StreamBlockList &SB) { IO.mapRequired("Stream", SB.Blocks); } -void MappingTraits::mapping(IO &IO, MsfHeaders &Obj) { - IO.mapRequired("SuperBlock", Obj.SuperBlock); - IO.mapRequired("NumDirectoryBlocks", Obj.NumDirectoryBlocks); - IO.mapRequired("BlockMapOffset", Obj.BlockMapOffset); - IO.mapRequired("DirectoryBlocks", Obj.DirectoryBlocks); - IO.mapRequired("NumStreams", Obj.NumStreams); - IO.mapRequired("FileSize", Obj.FileSize); -} - -void MappingTraits::mapping(IO &IO, PdbObject &Obj) { - IO.mapOptional("MSF", Obj.Headers); - IO.mapOptional("StreamSizes", Obj.StreamSizes); - IO.mapOptional("StreamMap", Obj.StreamMap); - IO.mapOptional("PdbStream", Obj.PdbStream); -} - void MappingTraits::mapping(IO &IO, PdbInfoStream &Obj) { IO.mapRequired("Age", Obj.Age); IO.mapRequired("Guid", Obj.Guid); IO.mapRequired("Signature", Obj.Signature); IO.mapRequired("Version", Obj.Version); -} \ No newline at end of file +} + +void MappingTraits::mapping(IO &IO, PdbDbiStream &Obj) { + IO.mapRequired("VerHeader", Obj.VerHeader); + IO.mapRequired("Age", Obj.Age); + IO.mapRequired("BuildNumber", Obj.BuildNumber); + IO.mapRequired("PdbDllVersion", Obj.PdbDllVersion); + IO.mapRequired("PdbDllRbld", Obj.PdbDllRbld); + IO.mapRequired("Flags", Obj.Flags); + IO.mapRequired("MachineType", Obj.MachineType); +} diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.h b/llvm/tools/llvm-pdbdump/PdbYaml.h index d243f9b12b1a..91c0a585926b 100644 --- a/llvm/tools/llvm-pdbdump/PdbYaml.h +++ b/llvm/tools/llvm-pdbdump/PdbYaml.h @@ -39,17 +39,28 @@ struct StreamBlockList { }; struct PdbInfoStream { - uint32_t Version; + PdbRaw_ImplVer Version; uint32_t Signature; uint32_t Age; PDB_UniqueId Guid; }; +struct PdbDbiStream { + PdbRaw_DbiVer VerHeader; + uint32_t Age; + uint16_t BuildNumber; + uint32_t PdbDllVersion; + uint16_t PdbDllRbld; + uint16_t Flags; + PDB_Machine MachineType; +}; + struct PdbObject { Optional Headers; Optional> StreamSizes; Optional> StreamMap; Optional PdbStream; + Optional DbiStream; }; } } @@ -58,6 +69,14 @@ struct PdbObject { namespace llvm { namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::PdbObject &Obj); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::MsfHeaders &Obj); +}; + template <> struct MappingTraits { static void mapping(IO &IO, pdb::PDBFile::SuperBlock &SB); }; @@ -66,17 +85,13 @@ template <> struct MappingTraits { static void mapping(IO &IO, pdb::yaml::StreamBlockList &SB); }; -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::MsfHeaders &Obj); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::PdbObject &Obj); -}; - template <> struct MappingTraits { static void mapping(IO &IO, pdb::yaml::PdbInfoStream &Obj); }; + +template <> struct MappingTraits { + static void mapping(IO &IO, pdb::yaml::PdbDbiStream &Obj); +}; } } diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp index f3c730fc6b39..aa68128cd80a 100644 --- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -12,6 +12,7 @@ #include "PdbYaml.h" #include "llvm-pdbdump.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" @@ -22,7 +23,8 @@ using namespace llvm::pdb; YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) : File(File), Out(outs()) {} Error YAMLOutputStyle::dump() { - if (opts::pdb2yaml::StreamDirectory || opts::pdb2yaml::PdbStream) + if (opts::pdb2yaml::StreamDirectory || opts::pdb2yaml::PdbStream || + opts::pdb2yaml::DbiStream) opts::pdb2yaml::StreamMetadata = true; if (auto EC = dumpFileHeaders()) @@ -37,6 +39,9 @@ Error YAMLOutputStyle::dump() { if (auto EC = dumpPDBStream()) return EC; + if (auto EC = dumpDbiStream()) + return EC; + flush(); return Error::success(); } @@ -105,6 +110,26 @@ Error YAMLOutputStyle::dumpPDBStream() { return Error::success(); } +Error YAMLOutputStyle::dumpDbiStream() { + if (!opts::pdb2yaml::DbiStream) + return Error::success(); + + auto DbiS = File.getPDBDbiStream(); + if (!DbiS) + return DbiS.takeError(); + + auto &DS = DbiS.get(); + Obj.DbiStream.emplace(); + Obj.DbiStream->Age = DS.getAge(); + Obj.DbiStream->BuildNumber = DS.getBuildNumber(); + Obj.DbiStream->Flags = DS.getFlags(); + Obj.DbiStream->MachineType = DS.getMachineType(); + Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld(); + Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion(); + Obj.DbiStream->VerHeader = DS.getDbiVersion(); + return Error::success(); +} + void YAMLOutputStyle::flush() { Out << Obj; outs().flush(); diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h index 1c7e8ace5eab..d36dfec5f25a 100644 --- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h +++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -30,6 +30,7 @@ private: Error dumpStreamMetadata(); Error dumpStreamDirectory(); Error dumpPDBStream(); + Error dumpDbiStream(); void flush(); diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index ffb71ba04107..5a3ced37a9d0 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -40,8 +40,12 @@ #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" +#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/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" #include "llvm/DebugInfo/PDB/Raw/RawSession.h" @@ -279,6 +283,10 @@ cl::opt PdbStream( "pdb-stream", cl::desc("Dump the PDB Stream (Stream 1) (implies -stream-metadata)"), cl::sub(PdbToYamlSubcommand), cl::init(false)); +cl::opt DbiStream( + "dbi-stream", + cl::desc("Dump the DBI Stream (Stream 2) (implies -stream-metadata)"), + cl::sub(PdbToYamlSubcommand), cl::init(false)); cl::list InputFilename(cl::Positional, cl::desc(""), cl::Required, @@ -314,34 +322,48 @@ static void yamlToPdb(StringRef Path) { auto FileByteStream = llvm::make_unique(std::move(*OutFileOrError)); - PDBFile Pdb(std::move(FileByteStream)); - ExitOnErr(Pdb.setSuperBlock(&YamlObj.Headers->SuperBlock)); + PDBFileBuilder Builder(std::move(FileByteStream)); + + ExitOnErr(Builder.setSuperBlock(YamlObj.Headers->SuperBlock)); if (YamlObj.StreamSizes.hasValue()) { - Pdb.setStreamSizes(YamlObj.StreamSizes.getValue()); + Builder.setStreamSizes(YamlObj.StreamSizes.getValue()); } - Pdb.setDirectoryBlocks(YamlObj.Headers->DirectoryBlocks); + Builder.setDirectoryBlocks(YamlObj.Headers->DirectoryBlocks); if (YamlObj.StreamMap.hasValue()) { std::vector> StreamMap; for (auto &E : YamlObj.StreamMap.getValue()) { StreamMap.push_back(E.Blocks); } - Pdb.setStreamMap(StreamMap); + Builder.setStreamMap(StreamMap); } else { - ExitOnErr(Pdb.generateSimpleStreamMap()); + ExitOnErr(Builder.generateSimpleStreamMap()); } if (YamlObj.PdbStream.hasValue()) { - auto IS = Pdb.emplacePDBInfoStream(); - ExitOnErr(IS.takeError()); - auto &InfoS = IS.get(); - InfoS.setAge(YamlObj.PdbStream->Age); - InfoS.setGuid(YamlObj.PdbStream->Guid); - InfoS.setSignature(YamlObj.PdbStream->Signature); - InfoS.setVersion(static_cast(YamlObj.PdbStream->Version)); + auto &InfoBuilder = Builder.getInfoBuilder(); + InfoBuilder.setAge(YamlObj.PdbStream->Age); + InfoBuilder.setGuid(YamlObj.PdbStream->Guid); + InfoBuilder.setSignature(YamlObj.PdbStream->Signature); + InfoBuilder.setVersion(YamlObj.PdbStream->Version); } - ExitOnErr(Pdb.commit()); + if (YamlObj.DbiStream.hasValue()) { + auto &DbiBuilder = Builder.getDbiBuilder(); + DbiBuilder.setAge(YamlObj.DbiStream->Age); + DbiBuilder.setBuildNumber(YamlObj.DbiStream->BuildNumber); + DbiBuilder.setFlags(YamlObj.DbiStream->Flags); + DbiBuilder.setMachineType(YamlObj.DbiStream->MachineType); + DbiBuilder.setPdbDllRbld(YamlObj.DbiStream->PdbDllRbld); + DbiBuilder.setPdbDllVersion(YamlObj.DbiStream->PdbDllVersion); + DbiBuilder.setVersionHeader(YamlObj.DbiStream->VerHeader); + } + + auto Pdb = Builder.build(); + ExitOnErr(Pdb.takeError()); + + auto &PdbFile = *Pdb; + ExitOnErr(PdbFile->commit()); } static void pdb2Yaml(StringRef Path) { diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h index 7ccf4d5c2b4f..0a66515f4a01 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h @@ -61,6 +61,7 @@ extern llvm::cl::opt NoFileHeaders; extern llvm::cl::opt StreamMetadata; extern llvm::cl::opt StreamDirectory; extern llvm::cl::opt PdbStream; +extern llvm::cl::opt DbiStream; extern llvm::cl::list InputFilename; } }