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};
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
361enum 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
384enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
385
386struct VersionInfo {
387  uint32_t Major;
388  uint32_t Minor;
389  uint32_t Build;
390  uint32_t QFE;
391};
392
393enum 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
410struct Variant {
411  Variant() = default;
412
413  explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; }
414  explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; }
415  explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) {
416    Value.Int16 = V;
417  }
418  explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) {
419    Value.Int32 = V;
420  }
421  explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) {
422    Value.Int64 = V;
423  }
424  explicit Variant(float V) : Type(PDB_VariantType::Single) {
425    Value.Single = V;
426  }
427  explicit Variant(double V) : Type(PDB_VariantType::Double) {
428    Value.Double = V;
429  }
430  explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) {
431    Value.UInt8 = V;
432  }
433  explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) {
434    Value.UInt16 = V;
435  }
436  explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) {
437    Value.UInt32 = V;
438  }
439  explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) {
440    Value.UInt64 = V;
441  }
442
443  Variant(const Variant &Other) {
444    *this = Other;
445  }
446
447  ~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
468  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
489  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
514  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
533  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
597namespace std {
598
599template <> 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