1//===- PDBTypes.h - Defines enums for various fields contained in PDB ----====//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H
10#define LLVM_DEBUGINFO_PDB_PDBTYPES_H
11
12#include "llvm/ADT/APFloat.h"
13#include "llvm/DebugInfo/CodeView/CodeView.h"
14#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
15#include "llvm/DebugInfo/PDB/IPDBFrameData.h"
16#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17#include <cctype>
18#include <cstddef>
19#include <cstdint>
20#include <cstring>
21#include <functional>
22
23namespace llvm {
24namespace pdb {
25
26typedef uint32_t SymIndexId;
27
28class IPDBDataStream;
29class IPDBInjectedSource;
30class IPDBLineNumber;
31class IPDBSectionContrib;
32class IPDBSession;
33class IPDBSourceFile;
34class IPDBTable;
35class PDBSymDumper;
36class PDBSymbol;
37class PDBSymbolExe;
38class PDBSymbolCompiland;
39class PDBSymbolCompilandDetails;
40class PDBSymbolCompilandEnv;
41class PDBSymbolFunc;
42class PDBSymbolBlock;
43class PDBSymbolData;
44class PDBSymbolAnnotation;
45class PDBSymbolLabel;
46class PDBSymbolPublicSymbol;
47class PDBSymbolTypeUDT;
48class PDBSymbolTypeEnum;
49class PDBSymbolTypeFunctionSig;
50class PDBSymbolTypePointer;
51class PDBSymbolTypeArray;
52class PDBSymbolTypeBuiltin;
53class PDBSymbolTypeTypedef;
54class PDBSymbolTypeBaseClass;
55class PDBSymbolTypeFriend;
56class PDBSymbolTypeFunctionArg;
57class PDBSymbolFuncDebugStart;
58class PDBSymbolFuncDebugEnd;
59class PDBSymbolUsingNamespace;
60class PDBSymbolTypeVTableShape;
61class PDBSymbolTypeVTable;
62class PDBSymbolCustom;
63class PDBSymbolThunk;
64class PDBSymbolTypeCustom;
65class PDBSymbolTypeManaged;
66class PDBSymbolTypeDimension;
67class PDBSymbolUnknown;
68
69using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>;
70using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>;
71using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>;
72using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>;
73using IPDBEnumTables = IPDBEnumChildren<IPDBTable>;
74using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>;
75using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>;
76using IPDBEnumFrameData = IPDBEnumChildren<IPDBFrameData>;
77
78/// Specifies which PDB reader implementation is to be used. Only a value
79/// of PDB_ReaderType::DIA is currently supported, but Native is in the works.
80enum class PDB_ReaderType {
81 DIA = 0,
82 Native = 1,
83};
84
85/// An enumeration indicating the type of data contained in this table.
86enum class PDB_TableType {
87 TableInvalid = 0,
88 Symbols,
89 SourceFiles,
90 LineNumbers,
91 SectionContribs,
92 Segments,
93 InjectedSources,
94 FrameData,
95 InputAssemblyFiles,
96 Dbg
97};
98
99/// Defines flags used for enumerating child symbols. This corresponds to the
100/// NameSearchOptions enumeration which is documented here:
101/// https://msdn.microsoft.com/en-us/library/yat28ads.aspx
102enum PDB_NameSearchFlags {
103 NS_Default = 0x0,
104 NS_CaseSensitive = 0x1,
105 NS_CaseInsensitive = 0x2,
106 NS_FileNameExtMatch = 0x4,
107 NS_Regex = 0x8,
108 NS_UndecoratedName = 0x10,
109
110 // For backward compatibility.
111 NS_CaseInFileNameExt = NS_CaseInsensitive | NS_FileNameExtMatch,
112 NS_CaseRegex = NS_Regex | NS_CaseSensitive,
113 NS_CaseInRex = NS_Regex | NS_CaseInsensitive
114};
115
116/// Specifies the hash algorithm that a source file from a PDB was hashed with.
117/// This corresponds to the CV_SourceChksum_t enumeration and are documented
118/// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx
119enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 };
120
121/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
122/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
123using PDB_Cpu = codeview::CPUType;
124
125enum class PDB_Machine {
126 Invalid = 0xffff,
127 Unknown = 0x0,
128 Am33 = 0x13,
129 Amd64 = 0x8664,
130 Arm = 0x1C0,
131 Arm64 = 0xaa64,
132 ArmNT = 0x1C4,
133 Ebc = 0xEBC,
134 x86 = 0x14C,
135 Ia64 = 0x200,
136 M32R = 0x9041,
137 Mips16 = 0x266,
138 MipsFpu = 0x366,
139 MipsFpu16 = 0x466,
140 PowerPC = 0x1F0,
141 PowerPCFP = 0x1F1,
142 R4000 = 0x166,
143 SH3 = 0x1A2,
144 SH3DSP = 0x1A3,
145 SH4 = 0x1A6,
146 SH5 = 0x1A8,
147 Thumb = 0x1C2,
148 WceMipsV2 = 0x169
149};
150
151// A struct with an inner unnamed enum with explicit underlying type resuls
152// in an enum class that can implicitly convert to the underlying type, which
153// is convenient for this enum.
154struct PDB_SourceCompression {
155 enum : uint32_t {
156 // No compression. Produced e.g. by `link.exe /natvis:foo.natvis`.
157 None,
158 // Not known what produces this.
159 RunLengthEncoded,
160 // Not known what produces this.
161 Huffman,
162 // Not known what produces this.
163 LZ,
164 // Produced e.g. by `csc /debug`. The encoded data is its own mini-stream
165 // with the following layout (in little endian):
166 // GUID LanguageTypeGuid;
167 // GUID LanguageVendorGuid;
168 // GUID DocumentTypeGuid;
169 // GUID HashFunctionGuid;
170 // uint32_t HashDataSize;
171 // uint32_t CompressedDataSize;
172 // Followed by HashDataSize bytes containing a hash checksum,
173 // followed by CompressedDataSize bytes containing source contents.
174 //
175 // CompressedDataSize can be 0, in this case only the hash data is present.
176 // (CompressedDataSize is != 0 e.g. if `/embed` is passed to csc.exe.)
177 // The compressed data format is:
178 // uint32_t UncompressedDataSize;
179 // If UncompressedDataSize is 0, the data is stored uncompressed and
180 // CompressedDataSize stores the uncompressed size.
181 // If UncompressedDataSize is != 0, then the data is in raw deflate
182 // encoding as described in rfc1951.
183 //
184 // A GUID is 16 bytes, stored in the usual
185 // uint32_t
186 // uint16_t
187 // uint16_t
188 // uint8_t[24]
189 // layout.
190 //
191 // Well-known GUIDs for LanguageTypeGuid are:
192 // 63a08714-fc37-11d2-904c-00c04fa302a1 C
193 // 3a12d0b7-c26c-11d0-b442-00a0244a1dd2 C++
194 // 3f5162f8-07c6-11d3-9053-00c04fa302a1 C#
195 // af046cd1-d0e1-11d2-977c-00a0c9b4d50c Cobol
196 // ab4f38c9-b6e6-43ba-be3b-58080b2ccce3 F#
197 // 3a12d0b4-c26c-11d0-b442-00a0244a1dd2 Java
198 // 3a12d0b6-c26c-11d0-b442-00a0244a1dd2 JScript
199 // af046cd2-d0e1-11d2-977c-00a0c9b4d50c Pascal
200 // 3a12d0b8-c26c-11d0-b442-00a0244a1dd2 Visual Basic
201 //
202 // Well-known GUIDs for LanguageVendorGuid are:
203 // 994b45c4-e6e9-11d2-903f-00c04fa302a1 Microsoft
204 //
205 // Well-known GUIDs for DocumentTypeGuid are:
206 // 5a869d0b-6611-11d3-bd2a-0000f80849bd Text
207 //
208 // Well-known GUIDs for HashFunctionGuid are:
209 // 406ea660-64cf-4c82-b6f0-42d48172a799 MD5 (HashDataSize is 16)
210 // ff1816ec-aa5e-4d10-87f7-6f4963833460 SHA1 (HashDataSize is 20)
211 // 8829d00f-11b8-4213-878b-770e8597ac16 SHA256 (HashDataSize is 32)
212 DotNet = 101,
213 };
214};
215
216/// These values correspond to the CV_call_e enumeration, and are documented
217/// at the following locations:
218/// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
219/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
220using PDB_CallingConv = codeview::CallingConvention;
221
222/// These values correspond to the CV_CFL_LANG enumeration, and are documented
223/// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
224using PDB_Lang = codeview::SourceLanguage;
225
226/// These values correspond to the DataKind enumeration, and are documented
227/// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx
228enum class PDB_DataKind {
229 Unknown,
230 Local,
231 StaticLocal,
232 Param,
233 ObjectPtr,
234 FileStatic,
235 Global,
236 Member,
237 StaticMember,
238 Constant
239};
240
241/// These values correspond to the SymTagEnum enumeration, and are documented
242/// here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx
243enum class PDB_SymType {
244 None,
245 Exe,
246 Compiland,
247 CompilandDetails,
248 CompilandEnv,
249 Function,
250 Block,
251 Data,
252 Annotation,
253 Label,
254 PublicSymbol,
255 UDT,
256 Enum,
257 FunctionSig,
258 PointerType,
259 ArrayType,
260 BuiltinType,
261 Typedef,
262 BaseClass,
263 Friend,
264 FunctionArg,
265 FuncDebugStart,
266 FuncDebugEnd,
267 UsingNamespace,
268 VTableShape,
269 VTable,
270 Custom,
271 Thunk,
272 CustomType,
273 ManagedType,
274 Dimension,
275 CallSite,
276 InlineSite,
277 BaseInterface,
278 VectorType,
279 MatrixType,
280 HLSLType,
281 Caller,
282 Callee,
283 Export,
284 HeapAllocationSite,
285 CoffGroup,
286 Inlinee,
287 Max
288};
289
290/// These values correspond to the LocationType enumeration, and are documented
291/// here: https://msdn.microsoft.com/en-us/library/f57kaez3.aspx
292enum class PDB_LocType {
293 Null,
294 Static,
295 TLS,
296 RegRel,
297 ThisRel,
298 Enregistered,
299 BitField,
300 Slot,
301 IlRel,
302 MetaData,
303 Constant,
304 RegRelAliasIndir,
305 Max
306};
307
308/// These values correspond to the UdtKind enumeration, and are documented
309/// here: https://msdn.microsoft.com/en-us/library/wcstk66t.aspx
310enum class PDB_UdtType { Struct, Class, Union, Interface };
311
312/// These values correspond to the StackFrameTypeEnum enumeration, and are
313/// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx.
314enum class PDB_StackFrameType : uint16_t {
315 FPO,
316 KernelTrap,
317 KernelTSS,
318 EBP,
319 FrameData,
320 Unknown = 0xffff
321};
322
323/// These values correspond to the MemoryTypeEnum enumeration, and are
324/// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx.
325enum class PDB_MemoryType : uint16_t {
326 Code,
327 Data,
328 Stack,
329 HeapCode,
330 Any = 0xffff
331};
332
333/// These values correspond to the Basictype enumeration, and are documented
334/// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx
335enum class PDB_BuiltinType {
336 None = 0,
337 Void = 1,
338 Char = 2,
339 WCharT = 3,
340 Int = 6,
341 UInt = 7,
342 Float = 8,
343 BCD = 9,
344 Bool = 10,
345 Long = 13,
346 ULong = 14,
347 Currency = 25,
348 Date = 26,
349 Variant = 27,
350 Complex = 28,
351 Bitfield = 29,
352 BSTR = 30,
353 HResult = 31,
354 Char16 = 32,
355 Char32 = 33,
356 Char8 = 34,
357};
358
359/// These values correspond to the flags that can be combined to control the
360/// return of an undecorated name for a C++ decorated name, and are documented
361/// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx
362enum PDB_UndnameFlags : uint32_t {
363 Undname_Complete = 0x0,
364 Undname_NoLeadingUnderscores = 0x1,
365 Undname_NoMsKeywords = 0x2,
366 Undname_NoFuncReturns = 0x4,
367 Undname_NoAllocModel = 0x8,
368 Undname_NoAllocLang = 0x10,
369 Undname_Reserved1 = 0x20,
370 Undname_Reserved2 = 0x40,
371 Undname_NoThisType = 0x60,
372 Undname_NoAccessSpec = 0x80,
373 Undname_NoThrowSig = 0x100,
374 Undname_NoMemberType = 0x200,
375 Undname_NoReturnUDTModel = 0x400,
376 Undname_32BitDecode = 0x800,
377 Undname_NameOnly = 0x1000,
378 Undname_TypeOnly = 0x2000,
379 Undname_HaveParams = 0x4000,
380 Undname_NoECSU = 0x8000,
381 Undname_NoIdentCharCheck = 0x10000,
382 Undname_NoPTR64 = 0x20000
383};
384
385enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
386
387struct VersionInfo {
388 uint32_t Major;
389 uint32_t Minor;
390 uint32_t Build;
391 uint32_t QFE;
392};
393
394enum PDB_VariantType {
395 Empty,
396 Unknown,
397 Int8,
398 Int16,
399 Int32,
400 Int64,
401 Single,
402 Double,
403 UInt8,
404 UInt16,
405 UInt32,
406 UInt64,
407 Bool,
408 String
409};
410
411struct Variant {
412 Variant() = default;
413
414 explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; }
415 explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; }
416 explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) {
417 Value.Int16 = V;
418 }
419 explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) {
420 Value.Int32 = V;
421 }
422 explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) {
423 Value.Int64 = V;
424 }
425 explicit Variant(float V) : Type(PDB_VariantType::Single) {
426 Value.Single = V;
427 }
428 explicit Variant(double V) : Type(PDB_VariantType::Double) {
429 Value.Double = V;
430 }
431 explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) {
432 Value.UInt8 = V;
433 }
434 explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) {
435 Value.UInt16 = V;
436 }
437 explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) {
438 Value.UInt32 = V;
439 }
440 explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) {
441 Value.UInt64 = V;
442 }
443
444 Variant(const Variant &Other) {
445 *this = Other;
446 }
447
448 ~Variant() {
449 if (Type == PDB_VariantType::String)
450 delete[] Value.String;
451 }
452
453 PDB_VariantType Type = PDB_VariantType::Empty;
454 union {
455 bool Bool;
456 int8_t Int8;
457 int16_t Int16;
458 int32_t Int32;
459 int64_t Int64;
460 float Single;
461 double Double;
462 uint8_t UInt8;
463 uint16_t UInt16;
464 uint32_t UInt32;
465 uint64_t UInt64;
466 char *String;
467 } Value;
468
469 bool isIntegralType() const {
470 switch (Type) {
471 case Bool:
472 case Int8:
473 case Int16:
474 case Int32:
475 case Int64:
476 case UInt8:
477 case UInt16:
478 case UInt32:
479 case UInt64:
480 return true;
481 default:
482 return false;
483 }
484 }
485
486#define VARIANT_WIDTH(Enum, NumBits) \
487 case PDB_VariantType::Enum: \
488 return NumBits;
489
490 unsigned getBitWidth() const {
491 switch (Type) {
492 VARIANT_WIDTH(Bool, 1u)
493 VARIANT_WIDTH(Int8, 8u)
494 VARIANT_WIDTH(Int16, 16u)
495 VARIANT_WIDTH(Int32, 32u)
496 VARIANT_WIDTH(Int64, 64u)
497 VARIANT_WIDTH(Single, 32u)
498 VARIANT_WIDTH(Double, 64u)
499 VARIANT_WIDTH(UInt8, 8u)
500 VARIANT_WIDTH(UInt16, 16u)
501 VARIANT_WIDTH(UInt32, 32u)
502 VARIANT_WIDTH(UInt64, 64u)
503 default:
504 assert(false && "Variant::toAPSInt called on non-numeric type");
505 return 0u;
506 }
507 }
508
509#undef VARIANT_WIDTH
510
511#define VARIANT_APSINT(Enum, NumBits, IsUnsigned) \
512 case PDB_VariantType::Enum: \
513 return APSInt(APInt(NumBits, Value.Enum), IsUnsigned);
514
515 APSInt toAPSInt() const {
516 switch (Type) {
517 VARIANT_APSINT(Bool, 1u, true)
518 VARIANT_APSINT(Int8, 8u, false)
519 VARIANT_APSINT(Int16, 16u, false)
520 VARIANT_APSINT(Int32, 32u, false)
521 VARIANT_APSINT(Int64, 64u, false)
522 VARIANT_APSINT(UInt8, 8u, true)
523 VARIANT_APSINT(UInt16, 16u, true)
524 VARIANT_APSINT(UInt32, 32u, true)
525 VARIANT_APSINT(UInt64, 64u, true)
526 default:
527 assert(false && "Variant::toAPSInt called on non-integral type");
528 return APSInt();
529 }
530 }
531
532#undef VARIANT_APSINT
533
534 APFloat toAPFloat() const {
535 // Float constants may be tagged as integers.
536 switch (Type) {
537 case PDB_VariantType::Single:
538 case PDB_VariantType::UInt32:
539 case PDB_VariantType::Int32:
540 return APFloat(Value.Single);
541 case PDB_VariantType::Double:
542 case PDB_VariantType::UInt64:
543 case PDB_VariantType::Int64:
544 return APFloat(Value.Double);
545 default:
546 assert(false && "Variant::toAPFloat called on non-floating-point type");
547 return APFloat::getZero(Sem: APFloat::IEEEsingle());
548 }
549 }
550
551#define VARIANT_EQUAL_CASE(Enum) \
552 case PDB_VariantType::Enum: \
553 return Value.Enum == Other.Value.Enum;
554
555 bool operator==(const Variant &Other) const {
556 if (Type != Other.Type)
557 return false;
558 switch (Type) {
559 VARIANT_EQUAL_CASE(Bool)
560 VARIANT_EQUAL_CASE(Int8)
561 VARIANT_EQUAL_CASE(Int16)
562 VARIANT_EQUAL_CASE(Int32)
563 VARIANT_EQUAL_CASE(Int64)
564 VARIANT_EQUAL_CASE(Single)
565 VARIANT_EQUAL_CASE(Double)
566 VARIANT_EQUAL_CASE(UInt8)
567 VARIANT_EQUAL_CASE(UInt16)
568 VARIANT_EQUAL_CASE(UInt32)
569 VARIANT_EQUAL_CASE(UInt64)
570 VARIANT_EQUAL_CASE(String)
571 default:
572 return true;
573 }
574 }
575
576#undef VARIANT_EQUAL_CASE
577
578 bool operator!=(const Variant &Other) const { return !(*this == Other); }
579 Variant &operator=(const Variant &Other) {
580 if (this == &Other)
581 return *this;
582 if (Type == PDB_VariantType::String)
583 delete[] Value.String;
584 Type = Other.Type;
585 Value = Other.Value;
586 if (Other.Type == PDB_VariantType::String &&
587 Other.Value.String != nullptr) {
588 Value.String = new char[strlen(s: Other.Value.String) + 1];
589 ::strcpy(dest: Value.String, src: Other.Value.String);
590 }
591 return *this;
592 }
593};
594
595} // end namespace pdb
596} // end namespace llvm
597
598namespace std {
599
600template <> struct hash<llvm::pdb::PDB_SymType> {
601 using argument_type = llvm::pdb::PDB_SymType;
602 using result_type = std::size_t;
603
604 result_type operator()(const argument_type &Arg) const {
605 return std::hash<int>()(static_cast<int>(Arg));
606 }
607};
608
609} // end namespace std
610
611#endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H
612

source code of llvm/include/llvm/DebugInfo/PDB/PDBTypes.h