Index: include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h +++ include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h @@ -19,6 +19,7 @@ #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" +#include "llvm/Support/Endian.h" namespace llvm { namespace msf { @@ -43,6 +44,7 @@ void setPdbDllRbld(uint16_t R); void setFlags(uint16_t F); void setMachineType(PDB_Machine M); + void setDebugStreamIndex(DbgHeaderType Type, uint32_t Index); uint32_t calculateSerializedLength() const; @@ -92,6 +94,8 @@ msf::WritableStreamRef NamesBuffer; msf::MutableByteStream ModInfoBuffer; msf::MutableByteStream FileInfoBuffer; + std::vector DbgStreams = { + (size_t)DbgHeaderType::Max, (support::ulittle16_t)0}; }; } } Index: include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h +++ include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h @@ -14,6 +14,7 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -44,6 +45,9 @@ TpiStreamBuilder &getTpiBuilder(); TpiStreamBuilder &getIpiBuilder(); + // Add given bytes as a new stream. Returns the stream index. + Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef Data); + Expected> build(std::unique_ptr PdbFileBuffer); @@ -59,6 +63,7 @@ std::unique_ptr Dbi; std::unique_ptr Tpi; std::unique_ptr Ipi; + std::vector, uint32_t>> Streams; }; } } Index: lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp +++ lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/MSF/StreamWriter.h" @@ -43,10 +44,15 @@ void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; } +void DbiStreamBuilder::setDebugStreamIndex(DbgHeaderType Type, uint32_t Index) { + DbgStreams[(int)Type] = Index; +} + uint32_t DbiStreamBuilder::calculateSerializedLength() const { // For now we only support serializing the header. return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() + - calculateModiSubstreamSize(); + calculateModiSubstreamSize() + + DbgStreams.size() * sizeof(DbgStreams[0]); } Error DbiStreamBuilder::addModuleInfo(StringRef ObjFile, StringRef Module) { @@ -216,7 +222,7 @@ H->ECSubstreamSize = 0; H->FileInfoSize = FileInfoBuffer.getLength(); H->ModiSubstreamSize = ModInfoBuffer.getLength(); - H->OptionalDbgHdrSize = 0; + H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(DbgStreams[0]); H->SecContrSubstreamSize = 0; H->SectionMapSize = 0; H->TypeServerSize = 0; @@ -273,6 +279,8 @@ return EC; if (auto EC = Writer.writeStreamRef(FileInfoBuffer)) return EC; + if (auto EC = Writer.writeArray(ArrayRef(DbgStreams))) + return EC; if (Writer.bytesRemaining() > 0) return make_error(raw_error_code::invalid_format, Index: lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp +++ lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp @@ -66,6 +66,18 @@ return *Ipi; } +Error PDBFileBuilder::addDbgStream(pdb::DbgHeaderType Type, + ArrayRef Data) { + auto ExpectedIndex = Msf->addStream(Data.size()); + if (!ExpectedIndex) + return ExpectedIndex.takeError(); + uint32_t Index = std::move(*ExpectedIndex); + getDbiBuilder().setDebugStreamIndex(Type, Index); + + Streams.emplace_back(Data, Index); + return Error::success(); +} + Expected PDBFileBuilder::finalizeMsfLayout() const { if (Info) { if (auto EC = Info->finalizeMsfLayout()) @@ -189,5 +201,14 @@ return EC; } + for (auto &Pair : Streams) { + ArrayRef Data = Pair.first; + uint32_t Idx = Pair.second; + auto Stream = WritableMappedBlockStream::createIndexedStream(Layout, Buffer, Idx); + StreamWriter Writer(*Stream); + if (auto EC = Writer.writeArray(Data)) + return EC; + } + return Buffer.commit(); }