LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Raw - PDBFileBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 77 99 77.8 %
Date: 2017-01-24 23:09:07 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           4 : PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
      34          28 :     : Allocator(Allocator) {}
      35             : 
      36           4 : Error PDBFileBuilder::initialize(uint32_t BlockSize) {
      37           8 :   auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
      38           4 :   if (!ExpectedMsf)
      39           0 :     return ExpectedMsf.takeError();
      40           8 :   Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
      41          12 :   return Error::success();
      42             : }
      43             : 
      44          40 : MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
      45             : 
      46           4 : InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
      47           8 :   if (!Info)
      48          12 :     Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
      49           8 :   return *Info;
      50             : }
      51             : 
      52           3 : DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
      53           6 :   if (!Dbi)
      54           9 :     Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
      55           6 :   return *Dbi;
      56             : }
      57             : 
      58           4 : TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
      59           8 :   if (!Tpi)
      60          12 :     Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
      61           8 :   return *Tpi;
      62             : }
      63             : 
      64           2 : TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
      65           4 :   if (!Ipi)
      66           6 :     Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
      67           4 :   return *Ipi;
      68             : }
      69             : 
      70           1 : StringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; }
      71             : 
      72          12 : Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
      73          36 :   auto ExpectedStream = Msf->addStream(Size);
      74          12 :   if (!ExpectedStream)
      75           0 :     return ExpectedStream.takeError();
      76          12 :   NamedStreams.set(Name, *ExpectedStream);
      77          36 :   return Error::success();
      78             : }
      79             : 
      80           4 : Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
      81           4 :   uint32_t StringTableSize = Strings.finalize();
      82             : 
      83           8 :   if (auto EC = addNamedStream("/names", StringTableSize))
      84           0 :     return std::move(EC);
      85          12 :   if (auto EC = addNamedStream("/LinkInfo", 0))
      86           0 :     return std::move(EC);
      87          12 :   if (auto EC = addNamedStream("/src/headerblock", 0))
      88           0 :     return std::move(EC);
      89             : 
      90           8 :   if (Info) {
      91          16 :     if (auto EC = Info->finalizeMsfLayout())
      92           0 :       return std::move(EC);
      93             :   }
      94           8 :   if (Dbi) {
      95          12 :     if (auto EC = Dbi->finalizeMsfLayout())
      96           0 :       return std::move(EC);
      97             :   }
      98           8 :   if (Tpi) {
      99          16 :     if (auto EC = Tpi->finalizeMsfLayout())
     100           0 :       return std::move(EC);
     101             :   }
     102           8 :   if (Ipi) {
     103           8 :     if (auto EC = Ipi->finalizeMsfLayout())
     104           0 :       return std::move(EC);
     105             :   }
     106             : 
     107           8 :   return Msf->build();
     108             : }
     109             : 
     110           4 : Error PDBFileBuilder::commit(StringRef Filename) {
     111           8 :   auto ExpectedLayout = finalizeMsfLayout();
     112           4 :   if (!ExpectedLayout)
     113           0 :     return ExpectedLayout.takeError();
     114           4 :   auto &Layout = *ExpectedLayout;
     115             : 
     116          12 :   uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
     117           4 :   auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize);
     118           4 :   if (OutFileOrError.getError())
     119             :     return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path,
     120           0 :                                                Filename);
     121           8 :   FileBufferByteStream Buffer(std::move(*OutFileOrError));
     122           4 :   StreamWriter Writer(Buffer);
     123             : 
     124          16 :   if (auto EC = Writer.writeObject(*Layout.SB))
     125           0 :     return EC;
     126             :   uint32_t BlockMapOffset =
     127          16 :       msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
     128           8 :   Writer.setOffset(BlockMapOffset);
     129          12 :   if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
     130           0 :     return EC;
     131             : 
     132             :   auto DirStream =
     133           4 :       WritableMappedBlockStream::createDirectoryStream(Layout, Buffer);
     134           8 :   StreamWriter DW(*DirStream);
     135           4 :   if (auto EC =
     136           8 :           DW.writeInteger(static_cast<uint32_t>(Layout.StreamSizes.size())))
     137           0 :     return EC;
     138             : 
     139          12 :   if (auto EC = DW.writeArray(Layout.StreamSizes))
     140           0 :     return EC;
     141             : 
     142          50 :   for (const auto &Blocks : Layout.StreamMap) {
     143         102 :     if (auto EC = DW.writeArray(Blocks))
     144           0 :       return EC;
     145             :   }
     146             : 
     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             : 
     151             :   auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
     152           4 :                                                            StringTableStreamNo);
     153           8 :   StreamWriter NSWriter(*NS);
     154          12 :   if (auto EC = Strings.commit(NSWriter))
     155           0 :     return EC;
     156             : 
     157           8 :   if (Info) {
     158          16 :     if (auto EC = Info->commit(Layout, Buffer))
     159           0 :       return EC;
     160             :   }
     161             : 
     162           8 :   if (Dbi) {
     163          12 :     if (auto EC = Dbi->commit(Layout, Buffer))
     164           0 :       return EC;
     165             :   }
     166             : 
     167           8 :   if (Tpi) {
     168          16 :     if (auto EC = Tpi->commit(Layout, Buffer))
     169           0 :       return EC;
     170             :   }
     171             : 
     172           8 :   if (Ipi) {
     173           8 :     if (auto EC = Ipi->commit(Layout, Buffer))
     174           0 :       return EC;
     175             :   }
     176             : 
     177             :   return Buffer.commit();
     178             : }

Generated by: LCOV version 1.13