1 //===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
11 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
12 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
13 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
14 #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
15 #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
16 #include "llvm/DebugInfo/PDB/Native/RawError.h"
17 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
18 #include "llvm/Support/BinaryStreamWriter.h"
21 using namespace llvm::codeview
;
22 using namespace llvm::msf
;
23 using namespace llvm::pdb
;
25 InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder
&Msf
,
26 NamedStreamMap
&NamedStreams
)
27 : Msf(Msf
), Ver(PdbRaw_ImplVer::PdbImplVC70
), Age(0),
28 NamedStreams(NamedStreams
) {
29 ::memset(&Guid
, 0, sizeof(Guid
));
32 void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V
) { Ver
= V
; }
34 void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig
) {
35 Features
.push_back(Sig
);
38 void InfoStreamBuilder::setHashPDBContentsToGUID(bool B
) {
39 HashPDBContentsToGUID
= B
;
42 void InfoStreamBuilder::setAge(uint32_t A
) { Age
= A
; }
44 void InfoStreamBuilder::setSignature(uint32_t S
) { Signature
= S
; }
46 void InfoStreamBuilder::setGuid(GUID G
) { Guid
= G
; }
49 Error
InfoStreamBuilder::finalizeMsfLayout() {
50 uint32_t Length
= sizeof(InfoStreamHeader
) +
51 NamedStreams
.calculateSerializedLength() +
52 (Features
.size() + 1) * sizeof(uint32_t);
53 if (auto EC
= Msf
.setStreamSize(StreamPDB
, Length
))
55 return Error::success();
58 Error
InfoStreamBuilder::commit(const msf::MSFLayout
&Layout
,
59 WritableBinaryStreamRef Buffer
) const {
60 auto InfoS
= WritableMappedBlockStream::createIndexedStream(
61 Layout
, Buffer
, StreamPDB
, Msf
.getAllocator());
62 BinaryStreamWriter
Writer(*InfoS
);
65 // Leave the build id fields 0 so they can be set as the last step before
66 // committing the file to disk.
67 ::memset(&H
, 0, sizeof(H
));
69 if (auto EC
= Writer
.writeObject(H
))
72 if (auto EC
= NamedStreams
.commit(Writer
))
74 if (auto EC
= Writer
.writeInteger(0))
76 for (auto E
: Features
) {
77 if (auto EC
= Writer
.writeEnum(E
))
80 assert(Writer
.bytesRemaining() == 0);
81 return Error::success();