• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- RawTypes.h -----------------------------------------------*- 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_RAWTYPES_H
11 #define LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
12 
13 #include "llvm/DebugInfo/CodeView/GUID.h"
14 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
15 #include "llvm/Support/Endian.h"
16 
17 namespace llvm {
18 namespace pdb {
19 // This struct is defined as "SO" in langapi/include/pdb.h.
20 struct SectionOffset {
21   support::ulittle32_t Off;
22   support::ulittle16_t Isect;
23   char Padding[2];
24 };
25 
26 /// Header of the hash tables found in the globals and publics sections.
27 /// Based on GSIHashHdr in
28 /// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
29 struct GSIHashHeader {
30   enum : unsigned {
31     HdrSignature = ~0U,
32     HdrVersion = 0xeffe0000 + 19990810,
33   };
34   support::ulittle32_t VerSignature;
35   support::ulittle32_t VerHdr;
36   support::ulittle32_t HrSize;
37   support::ulittle32_t NumBuckets;
38 };
39 
40 // This is HRFile.
41 struct PSHashRecord {
42   support::ulittle32_t Off; // Offset in the symbol record stream
43   support::ulittle32_t CRef;
44 };
45 
46 // This struct is defined as `SC` in include/dbicommon.h
47 struct SectionContrib {
48   support::ulittle16_t ISect;
49   char Padding[2];
50   support::little32_t Off;
51   support::little32_t Size;
52   support::ulittle32_t Characteristics;
53   support::ulittle16_t Imod;
54   char Padding2[2];
55   support::ulittle32_t DataCrc;
56   support::ulittle32_t RelocCrc;
57 };
58 
59 // This struct is defined as `SC2` in include/dbicommon.h
60 struct SectionContrib2 {
61   // To guarantee SectionContrib2 is standard layout, we cannot use inheritance.
62   SectionContrib Base;
63   support::ulittle32_t ISectCoff;
64 };
65 
66 // This corresponds to the `OMFSegMap` structure.
67 struct SecMapHeader {
68   support::ulittle16_t SecCount;    // Number of segment descriptors in table
69   support::ulittle16_t SecCountLog; // Number of logical segment descriptors
70 };
71 
72 // This corresponds to the `OMFSegMapDesc` structure.  The definition is not
73 // present in the reference implementation, but the layout is derived from
74 // code that accesses the fields.
75 struct SecMapEntry {
76   support::ulittle16_t Flags; // Descriptor flags.  See OMFSegDescFlags
77   support::ulittle16_t Ovl;   // Logical overlay number.
78   support::ulittle16_t Group; // Group index into descriptor array.
79   support::ulittle16_t Frame;
80   support::ulittle16_t SecName;       // Byte index of the segment or group name
81                                       // in the sstSegName table, or 0xFFFF.
82   support::ulittle16_t ClassName;     // Byte index of the class name in the
83                                       // sstSegName table, or 0xFFFF.
84   support::ulittle32_t Offset;        // Byte offset of the logical segment
85                                       // within the specified physical segment.
86                                       // If group is set in flags, offset is the
87                                       // offset of the group.
88   support::ulittle32_t SecByteLength; // Byte count of the segment or group.
89 };
90 
91 /// Some of the values are stored in bitfields.  Since this needs to be portable
92 /// across compilers and architectures (big / little endian in particular) we
93 /// can't use the actual structures below, but must instead do the shifting
94 /// and masking ourselves.  The struct definitions are provided for reference.
95 struct DbiFlags {
96   ///  uint16_t IncrementalLinking : 1; // True if linked incrementally
97   ///  uint16_t IsStripped : 1;         // True if private symbols were
98   ///  stripped.
99   ///  uint16_t HasCTypes : 1;          // True if linked with /debug:ctypes.
100   ///  uint16_t Reserved : 13;
101   static const uint16_t FlagIncrementalMask = 0x0001;
102   static const uint16_t FlagStrippedMask = 0x0002;
103   static const uint16_t FlagHasCTypesMask = 0x0004;
104 };
105 
106 struct DbiBuildNo {
107   ///  uint16_t MinorVersion : 8;
108   ///  uint16_t MajorVersion : 7;
109   ///  uint16_t NewVersionFormat : 1;
110   static const uint16_t BuildMinorMask = 0x00FF;
111   static const uint16_t BuildMinorShift = 0;
112 
113   static const uint16_t BuildMajorMask = 0x7F00;
114   static const uint16_t BuildMajorShift = 8;
115 
116   static const uint16_t NewVersionFormatMask = 0x8000;
117 };
118 
119 /// The fixed size header that appears at the beginning of the DBI Stream.
120 struct DbiStreamHeader {
121   support::little32_t VersionSignature;
122   support::ulittle32_t VersionHeader;
123 
124   /// How "old" is this DBI Stream. Should match the age of the PDB InfoStream.
125   support::ulittle32_t Age;
126 
127   /// Global symbol stream #
128   support::ulittle16_t GlobalSymbolStreamIndex;
129 
130   /// See DbiBuildNo structure.
131   support::ulittle16_t BuildNumber;
132 
133   /// Public symbols stream #
134   support::ulittle16_t PublicSymbolStreamIndex;
135 
136   /// version of mspdbNNN.dll
137   support::ulittle16_t PdbDllVersion;
138 
139   /// Symbol records stream #
140   support::ulittle16_t SymRecordStreamIndex;
141 
142   /// rbld number of mspdbNNN.dll
143   support::ulittle16_t PdbDllRbld;
144 
145   /// Size of module info stream
146   support::little32_t ModiSubstreamSize;
147 
148   /// Size of sec. contrib stream
149   support::little32_t SecContrSubstreamSize;
150 
151   /// Size of sec. map substream
152   support::little32_t SectionMapSize;
153 
154   /// Size of file info substream
155   support::little32_t FileInfoSize;
156 
157   /// Size of type server map
158   support::little32_t TypeServerSize;
159 
160   /// Index of MFC Type Server
161   support::ulittle32_t MFCTypeServerIndex;
162 
163   /// Size of DbgHeader info
164   support::little32_t OptionalDbgHdrSize;
165 
166   /// Size of EC stream (what is EC?)
167   support::little32_t ECSubstreamSize;
168 
169   /// See DbiFlags enum.
170   support::ulittle16_t Flags;
171 
172   /// See PDB_MachineType enum.
173   support::ulittle16_t MachineType;
174 
175   /// Pad to 64 bytes
176   support::ulittle32_t Reserved;
177 };
178 static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!");
179 
180 /// The header preceeding the File Info Substream of the DBI stream.
181 struct FileInfoSubstreamHeader {
182   /// Total # of modules, should match number of records in the ModuleInfo
183   /// substream.
184   support::ulittle16_t NumModules;
185 
186   /// Total # of source files. This value is not accurate because PDB actually
187   /// supports more than 64k source files, so we ignore it and compute the value
188   /// from other stream fields.
189   support::ulittle16_t NumSourceFiles;
190 
191   /// Following this header the File Info Substream is laid out as follows:
192   ///   ulittle16_t ModIndices[NumModules];
193   ///   ulittle16_t ModFileCounts[NumModules];
194   ///   ulittle32_t FileNameOffsets[NumSourceFiles];
195   ///   char Names[][NumSourceFiles];
196   /// with the caveat that `NumSourceFiles` cannot be trusted, so
197   /// it is computed by summing the `ModFileCounts` array.
198 };
199 
200 struct ModInfoFlags {
201   ///  uint16_t fWritten : 1;   // True if DbiModuleDescriptor is dirty
202   ///  uint16_t fECEnabled : 1; // Is EC symbolic info present?  (What is EC?)
203   ///  uint16_t unused : 6;     // Reserved
204   ///  uint16_t iTSM : 8;       // Type Server Index for this module
205   static const uint16_t HasECFlagMask = 0x2;
206 
207   static const uint16_t TypeServerIndexMask = 0xFF00;
208   static const uint16_t TypeServerIndexShift = 8;
209 };
210 
211 /// The header preceeding each entry in the Module Info substream of the DBI
212 /// stream.  Corresponds to the type MODI in the reference implementation.
213 struct ModuleInfoHeader {
214   /// Currently opened module. This field is a pointer in the reference
215   /// implementation, but that won't work on 64-bit systems, and anyway it
216   /// doesn't make sense to read a pointer from a file. For now it is unused,
217   /// so just ignore it.
218   support::ulittle32_t Mod;
219 
220   /// First section contribution of this module.
221   SectionContrib SC;
222 
223   /// See ModInfoFlags definition.
224   support::ulittle16_t Flags;
225 
226   /// Stream Number of module debug info
227   support::ulittle16_t ModDiStream;
228 
229   /// Size of local symbol debug info in above stream
230   support::ulittle32_t SymBytes;
231 
232   /// Size of C11 line number info in above stream
233   support::ulittle32_t C11Bytes;
234 
235   /// Size of C13 line number info in above stream
236   support::ulittle32_t C13Bytes;
237 
238   /// Number of files contributing to this module
239   support::ulittle16_t NumFiles;
240 
241   /// Padding so the next field is 4-byte aligned.
242   char Padding1[2];
243 
244   /// Array of [0..NumFiles) DBI name buffer offsets.  In the reference
245   /// implementation this field is a pointer.  But since you can't portably
246   /// serialize a pointer, on 64-bit platforms they copy all the values except
247   /// this one into the 32-bit version of the struct and use that for
248   /// serialization.  Regardless, this field is unused, it is only there to
249   /// store a pointer that can be accessed at runtime.
250   support::ulittle32_t FileNameOffs;
251 
252   /// Name Index for src file name
253   support::ulittle32_t SrcFileNameNI;
254 
255   /// Name Index for path to compiler PDB
256   support::ulittle32_t PdbFilePathNI;
257 
258   /// Following this header are two zero terminated strings.
259   /// char ModuleName[];
260   /// char ObjFileName[];
261 };
262 
263 // This is PSGSIHDR struct defined in
264 // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
265 struct PublicsStreamHeader {
266   support::ulittle32_t SymHash;
267   support::ulittle32_t AddrMap;
268   support::ulittle32_t NumThunks;
269   support::ulittle32_t SizeOfThunk;
270   support::ulittle16_t ISectThunkTable;
271   char Padding[2];
272   support::ulittle32_t OffThunkTable;
273   support::ulittle32_t NumSections;
274 };
275 
276 // The header preceeding the global TPI stream.
277 // This corresponds to `HDR` in PDB/dbi/tpi.h.
278 struct TpiStreamHeader {
279   struct EmbeddedBuf {
280     support::little32_t Off;
281     support::ulittle32_t Length;
282   };
283 
284   support::ulittle32_t Version;
285   support::ulittle32_t HeaderSize;
286   support::ulittle32_t TypeIndexBegin;
287   support::ulittle32_t TypeIndexEnd;
288   support::ulittle32_t TypeRecordBytes;
289 
290   // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
291   support::ulittle16_t HashStreamIndex;
292   support::ulittle16_t HashAuxStreamIndex;
293   support::ulittle32_t HashKeySize;
294   support::ulittle32_t NumHashBuckets;
295 
296   EmbeddedBuf HashValueBuffer;
297   EmbeddedBuf IndexOffsetBuffer;
298   EmbeddedBuf HashAdjBuffer;
299 };
300 
301 const uint32_t MinTpiHashBuckets = 0x1000;
302 const uint32_t MaxTpiHashBuckets = 0x40000;
303 
304 /// The header preceeding the global PDB Stream (Stream 1)
305 struct InfoStreamHeader {
306   support::ulittle32_t Version;
307   support::ulittle32_t Signature;
308   support::ulittle32_t Age;
309   codeview::GUID Guid;
310 };
311 
312 /// The header preceeding the /names stream.
313 struct PDBStringTableHeader {
314   support::ulittle32_t Signature;   // PDBStringTableSignature
315   support::ulittle32_t HashVersion; // 1 or 2
316   support::ulittle32_t ByteSize;    // Number of bytes of names buffer.
317 };
318 
319 const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
320 
321 /// The header preceding the /src/headerblock stream.
322 struct SrcHeaderBlockHeader {
323   support::ulittle32_t Version; // PdbRaw_SrcHeaderBlockVer enumeration.
324   support::ulittle32_t Size;    // Size of entire stream.
325   uint64_t FileTime;            // Time stamp (Windows FILETIME format).
326   support::ulittle32_t Age;     // Age
327   uint8_t Padding[44];          // Pad to 64 bytes.
328 };
329 static_assert(sizeof(SrcHeaderBlockHeader) == 64, "Incorrect struct size!");
330 
331 /// A single file record entry within the /src/headerblock stream.
332 struct SrcHeaderBlockEntry {
333   support::ulittle32_t Size;     // Record Length.
334   support::ulittle32_t Version;  // PdbRaw_SrcHeaderBlockVer enumeration.
335   support::ulittle32_t CRC;      // CRC of the original file contents.
336   support::ulittle32_t FileSize; // Size of original source file.
337   support::ulittle32_t FileNI;   // String table index of file name.
338   support::ulittle32_t ObjNI;    // String table index of object name.
339   support::ulittle32_t VFileNI;  // String table index of virtual file name.
340   uint8_t Compression;           // PDB_SourceCompression enumeration.
341   uint8_t IsVirtual;             // Is this a virtual file (injected)?
342   short Padding;                 // Pad to 4 bytes.
343   char Reserved[8];
344 };
345 
346 constexpr int I = sizeof(SrcHeaderBlockEntry);
347 static_assert(sizeof(SrcHeaderBlockEntry) == 40, "Incorrect struct size!");
348 
349 } // namespace pdb
350 } // namespace llvm
351 
352 #endif
353