| //===- PDBTypes.h - Defines enums for various fields contained in PDB ----====// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H |
| #define LLVM_DEBUGINFO_PDB_PDBTYPES_H |
| |
| #include "llvm/ADT/APFloat.h" |
| #include "llvm/DebugInfo/CodeView/CodeView.h" |
| #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" |
| #include "llvm/DebugInfo/PDB/IPDBFrameData.h" |
| #include "llvm/DebugInfo/PDB/Native/RawTypes.h" |
| #include <cctype> |
| #include <cstddef> |
| #include <cstdint> |
| #include <cstring> |
| #include <functional> |
| |
| namespace llvm { |
| namespace pdb { |
| |
| typedef uint32_t SymIndexId; |
| |
| class IPDBDataStream; |
| class IPDBInjectedSource; |
| class IPDBLineNumber; |
| class IPDBSectionContrib; |
| class IPDBSession; |
| class IPDBSourceFile; |
| class IPDBTable; |
| class PDBSymDumper; |
| class PDBSymbol; |
| class PDBSymbolExe; |
| class PDBSymbolCompiland; |
| class PDBSymbolCompilandDetails; |
| class PDBSymbolCompilandEnv; |
| class PDBSymbolFunc; |
| class PDBSymbolBlock; |
| class PDBSymbolData; |
| class PDBSymbolAnnotation; |
| class PDBSymbolLabel; |
| class PDBSymbolPublicSymbol; |
| class PDBSymbolTypeUDT; |
| class PDBSymbolTypeEnum; |
| class PDBSymbolTypeFunctionSig; |
| class PDBSymbolTypePointer; |
| class PDBSymbolTypeArray; |
| class PDBSymbolTypeBuiltin; |
| class PDBSymbolTypeTypedef; |
| class PDBSymbolTypeBaseClass; |
| class PDBSymbolTypeFriend; |
| class PDBSymbolTypeFunctionArg; |
| class PDBSymbolFuncDebugStart; |
| class PDBSymbolFuncDebugEnd; |
| class PDBSymbolUsingNamespace; |
| class PDBSymbolTypeVTableShape; |
| class PDBSymbolTypeVTable; |
| class PDBSymbolCustom; |
| class PDBSymbolThunk; |
| class PDBSymbolTypeCustom; |
| class PDBSymbolTypeManaged; |
| class PDBSymbolTypeDimension; |
| class PDBSymbolUnknown; |
| |
| using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>; |
| using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>; |
| using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>; |
| using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>; |
| using IPDBEnumTables = IPDBEnumChildren<IPDBTable>; |
| using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>; |
| using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>; |
| using IPDBEnumFrameData = IPDBEnumChildren<IPDBFrameData>; |
| |
| /// Specifies which PDB reader implementation is to be used. Only a value |
| /// of PDB_ReaderType::DIA is currently supported, but Native is in the works. |
| enum class PDB_ReaderType { |
| DIA = 0, |
| Native = 1, |
| }; |
| |
| /// An enumeration indicating the type of data contained in this table. |
| enum class PDB_TableType { |
| TableInvalid = 0, |
| Symbols, |
| SourceFiles, |
| LineNumbers, |
| SectionContribs, |
| Segments, |
| InjectedSources, |
| FrameData, |
| InputAssemblyFiles, |
| Dbg |
| }; |
| |
| /// Defines flags used for enumerating child symbols. This corresponds to the |
| /// NameSearchOptions enumeration which is documented here: |
| /// https://msdn.microsoft.com/en-us/library/yat28ads.aspx |
| enum PDB_NameSearchFlags { |
| NS_Default = 0x0, |
| NS_CaseSensitive = 0x1, |
| NS_CaseInsensitive = 0x2, |
| NS_FileNameExtMatch = 0x4, |
| NS_Regex = 0x8, |
| NS_UndecoratedName = 0x10, |
| |
| // For backward compatibility. |
| NS_CaseInFileNameExt = NS_CaseInsensitive | NS_FileNameExtMatch, |
| NS_CaseRegex = NS_Regex | NS_CaseSensitive, |
| NS_CaseInRex = NS_Regex | NS_CaseInsensitive |
| }; |
| |
| /// Specifies the hash algorithm that a source file from a PDB was hashed with. |
| /// This corresponds to the CV_SourceChksum_t enumeration and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx |
| enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 }; |
| |
| /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx |
| using PDB_Cpu = codeview::CPUType; |
| |
| enum class PDB_Machine { |
| Invalid = 0xffff, |
| Unknown = 0x0, |
| Am33 = 0x13, |
| Amd64 = 0x8664, |
| Arm = 0x1C0, |
| Arm64 = 0xaa64, |
| ArmNT = 0x1C4, |
| Ebc = 0xEBC, |
| x86 = 0x14C, |
| Ia64 = 0x200, |
| M32R = 0x9041, |
| Mips16 = 0x266, |
| MipsFpu = 0x366, |
| MipsFpu16 = 0x466, |
| PowerPC = 0x1F0, |
| PowerPCFP = 0x1F1, |
| R4000 = 0x166, |
| SH3 = 0x1A2, |
| SH3DSP = 0x1A3, |
| SH4 = 0x1A6, |
| SH5 = 0x1A8, |
| Thumb = 0x1C2, |
| WceMipsV2 = 0x169 |
| }; |
| |
| // A struct with an inner unnamed enum with explicit underlying type resuls |
| // in an enum class that can implicitly convert to the underlying type, which |
| // is convenient for this enum. |
| struct PDB_SourceCompression { |
| enum : uint32_t { |
| // No compression. Produced e.g. by `link.exe /natvis:foo.natvis`. |
| None, |
| // Not known what produces this. |
| RunLengthEncoded, |
| // Not known what produces this. |
| Huffman, |
| // Not known what produces this. |
| LZ, |
| // Produced e.g. by `csc /debug`. The encoded data is its own mini-stream |
| // with the following layout (in little endian): |
| // GUID LanguageTypeGuid; |
| // GUID LanguageVendorGuid; |
| // GUID DocumentTypeGuid; |
| // GUID HashFunctionGuid; |
| // uint32_t HashDataSize; |
| // uint32_t CompressedDataSize; |
| // Followed by HashDataSize bytes containing a hash checksum, |
| // followed by CompressedDataSize bytes containing source contents. |
| // |
| // CompressedDataSize can be 0, in this case only the hash data is present. |
| // (CompressedDataSize is != 0 e.g. if `/embed` is passed to csc.exe.) |
| // The compressed data format is: |
| // uint32_t UncompressedDataSize; |
| // If UncompressedDataSize is 0, the data is stored uncompressed and |
| // CompressedDataSize stores the uncompressed size. |
| // If UncompressedDataSize is != 0, then the data is in raw deflate |
| // encoding as described in rfc1951. |
| // |
| // A GUID is 16 bytes, stored in the usual |
| // uint32_t |
| // uint16_t |
| // uint16_t |
| // uint8_t[24] |
| // layout. |
| // |
| // Well-known GUIDs for LanguageTypeGuid are: |
| // 63a08714-fc37-11d2-904c-00c04fa302a1 C |
| // 3a12d0b7-c26c-11d0-b442-00a0244a1dd2 C++ |
| // 3f5162f8-07c6-11d3-9053-00c04fa302a1 C# |
| // af046cd1-d0e1-11d2-977c-00a0c9b4d50c Cobol |
| // ab4f38c9-b6e6-43ba-be3b-58080b2ccce3 F# |
| // 3a12d0b4-c26c-11d0-b442-00a0244a1dd2 Java |
| // 3a12d0b6-c26c-11d0-b442-00a0244a1dd2 JScript |
| // af046cd2-d0e1-11d2-977c-00a0c9b4d50c Pascal |
| // 3a12d0b8-c26c-11d0-b442-00a0244a1dd2 Visual Basic |
| // |
| // Well-known GUIDs for LanguageVendorGuid are: |
| // 994b45c4-e6e9-11d2-903f-00c04fa302a1 Microsoft |
| // |
| // Well-known GUIDs for DocumentTypeGuid are: |
| // 5a869d0b-6611-11d3-bd2a-0000f80849bd Text |
| // |
| // Well-known GUIDs for HashFunctionGuid are: |
| // 406ea660-64cf-4c82-b6f0-42d48172a799 MD5 (HashDataSize is 16) |
| // ff1816ec-aa5e-4d10-87f7-6f4963833460 SHA1 (HashDataSize is 20) |
| // 8829d00f-11b8-4213-878b-770e8597ac16 SHA256 (HashDataSize is 32) |
| DotNet = 101, |
| }; |
| }; |
| |
| /// These values correspond to the CV_call_e enumeration, and are documented |
| /// at the following locations: |
| /// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx |
| /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx |
| using PDB_CallingConv = codeview::CallingConvention; |
| |
| /// These values correspond to the CV_CFL_LANG enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx |
| using PDB_Lang = codeview::SourceLanguage; |
| |
| /// These values correspond to the DataKind enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx |
| enum class PDB_DataKind { |
| Unknown, |
| Local, |
| StaticLocal, |
| Param, |
| ObjectPtr, |
| FileStatic, |
| Global, |
| Member, |
| StaticMember, |
| Constant |
| }; |
| |
| /// These values correspond to the SymTagEnum enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx |
| enum class PDB_SymType { |
| None, |
| Exe, |
| Compiland, |
| CompilandDetails, |
| CompilandEnv, |
| Function, |
| Block, |
| Data, |
| Annotation, |
| Label, |
| PublicSymbol, |
| UDT, |
| Enum, |
| FunctionSig, |
| PointerType, |
| ArrayType, |
| BuiltinType, |
| Typedef, |
| BaseClass, |
| Friend, |
| FunctionArg, |
| FuncDebugStart, |
| FuncDebugEnd, |
| UsingNamespace, |
| VTableShape, |
| VTable, |
| Custom, |
| Thunk, |
| CustomType, |
| ManagedType, |
| Dimension, |
| CallSite, |
| InlineSite, |
| BaseInterface, |
| VectorType, |
| MatrixType, |
| HLSLType, |
| Caller, |
| Callee, |
| Export, |
| HeapAllocationSite, |
| CoffGroup, |
| Inlinee, |
| Max |
| }; |
| |
| /// These values correspond to the LocationType enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/f57kaez3.aspx |
| enum class PDB_LocType { |
| Null, |
| Static, |
| TLS, |
| RegRel, |
| ThisRel, |
| Enregistered, |
| BitField, |
| Slot, |
| IlRel, |
| MetaData, |
| Constant, |
| RegRelAliasIndir, |
| Max |
| }; |
| |
| /// These values correspond to the UdtKind enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/wcstk66t.aspx |
| enum class PDB_UdtType { Struct, Class, Union, Interface }; |
| |
| /// These values correspond to the StackFrameTypeEnum enumeration, and are |
| /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. |
| enum class PDB_StackFrameType : uint16_t { |
| FPO, |
| KernelTrap, |
| KernelTSS, |
| EBP, |
| FrameData, |
| Unknown = 0xffff |
| }; |
| |
| /// These values correspond to the MemoryTypeEnum enumeration, and are |
| /// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx. |
| enum class PDB_MemoryType : uint16_t { |
| Code, |
| Data, |
| Stack, |
| HeapCode, |
| Any = 0xffff |
| }; |
| |
| /// These values correspond to the Basictype enumeration, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx |
| enum class PDB_BuiltinType { |
| None = 0, |
| Void = 1, |
| Char = 2, |
| WCharT = 3, |
| Int = 6, |
| UInt = 7, |
| Float = 8, |
| BCD = 9, |
| Bool = 10, |
| Long = 13, |
| ULong = 14, |
| Currency = 25, |
| Date = 26, |
| Variant = 27, |
| Complex = 28, |
| Bitfield = 29, |
| BSTR = 30, |
| HResult = 31, |
| Char16 = 32, |
| Char32 = 33 |
| }; |
| |
| /// These values correspond to the flags that can be combined to control the |
| /// return of an undecorated name for a C++ decorated name, and are documented |
| /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx |
| enum PDB_UndnameFlags : uint32_t { |
| Undname_Complete = 0x0, |
| Undname_NoLeadingUnderscores = 0x1, |
| Undname_NoMsKeywords = 0x2, |
| Undname_NoFuncReturns = 0x4, |
| Undname_NoAllocModel = 0x8, |
| Undname_NoAllocLang = 0x10, |
| Undname_Reserved1 = 0x20, |
| Undname_Reserved2 = 0x40, |
| Undname_NoThisType = 0x60, |
| Undname_NoAccessSpec = 0x80, |
| Undname_NoThrowSig = 0x100, |
| Undname_NoMemberType = 0x200, |
| Undname_NoReturnUDTModel = 0x400, |
| Undname_32BitDecode = 0x800, |
| Undname_NameOnly = 0x1000, |
| Undname_TypeOnly = 0x2000, |
| Undname_HaveParams = 0x4000, |
| Undname_NoECSU = 0x8000, |
| Undname_NoIdentCharCheck = 0x10000, |
| Undname_NoPTR64 = 0x20000 |
| }; |
| |
| enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 }; |
| |
| struct VersionInfo { |
| uint32_t Major; |
| uint32_t Minor; |
| uint32_t Build; |
| uint32_t QFE; |
| }; |
| |
| enum PDB_VariantType { |
| Empty, |
| Unknown, |
| Int8, |
| Int16, |
| Int32, |
| Int64, |
| Single, |
| Double, |
| UInt8, |
| UInt16, |
| UInt32, |
| UInt64, |
| Bool, |
| String |
| }; |
| |
| struct Variant { |
| Variant() = default; |
| |
| explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; } |
| explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; } |
| explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) { |
| Value.Int16 = V; |
| } |
| explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) { |
| Value.Int32 = V; |
| } |
| explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) { |
| Value.Int64 = V; |
| } |
| explicit Variant(float V) : Type(PDB_VariantType::Single) { |
| Value.Single = V; |
| } |
| explicit Variant(double V) : Type(PDB_VariantType::Double) { |
| Value.Double = V; |
| } |
| explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) { |
| Value.UInt8 = V; |
| } |
| explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) { |
| Value.UInt16 = V; |
| } |
| explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) { |
| Value.UInt32 = V; |
| } |
| explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) { |
| Value.UInt64 = V; |
| } |
| |
| Variant(const Variant &Other) { |
| *this = Other; |
| } |
| |
| ~Variant() { |
| if (Type == PDB_VariantType::String) |
| delete[] Value.String; |
| } |
| |
| PDB_VariantType Type = PDB_VariantType::Empty; |
| union { |
| bool Bool; |
| int8_t Int8; |
| int16_t Int16; |
| int32_t Int32; |
| int64_t Int64; |
| float Single; |
| double Double; |
| uint8_t UInt8; |
| uint16_t UInt16; |
| uint32_t UInt32; |
| uint64_t UInt64; |
| char *String; |
| } Value; |
| |
| bool isIntegralType() const { |
| switch (Type) { |
| case Bool: |
| case Int8: |
| case Int16: |
| case Int32: |
| case Int64: |
| case UInt8: |
| case UInt16: |
| case UInt32: |
| case UInt64: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| #define VARIANT_WIDTH(Enum, NumBits) \ |
| case PDB_VariantType::Enum: \ |
| return NumBits; |
| |
| unsigned getBitWidth() const { |
| switch (Type) { |
| VARIANT_WIDTH(Bool, 1u) |
| VARIANT_WIDTH(Int8, 8u) |
| VARIANT_WIDTH(Int16, 16u) |
| VARIANT_WIDTH(Int32, 32u) |
| VARIANT_WIDTH(Int64, 64u) |
| VARIANT_WIDTH(Single, 32u) |
| VARIANT_WIDTH(Double, 64u) |
| VARIANT_WIDTH(UInt8, 8u) |
| VARIANT_WIDTH(UInt16, 16u) |
| VARIANT_WIDTH(UInt32, 32u) |
| VARIANT_WIDTH(UInt64, 64u) |
| default: |
| assert(false && "Variant::toAPSInt called on non-numeric type"); |
| return 0u; |
| } |
| } |
| |
| #undef VARIANT_WIDTH |
| |
| #define VARIANT_APSINT(Enum, NumBits, IsUnsigned) \ |
| case PDB_VariantType::Enum: \ |
| return APSInt(APInt(NumBits, Value.Enum), IsUnsigned); |
| |
| APSInt toAPSInt() const { |
| switch (Type) { |
| VARIANT_APSINT(Bool, 1u, true) |
| VARIANT_APSINT(Int8, 8u, false) |
| VARIANT_APSINT(Int16, 16u, false) |
| VARIANT_APSINT(Int32, 32u, false) |
| VARIANT_APSINT(Int64, 64u, false) |
| VARIANT_APSINT(UInt8, 8u, true) |
| VARIANT_APSINT(UInt16, 16u, true) |
| VARIANT_APSINT(UInt32, 32u, true) |
| VARIANT_APSINT(UInt64, 64u, true) |
| default: |
| assert(false && "Variant::toAPSInt called on non-integral type"); |
| return APSInt(); |
| } |
| } |
| |
| #undef VARIANT_APSINT |
| |
| APFloat toAPFloat() const { |
| // Float constants may be tagged as integers. |
| switch (Type) { |
| case PDB_VariantType::Single: |
| case PDB_VariantType::UInt32: |
| case PDB_VariantType::Int32: |
| return APFloat(Value.Single); |
| case PDB_VariantType::Double: |
| case PDB_VariantType::UInt64: |
| case PDB_VariantType::Int64: |
| return APFloat(Value.Double); |
| default: |
| assert(false && "Variant::toAPFloat called on non-floating-point type"); |
| return APFloat::getZero(APFloat::IEEEsingle()); |
| } |
| } |
| |
| #define VARIANT_EQUAL_CASE(Enum) \ |
| case PDB_VariantType::Enum: \ |
| return Value.Enum == Other.Value.Enum; |
| |
| bool operator==(const Variant &Other) const { |
| if (Type != Other.Type) |
| return false; |
| switch (Type) { |
| VARIANT_EQUAL_CASE(Bool) |
| VARIANT_EQUAL_CASE(Int8) |
| VARIANT_EQUAL_CASE(Int16) |
| VARIANT_EQUAL_CASE(Int32) |
| VARIANT_EQUAL_CASE(Int64) |
| VARIANT_EQUAL_CASE(Single) |
| VARIANT_EQUAL_CASE(Double) |
| VARIANT_EQUAL_CASE(UInt8) |
| VARIANT_EQUAL_CASE(UInt16) |
| VARIANT_EQUAL_CASE(UInt32) |
| VARIANT_EQUAL_CASE(UInt64) |
| VARIANT_EQUAL_CASE(String) |
| default: |
| return true; |
| } |
| } |
| |
| #undef VARIANT_EQUAL_CASE |
| |
| bool operator!=(const Variant &Other) const { return !(*this == Other); } |
| Variant &operator=(const Variant &Other) { |
| if (this == &Other) |
| return *this; |
| if (Type == PDB_VariantType::String) |
| delete[] Value.String; |
| Type = Other.Type; |
| Value = Other.Value; |
| if (Other.Type == PDB_VariantType::String && |
| Other.Value.String != nullptr) { |
| Value.String = new char[strlen(Other.Value.String) + 1]; |
| ::strcpy(Value.String, Other.Value.String); |
| } |
| return *this; |
| } |
| }; |
| |
| } // end namespace pdb |
| } // end namespace llvm |
| |
| namespace std { |
| |
| template <> struct hash<llvm::pdb::PDB_SymType> { |
| using argument_type = llvm::pdb::PDB_SymType; |
| using result_type = std::size_t; |
| |
| result_type operator()(const argument_type &Arg) const { |
| return std::hash<int>()(static_cast<int>(Arg)); |
| } |
| }; |
| |
| } // end namespace std |
| |
| #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H |