Coverage Report

Created: 2017-01-25 15:12

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
Line
Count
Source (jump to first uncovered line)
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
10
#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
11
12
#include "llvm/ADT/BitVector.h"
13
14
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
15
#include "llvm/DebugInfo/MSF/StreamInterface.h"
16
#include "llvm/DebugInfo/MSF/StreamWriter.h"
17
#include "llvm/DebugInfo/PDB/GenericError.h"
18
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
19
#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
20
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
21
#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
22
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
23
#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
24
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
25
#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
26
27
using namespace llvm;
28
using namespace llvm::codeview;
29
using namespace llvm::msf;
30
using namespace llvm::pdb;
31
using namespace llvm::support;
32
33
PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
34
4
    : Allocator(Allocator) {}
35
36
4
Error PDBFileBuilder::initialize(uint32_t BlockSize) {
37
4
  auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
38
4
  if (!ExpectedMsf)
39
0
    return ExpectedMsf.takeError();
40
4
  Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
41
4
  return Error::success();
42
4
}
43
44
20
MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
45
46
4
InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
47
4
  if (!Info)
48
4
    Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
49
4
  return *Info;
50
4
}
51
52
3
DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
53
3
  if (!Dbi)
54
3
    Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
55
3
  return *Dbi;
56
3
}
57
58
4
TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
59
4
  if (!Tpi)
60
4
    Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
61
4
  return *Tpi;
62
4
}
63
64
2
TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
65
2
  if (!Ipi)
66
2
    Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
67
2
  return *Ipi;
68
2
}
69
70
1
StringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; }
71
72
12
Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
73
12
  auto ExpectedStream = Msf->addStream(Size);
74
12
  if (!ExpectedStream)
75
0
    return ExpectedStream.takeError();
76
12
  NamedStreams.set(Name, *ExpectedStream);
77
12
  return Error::success();
78
12
}
79
80
4
Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
81
4
  uint32_t StringTableSize = Strings.finalize();
82
4
83
4
  if (auto EC = addNamedStream("/names", StringTableSize))
84
0
    return std::move(EC);
85
4
  
if (auto 4
EC4
= addNamedStream("/LinkInfo", 0))
86
0
    return std::move(EC);
87
4
  
if (auto 4
EC4
= addNamedStream("/src/headerblock", 0))
88
0
    return std::move(EC);
89
4
90
4
  
if (4
Info4
)
{4
91
4
    if (auto EC = Info->finalizeMsfLayout())
92
0
      return std::move(EC);
93
4
  }
94
4
  
if (4
Dbi4
)
{3
95
3
    if (auto EC = Dbi->finalizeMsfLayout())
96
0
      return std::move(EC);
97
3
  }
98
4
  
if (4
Tpi4
)
{4
99
4
    if (auto EC = Tpi->finalizeMsfLayout())
100
0
      return std::move(EC);
101
4
  }
102
4
  
if (4
Ipi4
)
{2
103
2
    if (auto EC = Ipi->finalizeMsfLayout())
104
0
      return std::move(EC);
105
2
  }
106
4
107
4
  return Msf->build();
108
4
}
109
110
4
Error PDBFileBuilder::commit(StringRef Filename) {
111
4
  auto ExpectedLayout = finalizeMsfLayout();
112
4
  if (!ExpectedLayout)
113
0
    return ExpectedLayout.takeError();
114
4
  auto &Layout = *ExpectedLayout;
115
4
116
4
  uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
117
4
  auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize);
118
4
  if (OutFileOrError.getError())
119
0
    return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path,
120
0
                                               Filename);
121
4
  FileBufferByteStream Buffer(std::move(*OutFileOrError));
122
4
  StreamWriter Writer(Buffer);
123
4
124
4
  if (auto EC = Writer.writeObject(*Layout.SB))
125
0
    return EC;
126
4
  uint32_t BlockMapOffset =
127
4
      msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
128
4
  Writer.setOffset(BlockMapOffset);
129
4
  if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
130
0
    return EC;
131
4
132
4
  auto DirStream =
133
4
      WritableMappedBlockStream::createDirectoryStream(Layout, Buffer);
134
4
  StreamWriter DW(*DirStream);
135
4
  if (auto EC =
136
4
          DW.writeInteger(static_cast<uint32_t>(Layout.StreamSizes.size())))
137
0
    return EC;
138
4
139
4
  
if (auto 4
EC4
= DW.writeArray(Layout.StreamSizes))
140
0
    return EC;
141
4
142
34
  
for (const auto &Blocks : Layout.StreamMap) 4
{34
143
34
    if (auto EC = DW.writeArray(Blocks))
144
0
      return EC;
145
34
  }
146
4
147
4
  uint32_t StringTableStreamNo = 0;
148
4
  if (!NamedStreams.get("/names", StringTableStreamNo))
149
0
    return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
150
4
151
4
  auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
152
4
                                                           StringTableStreamNo);
153
4
  StreamWriter NSWriter(*NS);
154
4
  if (auto EC = Strings.commit(NSWriter))
155
0
    return EC;
156
4
157
4
  
if (4
Info4
)
{4
158
4
    if (auto EC = Info->commit(Layout, Buffer))
159
0
      return EC;
160
4
  }
161
4
162
4
  
if (4
Dbi4
)
{3
163
3
    if (auto EC = Dbi->commit(Layout, Buffer))
164
0
      return EC;
165
3
  }
166
4
167
4
  
if (4
Tpi4
)
{4
168
4
    if (auto EC = Tpi->commit(Layout, Buffer))
169
0
      return EC;
170
4
  }
171
4
172
4
  
if (4
Ipi4
)
{2
173
2
    if (auto EC = Ipi->commit(Layout, Buffer))
174
0
      return EC;
175
2
  }
176
4
177
4
  return Buffer.commit();
178
4
}