LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Native - ModInfoBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 59 69 85.5 %
Date: 2017-04-27 17:53:54 Functions: 8 9 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ModInfoBuilder.cpp - PDB Module Info Stream 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/Native/ModInfoBuilder.h"
      11             : 
      12             : #include "llvm/ADT/ArrayRef.h"
      13             : #include "llvm/DebugInfo/MSF/MSFBuilder.h"
      14             : #include "llvm/DebugInfo/MSF/MSFCommon.h"
      15             : #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
      16             : #include "llvm/DebugInfo/PDB/Native/ModInfo.h"
      17             : #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
      18             : #include "llvm/DebugInfo/PDB/Native/RawError.h"
      19             : #include "llvm/Support/BinaryItemStream.h"
      20             : #include "llvm/Support/BinaryStreamWriter.h"
      21             : #include "llvm/Support/COFF.h"
      22             : 
      23             : using namespace llvm;
      24             : using namespace llvm::codeview;
      25             : using namespace llvm::msf;
      26             : using namespace llvm::pdb;
      27             : 
      28             : namespace llvm {
      29             : template <> struct BinaryItemTraits<CVSymbol> {
      30           1 :   static size_t length(const CVSymbol &Item) { return Item.RecordData.size(); }
      31             : 
      32             :   static ArrayRef<uint8_t> bytes(const CVSymbol &Item) {
      33             :     return Item.RecordData;
      34             :   }
      35             : };
      36             : }
      37             : 
      38             : static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize) {
      39          20 :   uint32_t Size = sizeof(uint32_t); // Signature
      40          20 :   Size += SymbolByteSize;           // Symbol Data
      41          20 :   Size += 0;                        // TODO: Layout.LineBytes
      42          20 :   Size += 0;                        // TODO: Layout.C13Bytes
      43          20 :   Size += sizeof(uint32_t);         // GlobalRefs substream size (always 0)
      44          20 :   Size += 0;                        // GlobalRefs substream bytes
      45             :   return Size;
      46             : }
      47             : 
      48          20 : ModInfoBuilder::ModInfoBuilder(StringRef ModuleName, uint32_t ModIndex,
      49          20 :                                msf::MSFBuilder &Msf)
      50         120 :     : MSF(Msf), ModuleName(ModuleName) {
      51          40 :   Layout.Mod = ModIndex;
      52          20 : }
      53             : 
      54           0 : uint16_t ModInfoBuilder::getStreamIndex() const { return Layout.ModDiStream; }
      55             : 
      56           3 : void ModInfoBuilder::setObjFileName(StringRef Name) { ObjFileName = Name; }
      57             : 
      58           1 : void ModInfoBuilder::addSymbol(CVSymbol Symbol) {
      59           1 :   Symbols.push_back(Symbol);
      60           1 :   SymbolByteSize += Symbol.data().size();
      61           1 : }
      62             : 
      63           1 : void ModInfoBuilder::addSourceFile(StringRef Path) {
      64           3 :   SourceFiles.push_back(Path);
      65           1 : }
      66             : 
      67          40 : uint32_t ModInfoBuilder::calculateSerializedLength() const {
      68          40 :   uint32_t L = sizeof(Layout);
      69          40 :   uint32_t M = ModuleName.size() + 1;
      70          40 :   uint32_t O = ObjFileName.size() + 1;
      71          80 :   return alignTo(L + M + O, sizeof(uint32_t));
      72             : }
      73             : 
      74          20 : void ModInfoBuilder::finalize() {
      75          40 :   Layout.C13Bytes = 0;
      76          40 :   Layout.FileNameOffs = 0; // TODO: Fix this
      77          40 :   Layout.Flags = 0;        // TODO: Fix this
      78          40 :   Layout.LineBytes = 0;
      79             :   (void)Layout.Mod;         // Set in constructor
      80             :   (void)Layout.ModDiStream; // Set in finalizeMsfLayout
      81          60 :   Layout.NumFiles = SourceFiles.size();
      82          40 :   Layout.PdbFilePathNI = 0;
      83          40 :   Layout.SrcFileNameNI = 0;
      84             : 
      85             :   // This value includes both the signature field as well as the record bytes
      86             :   // from the symbol stream.
      87          40 :   Layout.SymBytes = SymbolByteSize + sizeof(uint32_t);
      88          20 : }
      89             : 
      90          20 : Error ModInfoBuilder::finalizeMsfLayout() {
      91          40 :   this->Layout.ModDiStream = kInvalidStreamIndex;
      92          60 :   auto ExpectedSN = MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize));
      93          20 :   if (!ExpectedSN)
      94           0 :     return ExpectedSN.takeError();
      95          40 :   Layout.ModDiStream = *ExpectedSN;
      96          60 :   return Error::success();
      97             : }
      98             : 
      99          20 : Error ModInfoBuilder::commit(BinaryStreamWriter &ModiWriter,
     100             :                              const msf::MSFLayout &MsfLayout,
     101             :                              WritableBinaryStreamRef MsfBuffer) {
     102             :   // We write the Modi record to the `ModiWriter`, but we additionally write its
     103             :   // symbol stream to a brand new stream.
     104          80 :   if (auto EC = ModiWriter.writeObject(Layout))
     105           0 :     return EC;
     106          80 :   if (auto EC = ModiWriter.writeCString(ModuleName))
     107           0 :     return EC;
     108          80 :   if (auto EC = ModiWriter.writeCString(ObjFileName))
     109           0 :     return EC;
     110          60 :   if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
     111           0 :     return EC;
     112             : 
     113          40 :   if (Layout.ModDiStream != kInvalidStreamIndex) {
     114             :     auto NS = WritableMappedBlockStream::createIndexedStream(
     115          60 :         MsfLayout, MsfBuffer, Layout.ModDiStream);
     116          40 :     WritableBinaryStreamRef Ref(*NS);
     117          40 :     BinaryStreamWriter SymbolWriter(Ref);
     118             :     // Write the symbols.
     119          20 :     if (auto EC =
     120          40 :             SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
     121           0 :       return EC;
     122          40 :     BinaryItemStream<CVSymbol> Records(llvm::support::endianness::little);
     123          60 :     Records.setItems(Symbols);
     124          20 :     BinaryStreamRef RecordsRef(Records);
     125          60 :     if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
     126           0 :       return EC;
     127             :     // TODO: Write C11 Line data
     128             :     // TODO: Write C13 Line data
     129             :     // TODO: Figure out what GlobalRefs substream actually is and populate it.
     130          60 :     if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
     131           0 :       return EC;
     132          20 :     if (SymbolWriter.bytesRemaining() > 0)
     133           0 :       return make_error<RawError>(raw_error_code::stream_too_long);
     134             :   }
     135          60 :   return Error::success();
     136             : }

Generated by: LCOV version 1.13