Index: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h @@ -47,6 +47,7 @@ void setPdbDllRbld(uint16_t R); void setFlags(uint16_t F); void setMachineType(PDB_Machine M); + void setSectionContribs(ArrayRef SecMap); void setSectionMap(ArrayRef SecMap); // Add given bytes as a new stream. @@ -63,6 +64,11 @@ Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer); + // A helper function to create Section Contributions from COFF input + // section headers. + static std::vector + createSectionContribs(ArrayRef SecHdrs); + // A helper function to create a Section Map from a COFF section header. static std::vector createSectionMap(ArrayRef SecHdrs); @@ -75,6 +81,7 @@ Error finalize(); uint32_t calculateModiSubstreamSize() const; + uint32_t calculateSectionContribsStreamSize() const; uint32_t calculateSectionMapStreamSize() const; uint32_t calculateFileInfoSubstreamSize() const; uint32_t calculateNamesBufferSize() const; @@ -110,6 +117,7 @@ msf::WritableStreamRef NamesBuffer; msf::MutableByteStream ModInfoBuffer; msf::MutableByteStream FileInfoBuffer; + ArrayRef SectionContribs; ArrayRef SectionMap; llvm::SmallVector DbgStreams; }; Index: llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp @@ -46,6 +46,10 @@ void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; } +void DbiStreamBuilder::setSectionContribs(ArrayRef Arr) { + SectionContribs = Arr; +} + void DbiStreamBuilder::setSectionMap(ArrayRef SecMap) { SectionMap = SecMap; } @@ -67,8 +71,8 @@ uint32_t DbiStreamBuilder::calculateSerializedLength() const { // For now we only support serializing the header. return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() + - calculateModiSubstreamSize() + calculateSectionMapStreamSize() + - calculateDbgStreamsSize(); + calculateModiSubstreamSize() + calculateSectionContribsStreamSize() + + calculateSectionMapStreamSize() + calculateDbgStreamsSize(); } Error DbiStreamBuilder::addModuleInfo(StringRef ObjFile, StringRef Module) { @@ -106,6 +110,13 @@ return Size; } +uint32_t DbiStreamBuilder::calculateSectionContribsStreamSize() const { + if (SectionContribs.empty()) + return 0; + return sizeof(enum PdbRaw_DbiSecContribVer) + + sizeof(SectionContribs[0]) * SectionContribs.size(); +}; + uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const { if (SectionMap.empty()) return 0; @@ -249,7 +260,7 @@ H->FileInfoSize = FileInfoBuffer.getLength(); H->ModiSubstreamSize = ModInfoBuffer.getLength(); H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t); - H->SecContrSubstreamSize = 0; + H->SecContrSubstreamSize = calculateSectionContribsStreamSize(); H->SectionMapSize = calculateSectionMapStreamSize(); H->TypeServerSize = 0; H->SymRecordStreamIndex = kInvalidStreamIndex; @@ -287,6 +298,25 @@ return Ret; } +// A utility function to create Section Contributions +// for a given input sections. +std::vector DbiStreamBuilder::createSectionContribs( + ArrayRef SecHdrs) { + std::vector Ret; + + // Create a SectionContrib for each input section. + for (auto &Sec : SecHdrs) { + Ret.emplace_back(); + auto &Entry = Ret.back(); + memset(&Entry, 0, sizeof(Entry)); + + Entry.Off = Sec.PointerToRawData; + Entry.Size = Sec.SizeOfRawData; + Entry.Characteristics = Sec.Characteristics; + } + return Ret; +} + // A utility function to create a Section Map for a given list of COFF sections. // // A Section Map seem to be a copy of a COFF section list in other format. @@ -363,6 +393,13 @@ if (auto EC = Writer.writeStreamRef(ModInfoBuffer)) return EC; + if (!SectionContribs.empty()) { + if (auto EC = Writer.writeEnum(DbiSecContribVer60)) + return EC; + if (auto EC = Writer.writeArray(SectionContribs)) + return EC; + } + if (!SectionMap.empty()) { ulittle16_t Size = static_cast(SectionMap.size()); SecMapHeader SMHeader = {Size, Size};