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   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
362 enum 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 
385 enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
386 
387 struct VersionInfo {
388   uint32_t Major;
389   uint32_t Minor;
390   uint32_t Build;
391   uint32_t QFE;
392 };
393 
394 enum 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 
411 struct Variant {
412   Variant() = default;
413 
VariantVariant414   explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; }
VariantVariant415   explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; }
VariantVariant416   explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) {
417     Value.Int16 = V;
418   }
VariantVariant419   explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) {
420     Value.Int32 = V;
421   }
VariantVariant422   explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) {
423     Value.Int64 = V;
424   }
VariantVariant425   explicit Variant(float V) : Type(PDB_VariantType::Single) {
426     Value.Single = V;
427   }
VariantVariant428   explicit Variant(double V) : Type(PDB_VariantType::Double) {
429     Value.Double = V;
430   }
VariantVariant431   explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) {
432     Value.UInt8 = V;
433   }
VariantVariant434   explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) {
435     Value.UInt16 = V;
436   }
VariantVariant437   explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) {
438     Value.UInt32 = V;
439   }
VariantVariant440   explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) {
441     Value.UInt64 = V;
442   }
443 
VariantVariant444   Variant(const Variant &Other) {
445     *this = Other;
446   }
447 
~VariantVariant448   ~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 
isIntegralTypeVariant469   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 
getBitWidthVariant490   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 
toAPSIntVariant515   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 
toAPFloatVariant534   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(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(Other.Value.String) + 1];
589       ::strcpy(Value.String, Other.Value.String);
590     }
591     return *this;
592   }
593 };
594 
595 } // end namespace pdb
596 } // end namespace llvm
597 
598 namespace std {
599 
600 template <> 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