diff options
author | Reid Kleckner <rnk@google.com> | 2016-01-13 19:32:35 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-01-13 19:32:35 +0000 |
commit | 72e2ba7abb17a5d509df45451c546b9ac5de743f (patch) | |
tree | 209f68da6cef60b984bf971da7dfbbafba07a128 /llvm/tools/llvm-readobj/CodeView.h | |
parent | a39ca601262f2709c5b936a25f3d99c35dc84411 (diff) | |
download | llvm-72e2ba7abb17a5d509df45451c546b9ac5de743f.zip llvm-72e2ba7abb17a5d509df45451c546b9ac5de743f.tar.gz llvm-72e2ba7abb17a5d509df45451c546b9ac5de743f.tar.bz2 |
[readobj] Expand CodeView dumping functionality
This rewrites and expands the existing codeview dumping functionality in
llvm-readobj using techniques similar to those in lib/Object. This defines a
number of new records and enums useful for reading memory mapped codeview
sections in COFF objects.
The dumper is intended as a testing tool for LLVM as it grows more codeview
output capabilities.
Reviewers: majnemer
Differential Revision: http://reviews.llvm.org/D16104
llvm-svn: 257658
Diffstat (limited to 'llvm/tools/llvm-readobj/CodeView.h')
-rw-r--r-- | llvm/tools/llvm-readobj/CodeView.h | 571 |
1 files changed, 571 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/CodeView.h b/llvm/tools/llvm-readobj/CodeView.h new file mode 100644 index 0000000..444b264 --- /dev/null +++ b/llvm/tools/llvm-readobj/CodeView.h @@ -0,0 +1,571 @@ +//===-- 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 { + +/// A Symbols subsection is a sequence of SymRecords. Advancing by 'len' +/// bytes will find the next SymRecord. These are the possible types of a +/// record. Equivalent to SYM_ENUM_e in cvinfo.h. +enum SymType : uint16_t { +#define SYMBOL_TYPE(ename, value) ename = value, +#include "CVSymbolTypes.def" +}; + +/// Generic record compatible with all symbol records. +struct SymRecord { + ulittle16_t RecordLength; // Record length, starting from the next field + ulittle16_t RecordType; // Record type (SymType) + // Symbol data follows. +}; + +/// Corresponds to the CV_PROCFLAGS bitfield. +enum ProcFlags : uint8_t { + HasFP = 1 << 0, + HasIRET = 1 << 1, + HasFRET = 1 << 2, + IsNoReturn = 1 << 3, + IsUnreachable = 1 << 4, + HasCustomCallingConv = 1 << 5, + IsNoInline = 1 << 6, + HasOptimizedDebugInfo = 1 << 7, +}; + +// S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or +// S_LPROC32_DPC_ID +struct ProcSym { + ulittle32_t PtrParent; + ulittle32_t PtrEnd; + ulittle32_t PtrNext; + ulittle32_t CodeSize; + ulittle32_t DbgStart; + ulittle32_t DbgEnd; + TypeIndex FunctionType; + ulittle32_t CodeOffset; + ulittle16_t Segment; + uint8_t Flags; // CV_PROCFLAGS + // Name: The null-terminated name follows. +}; + +// S_INLINESITE +struct InlineSiteSym { + ulittle32_t PtrParent; + ulittle32_t PtrEnd; + TypeIndex Inlinee; + // BinaryAnnotations +}; + +// S_LOCAL +struct LocalSym { + TypeIndex Type; + ulittle16_t Flags; + enum : uint16_t { + IsParameter = 1 << 0, + IsAddressTaken = 1 << 1, + IsCompilerGenerated = 1 << 2, + IsAggregate = 1 << 3, + IsAggregated = 1 << 4, + IsAliased = 1 << 5, + IsAlias = 1 << 6, + IsReturnValue = 1 << 7, + IsOptimizedOut = 1 << 8, + IsEnregisteredGlobal = 1 << 9, + IsEnregisteredStatic = 1 << 10, + }; + // Name: The null-terminated name follows. +}; + +// S_BLOCK32 +struct BlockSym { + ulittle32_t PtrParent; + ulittle32_t PtrEnd; + ulittle32_t CodeSize; + ulittle32_t CodeOffset; + ulittle16_t Segment; + // Name: The null-terminated name follows. +}; + +// S_LABEL32 +struct LabelSym { + ulittle32_t CodeOffset; + ulittle16_t Segment; + uint8_t Flags; // CV_PROCFLAGS + // Name: The null-terminated name follows. +}; + +// S_OBJNAME +struct ObjNameSym { + ulittle32_t Signature; + // Name: The null-terminated name follows. +}; + +// S_COMPILE3 +struct CompileSym3 { + ulittle32_t flags; + uint8_t getLanguage() const { return flags & 0xff; } + enum Flags : uint32_t { + EC = 1 << 8, + NoDbgInfo = 1 << 9, + LTCG = 1 << 10, + NoDataAlign = 1 << 11, + ManagedPresent = 1 << 12, + SecurityChecks = 1 << 13, + HotPatch = 1 << 14, + CVTCIL = 1 << 15, + MSILModule = 1 << 16, + Sdl = 1 << 17, + PGO = 1 << 18, + Exp = 1 << 19, + }; + ulittle16_t Machine; // CPUType + ulittle16_t VersionFrontendMajor; + ulittle16_t VersionFrontendMinor; + ulittle16_t VersionFrontendBuild; + ulittle16_t VersionFrontendQFE; + ulittle16_t VersionBackendMajor; + ulittle16_t VersionBackendMinor; + ulittle16_t VersionBackendBuild; + ulittle16_t VersionBackendQFE; + // VersionString: The null-terminated version string follows. +}; + +// S_FRAMEPROC +struct FrameProcSym { + ulittle32_t TotalFrameBytes; + ulittle32_t PaddingFrameBytes; + ulittle32_t OffsetToPadding; + ulittle32_t BytesOfCalleeSavedRegisters; + ulittle32_t OffsetOfExceptionHandler; + ulittle16_t SectionIdOfExceptionHandler; + ulittle32_t Flags; +}; + +// S_CALLSITEINFO +struct CallSiteInfoSym { + ulittle32_t CodeOffset; + ulittle16_t Segment; + ulittle16_t Reserved; + TypeIndex Type; +}; + +// S_HEAPALLOCSITE +struct HeapAllocationSiteSym { + ulittle32_t CodeOffset; + ulittle16_t Segment; + ulittle16_t CallInstructionSize; + TypeIndex Type; +}; + +// S_FRAMECOOKIE +struct FrameCookieSym { + ulittle32_t CodeOffset; + ulittle16_t Register; + ulittle16_t CookieKind; + + enum : uint16_t { + Copy, + XorStackPointer, + XorFramePointer, + XorR13, + }; +}; + +// S_UDT, S_COBOLUDT +struct UDTSym { + TypeIndex Type; // Type of the UDT + // Name: The null-terminated name follows. +}; + +// S_BUILDINFO +struct BuildInfoSym { + ulittle32_t BuildId; +}; + +// S_BPREL32 +struct BPRelativeSym { + ulittle32_t Offset; // Offset from the base pointer register + TypeIndex Type; // Type of the variable + // Name: The null-terminated name follows. +}; + +// S_REGREL32 +struct RegRelativeSym { + ulittle32_t Offset; // Offset from the register + TypeIndex Type; // Type of the variable + ulittle16_t Register; // Register to which the variable is relative + // Name: The null-terminated name follows. +}; + +// S_CONSTANT, S_MANCONSTANT +struct ConstantSym { + TypeIndex Type; + // Value: The value of the constant. + // Name: The null-terminated name follows. +}; + +// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA +struct DataSym { + TypeIndex Type; + ulittle32_t DataOffset; + ulittle16_t Segment; + // Name: The null-terminated name follows. +}; + +// S_LTHREAD32, S_GTHREAD32 +struct ThreadLocalDataSym { + TypeIndex Type; + ulittle32_t DataOffset; + ulittle16_t Segment; + // Name: The null-terminated name follows. +}; + +/// 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 + +/// Indicates the kind of TypeRecord we're dealing with here. The documentation +/// and headers talk about this as the "leaf" type. +enum LeafType : uint16_t { +#define LEAF_TYPE(name, val) name = val, +#include "CVLeafTypes.def" +}; + +// 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 TypeRecord { + ulittle16_t Len; // Type record length, starting from &Leaf. + ulittle16_t Leaf; // Type record kind (LeafType) +}; + +// 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 |