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