//===- 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 #include #include #include #include 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; using IPDBEnumSourceFiles = IPDBEnumChildren; using IPDBEnumDataStreams = IPDBEnumChildren; using IPDBEnumLineNumbers = IPDBEnumChildren; using IPDBEnumTables = IPDBEnumChildren; using IPDBEnumInjectedSources = IPDBEnumChildren; using IPDBEnumSectionContribs = IPDBEnumChildren; using IPDBEnumFrameData = IPDBEnumChildren; /// 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, Char8 = 34, }; /// 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 { using argument_type = llvm::pdb::PDB_SymType; using result_type = std::size_t; result_type operator()(const argument_type &Arg) const { return std::hash()(static_cast(Arg)); } }; } // end namespace std #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H