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