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