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 getStreamSizes()96 ArrayRef<support::ulittle32_t> getStreamSizes() const { return StreamSizes; } getStreamMap()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 bytesToBlocks(uint64_t NumBytes,uint64_t BlockSize)106 static uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize) { 107 return alignTo(NumBytes, BlockSize) / BlockSize; 108 } 109 blockToOffset(uint64_t BlockNumber,uint64_t BlockSize)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