//===-- CodeView.h - On-disk record types for CodeView ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief This file provides data structures useful for consuming on-disk /// CodeView. It is based on information published by Microsoft at /// https://github.com/Microsoft/microsoft-pdb/. /// //===----------------------------------------------------------------------===// // FIXME: Find a home for this in include/llvm/DebugInfo/CodeView/. #ifndef LLVM_READOBJ_CODEVIEW_H #define LLVM_READOBJ_CODEVIEW_H #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/Endian.h" namespace llvm { namespace codeview { using llvm::support::little32_t; using llvm::support::ulittle16_t; using llvm::support::ulittle32_t; /// Data in the the SUBSEC_FRAMEDATA subection. struct FrameData { ulittle32_t RvaStart; ulittle32_t CodeSize; ulittle32_t LocalSize; ulittle32_t ParamsSize; ulittle32_t MaxStackSize; ulittle32_t FrameFunc; ulittle16_t PrologSize; ulittle16_t SavedRegsSize; ulittle32_t Flags; enum : uint32_t { HasSEH = 1 << 0, HasEH = 1 << 1, IsFunctionStart = 1 << 2, }; }; //===----------------------------------------------------------------------===// // On-disk representation of type information // A CodeView type stream is a sequence of TypeRecords. Records larger than // 65536 must chain on to a second record. Each TypeRecord is followed by one of // the leaf types described below. struct TypeRecordPrefix { ulittle16_t Len; // Type record length, starting from &Leaf. ulittle16_t Leaf; // Type record kind (TypeLeafKind) }; // LF_TYPESERVER2 struct TypeServer2 { char Signature[16]; // GUID ulittle32_t Age; // Name: Name of the PDB as a null-terminated string }; // LF_STRING_ID struct StringId { TypeIndex id; }; // LF_FUNC_ID struct FuncId { TypeIndex ParentScope; TypeIndex FunctionType; // Name: The null-terminated name follows. }; // LF_CLASS, LF_STRUCT, LF_INTERFACE struct ClassType { ulittle16_t MemberCount; // Number of members in FieldList. ulittle16_t Properties; // ClassOptions bitset TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members TypeIndex DerivedFrom; // LF_DERIVED: List of known derived classes TypeIndex VShape; // LF_VTSHAPE: Shape of the vftable // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC integer. // Name: The null-terminated name follows. }; // LF_UNION struct UnionType { ulittle16_t MemberCount; // Number of members in FieldList. ulittle16_t Properties; // ClassOptions bitset TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC integer. // Name: The null-terminated name follows. }; // LF_POINTER struct PointerType { TypeIndex PointeeType; ulittle32_t Attrs; // pointer attributes // if pointer to member: // PointerToMemberTail PointerKind getPtrKind() const { return PointerKind(Attrs & 0x1f); } PointerMode getPtrMode() const { return PointerMode((Attrs >> 5) & 0x07); } bool isFlat() const { return Attrs & (1 << 8); } bool isVolatile() const { return Attrs & (1 << 9); } bool isConst() const { return Attrs & (1 << 10); } bool isUnaligned() const { return Attrs & (1 << 11); } bool isPointerToDataMember() const { return getPtrMode() == PointerMode::PointerToDataMember; } bool isPointerToMemberFunction() const { return getPtrMode() == PointerMode::PointerToMemberFunction; } bool isPointerToMember() const { return isPointerToMemberFunction() || isPointerToDataMember(); } }; struct PointerToMemberTail { TypeIndex ClassType; ulittle16_t Representation; // PointerToMemberRepresentation }; /// In Clang parlance, these are "qualifiers". LF_MODIFIER struct TypeModifier { TypeIndex ModifiedType; ulittle16_t Modifiers; // ModifierOptions }; // LF_VTSHAPE struct VTableShape { // Number of vftable entries. Each method may have more than one entry due to // things like covariant return types. ulittle16_t VFEntryCount; // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e. }; // LF_UDT_SRC_LINE struct UDTSrcLine { TypeIndex UDT; // The user-defined type TypeIndex SourceFile; // StringID containing the source filename ulittle32_t LineNumber; }; // LF_ARGLIST, LF_SUBSTR_LIST struct ArgList { ulittle32_t NumArgs; // Number of arguments // ArgTypes[]: Type indicies of arguments }; // LF_BUILDINFO struct BuildInfo { ulittle16_t NumArgs; // Number of arguments // ArgTypes[]: Type indicies of arguments }; // LF_ENUM struct EnumType { ulittle16_t NumEnumerators; // Number of enumerators ulittle16_t Properties; TypeIndex UnderlyingType; TypeIndex FieldListType; // Name: The null-terminated name follows. }; // LF_ARRAY struct ArrayType { TypeIndex ElementType; TypeIndex IndexType; // SizeOf: LF_NUMERIC encoded size in bytes. Not element count! // Name: The null-terminated name follows. }; // LF_VFTABLE struct VFTableType { TypeIndex CompleteClass; // Class that owns this vftable. TypeIndex OverriddenVFTable; // VFTable that this overrides. ulittle32_t VFPtrOffset; // VFPtr offset in CompleteClass ulittle32_t NamesLen; // Length of subsequent names array in bytes. // Names: A sequence of null-terminated strings. First string is vftable // names. }; // LF_MFUNC_ID struct MemberFuncId { TypeIndex ClassType; TypeIndex FunctionType; // Name: The null-terminated name follows. }; // LF_PROCEDURE struct ProcedureType { TypeIndex ReturnType; CallingConvention CallConv; FunctionOptions Options; ulittle16_t NumParameters; TypeIndex ArgListType; }; // LF_MFUNCTION struct MemberFunctionType { TypeIndex ReturnType; TypeIndex ClassType; TypeIndex ThisType; CallingConvention CallConv; FunctionOptions Options; ulittle16_t NumParameters; TypeIndex ArgListType; little32_t ThisAdjustment; }; //===----------------------------------------------------------------------===// // Field list records, which do not include leafs or sizes /// Equvalent to CV_fldattr_t in cvinfo.h. struct MemberAttributes { ulittle16_t Attrs; /// Get the access specifier. Valid for any kind of member. MemberAccess getAccess() const { return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask)); } /// Indicates if a method is defined with friend, virtual, static, etc. MethodKind getMethodKind() const { return MethodKind( (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >> 2); } /// Get the flags that are not included in access control or method /// properties. MethodOptions getFlags() const { return MethodOptions( unsigned(Attrs) & ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask)); } /// Is this method virtual. bool isVirtual() const { auto MP = getMethodKind(); return MP != MethodKind::Vanilla && MP != MethodKind::Friend && MP != MethodKind::Static; } /// Does this member introduce a new virtual method. bool isIntroducedVirtual() const { auto MP = getMethodKind(); return MP == MethodKind::IntroducingVirtual || MP == MethodKind::PureIntroducingVirtual; } }; // LF_NESTTYPE struct NestedType { ulittle16_t Pad0; // Should be zero TypeIndex Type; // Type index of nested type // Name: Null-terminated string }; // LF_ONEMETHOD struct OneMethod { MemberAttributes Attrs; TypeIndex Type; // If is introduced virtual method: // VFTableOffset: int32_t offset in vftable // Name: Null-terminated string MethodKind getMethodKind() const { return Attrs.getMethodKind(); } bool isVirtual() const { return Attrs.isVirtual(); } bool isIntroducedVirtual() const { return Attrs.isIntroducedVirtual(); } }; struct MethodListEntry { MemberAttributes Attrs; ulittle16_t Padding; TypeIndex Type; // If is introduced virtual method: // VFTableOffset: int32_t offset in vftable MethodKind getMethodKind() const { return Attrs.getMethodKind(); } bool isVirtual() const { return Attrs.isVirtual(); } bool isIntroducedVirtual() const { return Attrs.isIntroducedVirtual(); } }; /// For method overload sets. LF_METHOD struct OverloadedMethod { ulittle16_t MethodCount; // Size of overload set TypeIndex MethList; // Type index of methods in overload set // Name: Null-terminated string }; // LF_VFUNCTAB struct VirtualFunctionPointer { ulittle16_t Pad0; TypeIndex Type; // Type of vfptr }; // LF_MEMBER struct DataMember { MemberAttributes Attrs; // Access control attributes, etc TypeIndex Type; // FieldOffset: LF_NUMERIC encoded byte offset // Name: Null-terminated string }; // LF_STMEMBER struct StaticDataMember { MemberAttributes Attrs; // Access control attributes, etc TypeIndex Type; // Name: Null-terminated string }; // LF_ENUMERATE struct Enumerator { MemberAttributes Attrs; // Access control attributes, etc // EnumValue: LF_NUMERIC encoded enumerator value // Name: Null-terminated string }; // LF_BCLASS, LF_BINTERFACE struct BaseClass { MemberAttributes Attrs; // Access control attributes, etc TypeIndex BaseType; // Base class type // BaseOffset: LF_NUMERIC encoded byte offset of base from derived. }; // LF_VBCLASS | LV_IVBCLASS struct VirtualBaseClass { MemberAttributes Attrs; // Access control attributes, etc. TypeIndex BaseType; // Base class type TypeIndex VBPtrType; // Virtual base pointer type // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC. // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC. }; } // namespace codeview } // namespace llvm #endif // LLVM_READOBJ_CODEVIEW_H