xref: /aosp_15_r20/external/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
11*9880d681SAndroid Build Coastguard Worker 
12*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/CodeView/StreamInterface.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/CodeView/StreamWriter.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/Raw/RawError.h"
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker using namespace llvm::codeview;
22*9880d681SAndroid Build Coastguard Worker using namespace llvm::pdb;
23*9880d681SAndroid Build Coastguard Worker 
PDBFileBuilder(std::unique_ptr<codeview::StreamInterface> PdbFileBuffer)24*9880d681SAndroid Build Coastguard Worker PDBFileBuilder::PDBFileBuilder(
25*9880d681SAndroid Build Coastguard Worker     std::unique_ptr<codeview::StreamInterface> PdbFileBuffer)
26*9880d681SAndroid Build Coastguard Worker     : File(llvm::make_unique<PDBFile>(std::move(PdbFileBuffer))) {}
27*9880d681SAndroid Build Coastguard Worker 
setSuperBlock(const PDBFile::SuperBlock & B)28*9880d681SAndroid Build Coastguard Worker Error PDBFileBuilder::setSuperBlock(const PDBFile::SuperBlock &B) {
29*9880d681SAndroid Build Coastguard Worker   auto SB = static_cast<PDBFile::SuperBlock *>(
30*9880d681SAndroid Build Coastguard Worker       File->Allocator.Allocate(sizeof(PDBFile::SuperBlock),
31*9880d681SAndroid Build Coastguard Worker                                llvm::AlignOf<PDBFile::SuperBlock>::Alignment));
32*9880d681SAndroid Build Coastguard Worker   ::memcpy(SB, &B, sizeof(PDBFile::SuperBlock));
33*9880d681SAndroid Build Coastguard Worker   return File->setSuperBlock(SB);
34*9880d681SAndroid Build Coastguard Worker }
35*9880d681SAndroid Build Coastguard Worker 
setStreamSizes(ArrayRef<support::ulittle32_t> S)36*9880d681SAndroid Build Coastguard Worker void PDBFileBuilder::setStreamSizes(ArrayRef<support::ulittle32_t> S) {
37*9880d681SAndroid Build Coastguard Worker   File->StreamSizes = S;
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker 
setDirectoryBlocks(ArrayRef<support::ulittle32_t> D)40*9880d681SAndroid Build Coastguard Worker void PDBFileBuilder::setDirectoryBlocks(ArrayRef<support::ulittle32_t> D) {
41*9880d681SAndroid Build Coastguard Worker   File->DirectoryBlocks = D;
42*9880d681SAndroid Build Coastguard Worker }
43*9880d681SAndroid Build Coastguard Worker 
setStreamMap(const std::vector<ArrayRef<support::ulittle32_t>> & S)44*9880d681SAndroid Build Coastguard Worker void PDBFileBuilder::setStreamMap(
45*9880d681SAndroid Build Coastguard Worker     const std::vector<ArrayRef<support::ulittle32_t>> &S) {
46*9880d681SAndroid Build Coastguard Worker   File->StreamMap = S;
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker 
generateSimpleStreamMap()49*9880d681SAndroid Build Coastguard Worker Error PDBFileBuilder::generateSimpleStreamMap() {
50*9880d681SAndroid Build Coastguard Worker   if (File->StreamSizes.empty())
51*9880d681SAndroid Build Coastguard Worker     return Error::success();
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker   static std::vector<std::vector<support::ulittle32_t>> StaticMap;
54*9880d681SAndroid Build Coastguard Worker   File->StreamMap.clear();
55*9880d681SAndroid Build Coastguard Worker   StaticMap.clear();
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker   // Figure out how many blocks are needed for all streams, and set the first
58*9880d681SAndroid Build Coastguard Worker   // used block to the highest block so that we can write the rest of the
59*9880d681SAndroid Build Coastguard Worker   // blocks contiguously.
60*9880d681SAndroid Build Coastguard Worker   uint32_t TotalFileBlocks = File->getBlockCount();
61*9880d681SAndroid Build Coastguard Worker   std::vector<support::ulittle32_t> ReservedBlocks;
62*9880d681SAndroid Build Coastguard Worker   ReservedBlocks.push_back(support::ulittle32_t(0));
63*9880d681SAndroid Build Coastguard Worker   ReservedBlocks.push_back(File->SB->BlockMapAddr);
64*9880d681SAndroid Build Coastguard Worker   ReservedBlocks.insert(ReservedBlocks.end(), File->DirectoryBlocks.begin(),
65*9880d681SAndroid Build Coastguard Worker                         File->DirectoryBlocks.end());
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   uint32_t BlocksNeeded = 0;
68*9880d681SAndroid Build Coastguard Worker   for (auto Size : File->StreamSizes)
69*9880d681SAndroid Build Coastguard Worker     BlocksNeeded += File->bytesToBlocks(Size, File->getBlockSize());
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded -
72*9880d681SAndroid Build Coastguard Worker                                  ReservedBlocks.size());
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   StaticMap.resize(File->StreamSizes.size());
75*9880d681SAndroid Build Coastguard Worker   for (uint32_t S = 0; S < File->StreamSizes.size(); ++S) {
76*9880d681SAndroid Build Coastguard Worker     uint32_t Size = File->StreamSizes[S];
77*9880d681SAndroid Build Coastguard Worker     uint32_t NumBlocks = File->bytesToBlocks(Size, File->getBlockSize());
78*9880d681SAndroid Build Coastguard Worker     auto &ThisStream = StaticMap[S];
79*9880d681SAndroid Build Coastguard Worker     for (uint32_t I = 0; I < NumBlocks;) {
80*9880d681SAndroid Build Coastguard Worker       NextBlock += 1;
81*9880d681SAndroid Build Coastguard Worker       if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) !=
82*9880d681SAndroid Build Coastguard Worker           ReservedBlocks.end())
83*9880d681SAndroid Build Coastguard Worker         continue;
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker       ++I;
86*9880d681SAndroid Build Coastguard Worker       assert(NextBlock < File->getBlockCount());
87*9880d681SAndroid Build Coastguard Worker       ThisStream.push_back(NextBlock);
88*9880d681SAndroid Build Coastguard Worker     }
89*9880d681SAndroid Build Coastguard Worker     File->StreamMap.push_back(ThisStream);
90*9880d681SAndroid Build Coastguard Worker   }
91*9880d681SAndroid Build Coastguard Worker   return Error::success();
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker 
getInfoBuilder()94*9880d681SAndroid Build Coastguard Worker InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
95*9880d681SAndroid Build Coastguard Worker   if (!Info)
96*9880d681SAndroid Build Coastguard Worker     Info = llvm::make_unique<InfoStreamBuilder>(*File);
97*9880d681SAndroid Build Coastguard Worker   return *Info;
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker 
getDbiBuilder()100*9880d681SAndroid Build Coastguard Worker DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
101*9880d681SAndroid Build Coastguard Worker   if (!Dbi)
102*9880d681SAndroid Build Coastguard Worker     Dbi = llvm::make_unique<DbiStreamBuilder>(*File);
103*9880d681SAndroid Build Coastguard Worker   return *Dbi;
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker 
build()106*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<PDBFile>> PDBFileBuilder::build() {
107*9880d681SAndroid Build Coastguard Worker   if (Info) {
108*9880d681SAndroid Build Coastguard Worker     auto ExpectedInfo = Info->build();
109*9880d681SAndroid Build Coastguard Worker     if (!ExpectedInfo)
110*9880d681SAndroid Build Coastguard Worker       return ExpectedInfo.takeError();
111*9880d681SAndroid Build Coastguard Worker     File->Info = std::move(*ExpectedInfo);
112*9880d681SAndroid Build Coastguard Worker   }
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   if (Dbi) {
115*9880d681SAndroid Build Coastguard Worker     auto ExpectedDbi = Dbi->build();
116*9880d681SAndroid Build Coastguard Worker     if (!ExpectedDbi)
117*9880d681SAndroid Build Coastguard Worker       return ExpectedDbi.takeError();
118*9880d681SAndroid Build Coastguard Worker     File->Dbi = std::move(*ExpectedDbi);
119*9880d681SAndroid Build Coastguard Worker   }
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   if (File->Info && File->Dbi && File->Info->getAge() != File->Dbi->getAge())
122*9880d681SAndroid Build Coastguard Worker     return llvm::make_error<RawError>(
123*9880d681SAndroid Build Coastguard Worker         raw_error_code::corrupt_file,
124*9880d681SAndroid Build Coastguard Worker         "PDB Stream Age doesn't match Dbi Stream Age!");
125*9880d681SAndroid Build Coastguard Worker 
126*9880d681SAndroid Build Coastguard Worker   return std::move(File);
127*9880d681SAndroid Build Coastguard Worker }
128