• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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