10b57cec5SDimitry Andric //===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "llvm/DebugInfo/MSF/MSFBuilder.h" 120b57cec5SDimitry Andric #include "llvm/DebugInfo/MSF/MappedBlockStream.h" 130b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" 140b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawTypes.h" 1581ad6265SDimitry Andric #include "llvm/Support/BinaryStreamReader.h" 160b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamWriter.h" 17*5f757f3fSDimitry Andric #include "llvm/Support/TimeProfiler.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric using namespace llvm::codeview; 210b57cec5SDimitry Andric using namespace llvm::msf; 220b57cec5SDimitry Andric using namespace llvm::pdb; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf, 250b57cec5SDimitry Andric NamedStreamMap &NamedStreams) 260b57cec5SDimitry Andric : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Age(0), 270b57cec5SDimitry Andric NamedStreams(NamedStreams) { 280b57cec5SDimitry Andric ::memset(&Guid, 0, sizeof(Guid)); 290b57cec5SDimitry Andric } 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; } 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) { 340b57cec5SDimitry Andric Features.push_back(Sig); 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) { 380b57cec5SDimitry Andric HashPDBContentsToGUID = B; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric void InfoStreamBuilder::setAge(uint32_t A) { Age = A; } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void InfoStreamBuilder::setGuid(GUID G) { Guid = G; } 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric Error InfoStreamBuilder::finalizeMsfLayout() { 490b57cec5SDimitry Andric uint32_t Length = sizeof(InfoStreamHeader) + 500b57cec5SDimitry Andric NamedStreams.calculateSerializedLength() + 510b57cec5SDimitry Andric (Features.size() + 1) * sizeof(uint32_t); 520b57cec5SDimitry Andric if (auto EC = Msf.setStreamSize(StreamPDB, Length)) 530b57cec5SDimitry Andric return EC; 540b57cec5SDimitry Andric return Error::success(); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout, 580b57cec5SDimitry Andric WritableBinaryStreamRef Buffer) const { 59*5f757f3fSDimitry Andric llvm::TimeTraceScope timeScope("Commit info stream"); 600b57cec5SDimitry Andric auto InfoS = WritableMappedBlockStream::createIndexedStream( 610b57cec5SDimitry Andric Layout, Buffer, StreamPDB, Msf.getAllocator()); 620b57cec5SDimitry Andric BinaryStreamWriter Writer(*InfoS); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric InfoStreamHeader H; 650b57cec5SDimitry Andric // Leave the build id fields 0 so they can be set as the last step before 660b57cec5SDimitry Andric // committing the file to disk. 670b57cec5SDimitry Andric ::memset(&H, 0, sizeof(H)); 680b57cec5SDimitry Andric H.Version = Ver; 690b57cec5SDimitry Andric if (auto EC = Writer.writeObject(H)) 700b57cec5SDimitry Andric return EC; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric if (auto EC = NamedStreams.commit(Writer)) 730b57cec5SDimitry Andric return EC; 740b57cec5SDimitry Andric if (auto EC = Writer.writeInteger(0)) 750b57cec5SDimitry Andric return EC; 760b57cec5SDimitry Andric for (auto E : Features) { 770b57cec5SDimitry Andric if (auto EC = Writer.writeEnum(E)) 780b57cec5SDimitry Andric return EC; 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric assert(Writer.bytesRemaining() == 0); 810b57cec5SDimitry Andric return Error::success(); 820b57cec5SDimitry Andric } 83