LLVM  4.0.0
PDBFileBuilder.cpp
Go to the documentation of this file.
1 //===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 
12 #include "llvm/ADT/BitVector.h"
13 
25 
26 using namespace llvm;
27 using namespace llvm::codeview;
28 using namespace llvm::msf;
29 using namespace llvm::pdb;
30 using namespace llvm::support;
31 
32 PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
33  : Allocator(Allocator) {}
34 
36  auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
37  if (!ExpectedMsf)
38  return ExpectedMsf.takeError();
39  Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
40  return Error::success();
41 }
42 
44 
46  if (!Info)
47  Info = llvm::make_unique<InfoStreamBuilder>(*Msf);
48  return *Info;
49 }
50 
52  if (!Dbi)
53  Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
54  return *Dbi;
55 }
56 
58  if (!Tpi)
59  Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
60  return *Tpi;
61 }
62 
64  if (!Ipi)
65  Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
66  return *Ipi;
67 }
68 
69 Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
70  if (Info) {
71  if (auto EC = Info->finalizeMsfLayout())
72  return std::move(EC);
73  }
74  if (Dbi) {
75  if (auto EC = Dbi->finalizeMsfLayout())
76  return std::move(EC);
77  }
78  if (Tpi) {
79  if (auto EC = Tpi->finalizeMsfLayout())
80  return std::move(EC);
81  }
82  if (Ipi) {
83  if (auto EC = Ipi->finalizeMsfLayout())
84  return std::move(EC);
85  }
86 
87  return Msf->build();
88 }
89 
91  auto ExpectedLayout = finalizeMsfLayout();
92  if (!ExpectedLayout)
93  return ExpectedLayout.takeError();
94  auto &Layout = *ExpectedLayout;
95 
96  uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
97  auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize);
98  if (OutFileOrError.getError())
99  return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path,
100  Filename);
101  FileBufferByteStream Buffer(std::move(*OutFileOrError));
102  StreamWriter Writer(Buffer);
103 
104  if (auto EC = Writer.writeObject(*Layout.SB))
105  return EC;
106  uint32_t BlockMapOffset =
107  msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
108  Writer.setOffset(BlockMapOffset);
109  if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
110  return EC;
111 
112  auto DirStream =
113  WritableMappedBlockStream::createDirectoryStream(Layout, Buffer);
114  StreamWriter DW(*DirStream);
115  if (auto EC =
116  DW.writeInteger(static_cast<uint32_t>(Layout.StreamSizes.size())))
117  return EC;
118 
119  if (auto EC = DW.writeArray(Layout.StreamSizes))
120  return EC;
121 
122  for (const auto &Blocks : Layout.StreamMap) {
123  if (auto EC = DW.writeArray(Blocks))
124  return EC;
125  }
126 
127  if (Info) {
128  if (auto EC = Info->commit(Layout, Buffer))
129  return EC;
130  }
131 
132  if (Dbi) {
133  if (auto EC = Dbi->commit(Layout, Buffer))
134  return EC;
135  }
136 
137  if (Tpi) {
138  if (auto EC = Tpi->commit(Layout, Buffer))
139  return EC;
140  }
141 
142  if (Ipi) {
143  if (auto EC = Ipi->commit(Layout, Buffer))
144  return EC;
145  }
146 
147  return Buffer.commit();
148 }
void setOffset(uint32_t Off)
Definition: StreamWriter.h:79
Error commit() const override
Definition: ByteStream.h:160
uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)
Definition: MSFCommon.h:83
DbiStreamBuilder & getDbiBuilder()
Tagged union holding either a T or a Error.
TpiStreamBuilder & getIpiBuilder()
Error writeObject(const T &Obj)
Definition: StreamWriter.h:49
Error commit(StringRef Filename)
Error initialize(uint32_t BlockSize)
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:138
Greedy Register Allocator
static ErrorOr< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
Error writeInteger(uint8_t Int)
static const int BlockSize
Definition: TarWriter.cpp:34
Error writeArray(ArrayRef< T > Array)
Definition: StreamWriter.h:58
static ErrorSuccess success()
Create a success value.
InfoStreamBuilder & getInfoBuilder()
msf::MSFBuilder & getMsfBuilder()
Lightweight error class with error context and mandatory checking.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
TpiStreamBuilder & getTpiBuilder()