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