Home | History | Annotate | Download | only in Raw
      1 //===- PDBFile.h - Low level interface to a PDB file ------------*- 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 #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
     11 #define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/DebugInfo/CodeView/StreamArray.h"
     15 #include "llvm/DebugInfo/CodeView/StreamInterface.h"
     16 #include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
     17 #include "llvm/Support/Allocator.h"
     18 #include "llvm/Support/Endian.h"
     19 #include "llvm/Support/Error.h"
     20 #include "llvm/Support/MathExtras.h"
     21 
     22 #include <memory>
     23 
     24 namespace llvm {
     25 
     26 namespace codeview {
     27 class StreamInterface;
     28 }
     29 
     30 namespace pdb {
     31 class DbiStream;
     32 class InfoStream;
     33 class MappedBlockStream;
     34 class NameHashTable;
     35 class PDBFileBuilder;
     36 class PublicsStream;
     37 class SymbolStream;
     38 class TpiStream;
     39 
     40 static const char MsfMagic[] = {'M',  'i',  'c',    'r', 'o', 's',  'o',  'f',
     41                                 't',  ' ',  'C',    '/', 'C', '+',  '+',  ' ',
     42                                 'M',  'S',  'F',    ' ', '7', '.',  '0',  '0',
     43                                 '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
     44 
     45 class PDBFile : public IPDBFile {
     46   friend PDBFileBuilder;
     47 
     48 public:
     49   // The superblock is overlaid at the beginning of the file (offset 0).
     50   // It starts with a magic header and is followed by information which
     51   // describes the layout of the file system.
     52   struct SuperBlock {
     53     char MagicBytes[sizeof(MsfMagic)];
     54     // The file system is split into a variable number of fixed size elements.
     55     // These elements are referred to as blocks.  The size of a block may vary
     56     // from system to system.
     57     support::ulittle32_t BlockSize;
     58     // This field's purpose is not yet known.
     59     support::ulittle32_t Unknown0;
     60     // This contains the number of blocks resident in the file system.  In
     61     // practice, NumBlocks * BlockSize is equivalent to the size of the PDB
     62     // file.
     63     support::ulittle32_t NumBlocks;
     64     // This contains the number of bytes which make up the directory.
     65     support::ulittle32_t NumDirectoryBytes;
     66     // This field's purpose is not yet known.
     67     support::ulittle32_t Unknown1;
     68     // This contains the block # of the block map.
     69     support::ulittle32_t BlockMapAddr;
     70   };
     71 
     72   explicit PDBFile(std::unique_ptr<codeview::StreamInterface> PdbFileBuffer);
     73   ~PDBFile() override;
     74 
     75   uint32_t getUnknown0() const;
     76   uint32_t getUnknown1() const;
     77 
     78   uint32_t getBlockSize() const override;
     79   uint32_t getBlockCount() const override;
     80   uint32_t getNumDirectoryBytes() const;
     81   uint32_t getBlockMapIndex() const;
     82   uint32_t getNumDirectoryBlocks() const;
     83   uint64_t getBlockMapOffset() const;
     84 
     85   uint32_t getNumStreams() const override;
     86   uint32_t getStreamByteSize(uint32_t StreamIndex) const override;
     87   ArrayRef<support::ulittle32_t>
     88   getStreamBlockList(uint32_t StreamIndex) const override;
     89   uint32_t getFileSize() const;
     90 
     91   Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
     92                                            uint32_t NumBytes) const override;
     93   Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
     94                      ArrayRef<uint8_t> Data) const override;
     95 
     96   ArrayRef<support::ulittle32_t> getStreamSizes() const { return StreamSizes; }
     97   ArrayRef<ArrayRef<support::ulittle32_t>> getStreamMap() const {
     98     return StreamMap;
     99   }
    100 
    101   ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
    102 
    103   Error parseFileHeaders();
    104   Error parseStreamData();
    105 
    106   static uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) {
    107     return alignTo(NumBytes, BlockSize) / BlockSize;
    108   }
    109 
    110   static uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) {
    111     return BlockNumber * BlockSize;
    112   }
    113 
    114   Expected<InfoStream &> getPDBInfoStream();
    115   Expected<DbiStream &> getPDBDbiStream();
    116   Expected<TpiStream &> getPDBTpiStream();
    117   Expected<TpiStream &> getPDBIpiStream();
    118   Expected<PublicsStream &> getPDBPublicsStream();
    119   Expected<SymbolStream &> getPDBSymbolStream();
    120   Expected<NameHashTable &> getStringTable();
    121 
    122   Error commit();
    123 
    124 private:
    125   Error setSuperBlock(const SuperBlock *Block);
    126 
    127   BumpPtrAllocator Allocator;
    128 
    129   std::unique_ptr<codeview::StreamInterface> Buffer;
    130   const PDBFile::SuperBlock *SB;
    131   ArrayRef<support::ulittle32_t> StreamSizes;
    132   ArrayRef<support::ulittle32_t> DirectoryBlocks;
    133   std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
    134 
    135   std::unique_ptr<InfoStream> Info;
    136   std::unique_ptr<DbiStream> Dbi;
    137   std::unique_ptr<TpiStream> Tpi;
    138   std::unique_ptr<TpiStream> Ipi;
    139   std::unique_ptr<PublicsStream> Publics;
    140   std::unique_ptr<SymbolStream> Symbols;
    141   std::unique_ptr<MappedBlockStream> DirectoryStream;
    142   std::unique_ptr<MappedBlockStream> StringTableStream;
    143   std::unique_ptr<NameHashTable> StringTable;
    144 };
    145 }
    146 }
    147 
    148 #endif
    149