blob: 9063fd62d2953f80a818177713dfdd7834c6c464 [file] [log] [blame]
Zachary Turnerdbeaea72016-07-11 21:45:26 +00001//===- 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
Zachary Turnerfaa554b2016-07-15 22:16:56 +000012#include "llvm/ADT/BitVector.h"
13
Zachary Turnerdbeaea72016-07-11 21:45:26 +000014#include "llvm/DebugInfo/CodeView/StreamInterface.h"
15#include "llvm/DebugInfo/CodeView/StreamWriter.h"
16#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
17#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
18#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
19#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
20#include "llvm/DebugInfo/PDB/Raw/RawError.h"
21
22using namespace llvm;
23using namespace llvm::codeview;
24using namespace llvm::pdb;
Zachary Turnerfaa554b2016-07-15 22:16:56 +000025using namespace llvm::support;
Zachary Turnerdbeaea72016-07-11 21:45:26 +000026
27PDBFileBuilder::PDBFileBuilder(
Zachary Turnerfaa554b2016-07-15 22:16:56 +000028 std::unique_ptr<codeview::StreamInterface> FileBuffer)
29 : File(llvm::make_unique<PDBFile>(std::move(FileBuffer))) {}
Zachary Turnerdbeaea72016-07-11 21:45:26 +000030
Zachary Turnerfaa554b2016-07-15 22:16:56 +000031Error PDBFileBuilder::initialize(const msf::SuperBlock &Super) {
32 auto ExpectedMsf =
33 MsfBuilder::create(File->Allocator, Super.BlockSize, Super.NumBlocks);
34 if (!ExpectedMsf)
35 return ExpectedMsf.takeError();
Zachary Turnerdbeaea72016-07-11 21:45:26 +000036
Zachary Turnerfaa554b2016-07-15 22:16:56 +000037 auto &MsfResult = *ExpectedMsf;
38 if (auto EC = MsfResult.setBlockMapAddr(Super.BlockMapAddr))
39 return EC;
Zachary Turnerfaa554b2016-07-15 22:16:56 +000040 Msf = llvm::make_unique<MsfBuilder>(std::move(MsfResult));
Zachary Turnerb927e022016-07-15 22:17:19 +000041 Msf->setFreePageMap(Super.FreeBlockMapBlock);
42 Msf->setUnknown1(Super.Unknown1);
Zachary Turnerdbeaea72016-07-11 21:45:26 +000043 return Error::success();
44}
45
Zachary Turnerfaa554b2016-07-15 22:16:56 +000046MsfBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
47
Zachary Turnerdbeaea72016-07-11 21:45:26 +000048InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
49 if (!Info)
Zachary Turnerfaa554b2016-07-15 22:16:56 +000050 Info = llvm::make_unique<InfoStreamBuilder>();
Zachary Turnerdbeaea72016-07-11 21:45:26 +000051 return *Info;
52}
53
54DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
55 if (!Dbi)
Zachary Turnerfaa554b2016-07-15 22:16:56 +000056 Dbi = llvm::make_unique<DbiStreamBuilder>();
Zachary Turnerdbeaea72016-07-11 21:45:26 +000057 return *Dbi;
58}
59
60Expected<std::unique_ptr<PDBFile>> PDBFileBuilder::build() {
61 if (Info) {
Zachary Turnerfaa554b2016-07-15 22:16:56 +000062 uint32_t Length = Info->calculateSerializedLength();
63 if (auto EC = Msf->setStreamSize(StreamPDB, Length))
64 return std::move(EC);
65 }
66 if (Dbi) {
67 uint32_t Length = Dbi->calculateSerializedLength();
68 if (auto EC = Msf->setStreamSize(StreamDBI, Length))
69 return std::move(EC);
70 }
71
72 auto ExpectedLayout = Msf->build();
73 if (!ExpectedLayout)
74 return ExpectedLayout.takeError();
75
76 const msf::Layout &L = *ExpectedLayout;
77 File->StreamMap = L.StreamMap;
78 File->StreamSizes = L.StreamSizes;
79 File->DirectoryBlocks = L.DirectoryBlocks;
80 File->SB = L.SB;
81
82 if (Info) {
83 auto ExpectedInfo = Info->build(*File);
Zachary Turnerdbeaea72016-07-11 21:45:26 +000084 if (!ExpectedInfo)
85 return ExpectedInfo.takeError();
86 File->Info = std::move(*ExpectedInfo);
87 }
88
89 if (Dbi) {
Zachary Turnerfaa554b2016-07-15 22:16:56 +000090 auto ExpectedDbi = Dbi->build(*File);
Zachary Turnerdbeaea72016-07-11 21:45:26 +000091 if (!ExpectedDbi)
92 return ExpectedDbi.takeError();
93 File->Dbi = std::move(*ExpectedDbi);
94 }
95
96 if (File->Info && File->Dbi && File->Info->getAge() != File->Dbi->getAge())
97 return llvm::make_error<RawError>(
98 raw_error_code::corrupt_file,
99 "PDB Stream Age doesn't match Dbi Stream Age!");
100
101 return std::move(File);
102}