16b6b8c4fSAdrian McCarthy //===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
26b6b8c4fSAdrian McCarthy //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66b6b8c4fSAdrian McCarthy //
76b6b8c4fSAdrian McCarthy //===----------------------------------------------------------------------===//
86b6b8c4fSAdrian McCarthy
96b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
106b6b8c4fSAdrian McCarthy
116b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/MSF/MSFBuilder.h"
126b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
136b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
146b6b8c4fSAdrian McCarthy #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
15*ed98c1b3Sserge-sans-paille #include "llvm/Support/BinaryStreamReader.h"
16d9dc2829SZachary Turner #include "llvm/Support/BinaryStreamWriter.h"
176b6b8c4fSAdrian McCarthy
186b6b8c4fSAdrian McCarthy using namespace llvm;
196b6b8c4fSAdrian McCarthy using namespace llvm::codeview;
206b6b8c4fSAdrian McCarthy using namespace llvm::msf;
216b6b8c4fSAdrian McCarthy using namespace llvm::pdb;
226b6b8c4fSAdrian McCarthy
InfoStreamBuilder(msf::MSFBuilder & Msf,NamedStreamMap & NamedStreams)236b6b8c4fSAdrian McCarthy InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
246b6b8c4fSAdrian McCarthy NamedStreamMap &NamedStreams)
25c6a75a69SZachary Turner : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Age(0),
26c6a75a69SZachary Turner NamedStreams(NamedStreams) {
27c6a75a69SZachary Turner ::memset(&Guid, 0, sizeof(Guid));
28c6a75a69SZachary Turner }
296b6b8c4fSAdrian McCarthy
setVersion(PdbRaw_ImplVer V)306b6b8c4fSAdrian McCarthy void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
316b6b8c4fSAdrian McCarthy
addFeature(PdbRaw_FeatureSig Sig)32205ca68bSNico Weber void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
33205ca68bSNico Weber Features.push_back(Sig);
34205ca68bSNico Weber }
35205ca68bSNico Weber
setHashPDBContentsToGUID(bool B)36205ca68bSNico Weber void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) {
37205ca68bSNico Weber HashPDBContentsToGUID = B;
38205ca68bSNico Weber }
39205ca68bSNico Weber
setAge(uint32_t A)406b6b8c4fSAdrian McCarthy void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
416b6b8c4fSAdrian McCarthy
setSignature(uint32_t S)42c6a75a69SZachary Turner void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; }
43c6a75a69SZachary Turner
setGuid(GUID G)4467653ee0SReid Kleckner void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
456b6b8c4fSAdrian McCarthy
4605d5e613SZachary Turner
finalizeMsfLayout()476b6b8c4fSAdrian McCarthy Error InfoStreamBuilder::finalizeMsfLayout() {
48cafd4768SZachary Turner uint32_t Length = sizeof(InfoStreamHeader) +
49cafd4768SZachary Turner NamedStreams.calculateSerializedLength() +
5005d5e613SZachary Turner (Features.size() + 1) * sizeof(uint32_t);
516b6b8c4fSAdrian McCarthy if (auto EC = Msf.setStreamSize(StreamPDB, Length))
526b6b8c4fSAdrian McCarthy return EC;
536b6b8c4fSAdrian McCarthy return Error::success();
546b6b8c4fSAdrian McCarthy }
556b6b8c4fSAdrian McCarthy
commit(const msf::MSFLayout & Layout,WritableBinaryStreamRef Buffer) const566b6b8c4fSAdrian McCarthy Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout,
57120faca4SZachary Turner WritableBinaryStreamRef Buffer) const {
585b74ff33SZachary Turner auto InfoS = WritableMappedBlockStream::createIndexedStream(
595b74ff33SZachary Turner Layout, Buffer, StreamPDB, Msf.getAllocator());
60120faca4SZachary Turner BinaryStreamWriter Writer(*InfoS);
616b6b8c4fSAdrian McCarthy
626b6b8c4fSAdrian McCarthy InfoStreamHeader H;
63c6a75a69SZachary Turner // Leave the build id fields 0 so they can be set as the last step before
64c6a75a69SZachary Turner // committing the file to disk.
65c6a75a69SZachary Turner ::memset(&H, 0, sizeof(H));
666b6b8c4fSAdrian McCarthy H.Version = Ver;
676b6b8c4fSAdrian McCarthy if (auto EC = Writer.writeObject(H))
686b6b8c4fSAdrian McCarthy return EC;
696b6b8c4fSAdrian McCarthy
7005d5e613SZachary Turner if (auto EC = NamedStreams.commit(Writer))
7105d5e613SZachary Turner return EC;
7205d5e613SZachary Turner if (auto EC = Writer.writeInteger(0))
7305d5e613SZachary Turner return EC;
7405d5e613SZachary Turner for (auto E : Features) {
7505d5e613SZachary Turner if (auto EC = Writer.writeEnum(E))
7605d5e613SZachary Turner return EC;
7705d5e613SZachary Turner }
78a6fb536eSZachary Turner assert(Writer.bytesRemaining() == 0);
7905d5e613SZachary Turner return Error::success();
806b6b8c4fSAdrian McCarthy }
81