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 
23 namespace llvm {
24 namespace pdb {
25 
26 typedef uint32_t SymIndexId;
27 
28 class IPDBDataStream;
29 class IPDBInjectedSource;
30 class IPDBLineNumber;
31 class IPDBSectionContrib;
32 class IPDBSession;
33 class IPDBSourceFile;
34 class IPDBTable;
35 class PDBSymDumper;
36 class PDBSymbol;
37 class PDBSymbolExe;
38 class PDBSymbolCompiland;
39 class PDBSymbolCompilandDetails;
40 class PDBSymbolCompilandEnv;
41 class PDBSymbolFunc;
42 class PDBSymbolBlock;
43 class PDBSymbolData;
44 class PDBSymbolAnnotation;
45 class PDBSymbolLabel;
46 class PDBSymbolPublicSymbol;
47 class PDBSymbolTypeUDT;
48 class PDBSymbolTypeEnum;
49 class PDBSymbolTypeFunctionSig;
50 class PDBSymbolTypePointer;
51 class PDBSymbolTypeArray;
52 class PDBSymbolTypeBuiltin;
53 class PDBSymbolTypeTypedef;
54 class PDBSymbolTypeBaseClass;
55 class PDBSymbolTypeFriend;
56 class PDBSymbolTypeFunctionArg;
57 class PDBSymbolFuncDebugStart;
58 class PDBSymbolFuncDebugEnd;
59 class PDBSymbolUsingNamespace;
60 class PDBSymbolTypeVTableShape;
61 class PDBSymbolTypeVTable;
62 class PDBSymbolCustom;
63 class PDBSymbolThunk;
64 class PDBSymbolTypeCustom;
65 class PDBSymbolTypeManaged;
66 class PDBSymbolTypeDimension;
67 class PDBSymbolUnknown;
68 
69 using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>;
70 using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>;
71 using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>;
72 using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>;
73 using IPDBEnumTables = IPDBEnumChildren<IPDBTable>;
74 using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>;
75 using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>;
76 using 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.
80 enum class PDB_ReaderType {
81   DIA = 0,
82   Native = 1,
83 };
84 
85 /// An enumeration indicating the type of data contained in this table.
86 enum 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
102 enum 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
119 enum 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
123 using PDB_Cpu = codeview::CPUType;
124 
125 enum 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.
154 struct 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
220 using 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
224 using 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
228 enum 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
243 enum 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
292 enum 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
310 enum 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.
314 enum 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.
325 enum 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
335 enum 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 };
357 
358 /// These values correspond to the flags that can be combined to control the
359 /// return of an undecorated name for a C++ decorated name, and are documented
360 /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx
361 enum PDB_UndnameFlags : uint32_t {
362   Undname_Complete = 0x0,
363   Undname_NoLeadingUnderscores = 0x1,
364   Undname_NoMsKeywords = 0x2,
365   Undname_NoFuncReturns = 0x4,
366   Undname_NoAllocModel = 0x8,
367   Undname_NoAllocLang = 0x10,
368   Undname_Reserved1 = 0x20,
369   Undname_Reserved2 = 0x40,
370   Undname_NoThisType = 0x60,
371   Undname_NoAccessSpec = 0x80,
372   Undname_NoThrowSig = 0x100,
373   Undname_NoMemberType = 0x200,
374   Undname_NoReturnUDTModel = 0x400,
375   Undname_32BitDecode = 0x800,
376   Undname_NameOnly = 0x1000,
377   Undname_TypeOnly = 0x2000,
378   Undname_HaveParams = 0x4000,
379   Undname_NoECSU = 0x8000,
380   Undname_NoIdentCharCheck = 0x10000,
381   Undname_NoPTR64 = 0x20000
382 };
383 
384 enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
385 
386 struct VersionInfo {
387   uint32_t Major;
388   uint32_t Minor;
389   uint32_t Build;
390   uint32_t QFE;
391 };
392 
393 enum PDB_VariantType {
394   Empty,
395   Unknown,
396   Int8,
397   Int16,
398   Int32,
399   Int64,
400   Single,
401   Double,
402   UInt8,
403   UInt16,
404   UInt32,
405   UInt64,
406   Bool,
407   String
408 };
409 
410 struct Variant {
411   Variant() = default;
412 
VariantVariant413   explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; }
VariantVariant414   explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; }
VariantVariant415   explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) {
416     Value.Int16 = V;
417   }
VariantVariant418   explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) {
419     Value.Int32 = V;
420   }
VariantVariant421   explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) {
422     Value.Int64 = V;
423   }
VariantVariant424   explicit Variant(float V) : Type(PDB_VariantType::Single) {
425     Value.Single = V;
426   }
VariantVariant427   explicit Variant(double V) : Type(PDB_VariantType::Double) {
428     Value.Double = V;
429   }
VariantVariant430   explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) {
431     Value.UInt8 = V;
432   }
VariantVariant433   explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) {
434     Value.UInt16 = V;
435   }
VariantVariant436   explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) {
437     Value.UInt32 = V;
438   }
VariantVariant439   explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) {
440     Value.UInt64 = V;
441   }
442 
VariantVariant443   Variant(const Variant &Other) {
444     *this = Other;
445   }
446 
~VariantVariant447   ~Variant() {
448     if (Type == PDB_VariantType::String)
449       delete[] Value.String;
450   }
451 
452   PDB_VariantType Type = PDB_VariantType::Empty;
453   union {
454     bool Bool;
455     int8_t Int8;
456     int16_t Int16;
457     int32_t Int32;
458     int64_t Int64;
459     float Single;
460     double Double;
461     uint8_t UInt8;
462     uint16_t UInt16;
463     uint32_t UInt32;
464     uint64_t UInt64;
465     char *String;
466   } Value;
467 
isIntegralTypeVariant468   bool isIntegralType() const {
469     switch (Type) {
470     case Bool:
471     case Int8:
472     case Int16:
473     case Int32:
474     case Int64:
475     case UInt8:
476     case UInt16:
477     case UInt32:
478     case UInt64:
479       return true;
480     default:
481       return false;
482     }
483   }
484 
485 #define VARIANT_WIDTH(Enum, NumBits)                                           \
486   case PDB_VariantType::Enum:                                                  \
487     return NumBits;
488 
getBitWidthVariant489   unsigned getBitWidth() const {
490     switch (Type) {
491       VARIANT_WIDTH(Bool, 1u)
492       VARIANT_WIDTH(Int8, 8u)
493       VARIANT_WIDTH(Int16, 16u)
494       VARIANT_WIDTH(Int32, 32u)
495       VARIANT_WIDTH(Int64, 64u)
496       VARIANT_WIDTH(Single, 32u)
497       VARIANT_WIDTH(Double, 64u)
498       VARIANT_WIDTH(UInt8, 8u)
499       VARIANT_WIDTH(UInt16, 16u)
500       VARIANT_WIDTH(UInt32, 32u)
501       VARIANT_WIDTH(UInt64, 64u)
502     default:
503       assert(false && "Variant::toAPSInt called on non-numeric type");
504       return 0u;
505     }
506   }
507 
508 #undef VARIANT_WIDTH
509 
510 #define VARIANT_APSINT(Enum, NumBits, IsUnsigned)                              \
511   case PDB_VariantType::Enum:                                                  \
512     return APSInt(APInt(NumBits, Value.Enum), IsUnsigned);
513 
toAPSIntVariant514   APSInt toAPSInt() const {
515     switch (Type) {
516       VARIANT_APSINT(Bool, 1u, true)
517       VARIANT_APSINT(Int8, 8u, false)
518       VARIANT_APSINT(Int16, 16u, false)
519       VARIANT_APSINT(Int32, 32u, false)
520       VARIANT_APSINT(Int64, 64u, false)
521       VARIANT_APSINT(UInt8, 8u, true)
522       VARIANT_APSINT(UInt16, 16u, true)
523       VARIANT_APSINT(UInt32, 32u, true)
524       VARIANT_APSINT(UInt64, 64u, true)
525     default:
526       assert(false && "Variant::toAPSInt called on non-integral type");
527       return APSInt();
528     }
529   }
530 
531 #undef VARIANT_APSINT
532 
toAPFloatVariant533   APFloat toAPFloat() const {
534     // Float constants may be tagged as integers.
535     switch (Type) {
536     case PDB_VariantType::Single:
537     case PDB_VariantType::UInt32:
538     case PDB_VariantType::Int32:
539       return APFloat(Value.Single);
540     case PDB_VariantType::Double:
541     case PDB_VariantType::UInt64:
542     case PDB_VariantType::Int64:
543       return APFloat(Value.Double);
544     default:
545       assert(false && "Variant::toAPFloat called on non-floating-point type");
546       return APFloat::getZero(APFloat::IEEEsingle());
547     }
548   }
549 
550 #define VARIANT_EQUAL_CASE(Enum)                                               \
551   case PDB_VariantType::Enum:                                                  \
552     return Value.Enum == Other.Value.Enum;
553 
554   bool operator==(const Variant &Other) const {
555     if (Type != Other.Type)
556       return false;
557     switch (Type) {
558       VARIANT_EQUAL_CASE(Bool)
559       VARIANT_EQUAL_CASE(Int8)
560       VARIANT_EQUAL_CASE(Int16)
561       VARIANT_EQUAL_CASE(Int32)
562       VARIANT_EQUAL_CASE(Int64)
563       VARIANT_EQUAL_CASE(Single)
564       VARIANT_EQUAL_CASE(Double)
565       VARIANT_EQUAL_CASE(UInt8)
566       VARIANT_EQUAL_CASE(UInt16)
567       VARIANT_EQUAL_CASE(UInt32)
568       VARIANT_EQUAL_CASE(UInt64)
569       VARIANT_EQUAL_CASE(String)
570     default:
571       return true;
572     }
573   }
574 
575 #undef VARIANT_EQUAL_CASE
576 
577   bool operator!=(const Variant &Other) const { return !(*this == Other); }
578   Variant &operator=(const Variant &Other) {
579     if (this == &Other)
580       return *this;
581     if (Type == PDB_VariantType::String)
582       delete[] Value.String;
583     Type = Other.Type;
584     Value = Other.Value;
585     if (Other.Type == PDB_VariantType::String &&
586         Other.Value.String != nullptr) {
587       Value.String = new char[strlen(Other.Value.String) + 1];
588       ::strcpy(Value.String, Other.Value.String);
589     }
590     return *this;
591   }
592 };
593 
594 } // end namespace pdb
595 } // end namespace llvm
596 
597 namespace std {
598 
599 template <> struct hash<llvm::pdb::PDB_SymType> {
600   using argument_type = llvm::pdb::PDB_SymType;
601   using result_type = std::size_t;
602 
603   result_type operator()(const argument_type &Arg) const {
604     return std::hash<int>()(static_cast<int>(Arg));
605   }
606 };
607 
608 } // end namespace std
609 
610 #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H
611