1*5a736c9bSZachary Turner===================================== 23f0627c5SZachary TurnerCodeView Type Records 33f0627c5SZachary Turner===================================== 43f0627c5SZachary Turner 5*5a736c9bSZachary Turner 6*5a736c9bSZachary Turner.. contents:: 7*5a736c9bSZachary Turner :local: 8*5a736c9bSZachary Turner 9*5a736c9bSZachary Turner.. _types_intro: 10*5a736c9bSZachary Turner 11*5a736c9bSZachary TurnerIntroduction 12*5a736c9bSZachary Turner============ 13*5a736c9bSZachary Turner 14*5a736c9bSZachary TurnerThis document describes the usage and serialization format of the various 15*5a736c9bSZachary TurnerCodeView type records that LLVM understands. This document does not describe 16*5a736c9bSZachary Turnerevery single CodeView type record that is defined. In some cases, this is 17*5a736c9bSZachary Turnerbecause the records are clearly deprecated and can only appear in very old 18*5a736c9bSZachary Turnersoftware (e.g. the 16-bit types). On other cases, it is because the records 19*5a736c9bSZachary Turnerhave never been observed in practice. This could be because they are only 20*5a736c9bSZachary Turnergenerated for non-C++ code (e.g. Visual Basic, C#), or because they have been 21*5a736c9bSZachary Turnermade obsolete by newer records, or any number of other reasons. However, the 22*5a736c9bSZachary Turnerrecords we describe here should cover 99% of type records that one can expect 23*5a736c9bSZachary Turnerto encounter when dealing with modern C++ toolchains. 24*5a736c9bSZachary Turner 25*5a736c9bSZachary TurnerRecord Categories 26*5a736c9bSZachary Turner================= 27*5a736c9bSZachary Turner 28*5a736c9bSZachary TurnerWe can think of a sequence of CodeView type records as an array of variable length 29*5a736c9bSZachary Turner`leaf records`. Each such record describes its own length as part of a fixed-size 30*5a736c9bSZachary Turnerheader, as well as the kind of record it is. Leaf records are either padded to 4 31*5a736c9bSZachary Turnerbytes (if this type stream appears in a TPI/IPI stream of a PDB) or not padded at 32*5a736c9bSZachary Turnerall (if this type stream appears in the ``.debug$T`` section of an object file). 33*5a736c9bSZachary TurnerPadding is implemented by inserting a decreasing sequence of `<_padding_records>` 34*5a736c9bSZachary Turnerthat terminates with ``LF_PAD0``. 35*5a736c9bSZachary Turner 36*5a736c9bSZachary TurnerThe final category of record is a ``member record``. One particular leaf type -- 37*5a736c9bSZachary Turner``LF_FIELDLIST`` -- contains a series of embedded records. While the outer 38*5a736c9bSZachary Turner``LF_FIELDLIST`` describes its length (like any other leaf record), the embedded 39*5a736c9bSZachary Turnerrecords -- called ``member records`` do not. 40*5a736c9bSZachary Turner 41*5a736c9bSZachary Turner.. _leaf_types: 42*5a736c9bSZachary Turner 43*5a736c9bSZachary TurnerLeaf Records 44*5a736c9bSZachary Turner------------ 45*5a736c9bSZachary Turner 46*5a736c9bSZachary TurnerAll leaf records begin with the following 4 byte prefix: 47*5a736c9bSZachary Turner 48*5a736c9bSZachary Turner.. code-block:: c++ 49*5a736c9bSZachary Turner 50*5a736c9bSZachary Turner struct RecordHeader { 51*5a736c9bSZachary Turner uint16_t RecordLen; // Record length, not including this 2 byte field. 52*5a736c9bSZachary Turner uint16_t RecordKind; // Record kind enum. 53*5a736c9bSZachary Turner }; 54*5a736c9bSZachary Turner 55*5a736c9bSZachary TurnerLF_POINTER (0x1002) 56*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 57*5a736c9bSZachary Turner 58*5a736c9bSZachary Turner**Usage:** Describes a pointer to another type. 59*5a736c9bSZachary Turner 60*5a736c9bSZachary Turner**Layout:** 61*5a736c9bSZachary Turner 62*5a736c9bSZachary Turner.. code-block:: none 63*5a736c9bSZachary Turner 64*5a736c9bSZachary Turner .--------------------.-- +0 65*5a736c9bSZachary Turner | Referent Type | 66*5a736c9bSZachary Turner .--------------------.-- +4 67*5a736c9bSZachary Turner | Attributes | 68*5a736c9bSZachary Turner .--------------------.-- +8 69*5a736c9bSZachary Turner | Member Ptr Info | Only present if |Attributes| indicates this is a member pointer. 70*5a736c9bSZachary Turner .--------------------.-- +E 71*5a736c9bSZachary Turner 72*5a736c9bSZachary TurnerAttributes is a bitfield with the following layout: 73*5a736c9bSZachary Turner 74*5a736c9bSZachary Turner.. code-block:: none 75*5a736c9bSZachary Turner 76*5a736c9bSZachary Turner .-----------------------------------------------------------------------------------------------------. 77*5a736c9bSZachary Turner | Unused | Flags | Size | Modifiers | Mode | Kind | 78*5a736c9bSZachary Turner .-----------------------------------------------------------------------------------------------------. 79*5a736c9bSZachary Turner | | | | | | | 80*5a736c9bSZachary Turner 0x100 +0x16 +0x13 +0xD +0x8 +0x5 +0x0 81*5a736c9bSZachary Turner 82*5a736c9bSZachary Turnerwhere the various fields are defined by the following enums: 83*5a736c9bSZachary Turner 84*5a736c9bSZachary Turner.. code-block:: c++ 85*5a736c9bSZachary Turner 86*5a736c9bSZachary Turner enum class PointerKind : uint8_t { 87*5a736c9bSZachary Turner Near16 = 0x00, // 16 bit pointer 88*5a736c9bSZachary Turner Far16 = 0x01, // 16:16 far pointer 89*5a736c9bSZachary Turner Huge16 = 0x02, // 16:16 huge pointer 90*5a736c9bSZachary Turner BasedOnSegment = 0x03, // based on segment 91*5a736c9bSZachary Turner BasedOnValue = 0x04, // based on value of base 92*5a736c9bSZachary Turner BasedOnSegmentValue = 0x05, // based on segment value of base 93*5a736c9bSZachary Turner BasedOnAddress = 0x06, // based on address of base 94*5a736c9bSZachary Turner BasedOnSegmentAddress = 0x07, // based on segment address of base 95*5a736c9bSZachary Turner BasedOnType = 0x08, // based on type 96*5a736c9bSZachary Turner BasedOnSelf = 0x09, // based on self 97*5a736c9bSZachary Turner Near32 = 0x0a, // 32 bit pointer 98*5a736c9bSZachary Turner Far32 = 0x0b, // 16:32 pointer 99*5a736c9bSZachary Turner Near64 = 0x0c // 64 bit pointer 100*5a736c9bSZachary Turner }; 101*5a736c9bSZachary Turner enum class PointerMode : uint8_t { 102*5a736c9bSZachary Turner Pointer = 0x00, // "normal" pointer 103*5a736c9bSZachary Turner LValueReference = 0x01, // "old" reference 104*5a736c9bSZachary Turner PointerToDataMember = 0x02, // pointer to data member 105*5a736c9bSZachary Turner PointerToMemberFunction = 0x03, // pointer to member function 106*5a736c9bSZachary Turner RValueReference = 0x04 // r-value reference 107*5a736c9bSZachary Turner }; 108*5a736c9bSZachary Turner enum class PointerModifiers : uint8_t { 109*5a736c9bSZachary Turner None = 0x00, // "normal" pointer 110*5a736c9bSZachary Turner Flat32 = 0x01, // "flat" pointer 111*5a736c9bSZachary Turner Volatile = 0x02, // pointer is marked volatile 112*5a736c9bSZachary Turner Const = 0x04, // pointer is marked const 113*5a736c9bSZachary Turner Unaligned = 0x08, // pointer is marked unaligned 114*5a736c9bSZachary Turner Restrict = 0x10, // pointer is marked restrict 115*5a736c9bSZachary Turner }; 116*5a736c9bSZachary Turner enum class PointerFlags : uint8_t { 117*5a736c9bSZachary Turner WinRTSmartPointer = 0x01, // pointer is a WinRT smart pointer 118*5a736c9bSZachary Turner LValueRefThisPointer = 0x02, // pointer is a 'this' pointer of a member function with ref qualifier (e.g. void X::foo() &) 119*5a736c9bSZachary Turner RValueRefThisPointer = 0x04 // pointer is a 'this' pointer of a member function with ref qualifier (e.g. void X::foo() &&) 120*5a736c9bSZachary Turner }; 121*5a736c9bSZachary Turner 122*5a736c9bSZachary TurnerThe ``Size`` field of the Attributes bitmask is a 1-byte value indicating the 123*5a736c9bSZachary Turnerpointer size. For example, a `void*` would have a size of either 4 or 8 depending 124*5a736c9bSZachary Turneron the target architecture. On the other hand, if ``Mode`` indicates that this is 125*5a736c9bSZachary Turnera pointer to member function or pointer to data member, then the size can be any 126*5a736c9bSZachary Turnerimplementation defined number. 127*5a736c9bSZachary Turner 128*5a736c9bSZachary TurnerThe ``Member Ptr Info`` field of the ``LF_POINTER`` record is only present if the 129*5a736c9bSZachary Turnerattributes indicate that this is a pointer to member. 130*5a736c9bSZachary Turner 131*5a736c9bSZachary TurnerNote that "plain" pointers to primitive types are not represented by ``LF_POINTER`` 132*5a736c9bSZachary Turnerrecords, they are indicated by special reserved :ref:`TypeIndex values <type_indices>`. 133*5a736c9bSZachary Turner 134*5a736c9bSZachary Turner 135*5a736c9bSZachary Turner 136*5a736c9bSZachary TurnerLF_MODIFIER (0x1001) 137*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 138*5a736c9bSZachary Turner 139*5a736c9bSZachary TurnerLF_PROCEDURE (0x1008) 140*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 141*5a736c9bSZachary Turner 142*5a736c9bSZachary TurnerLF_MFUNCTION (0x1009) 143*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 144*5a736c9bSZachary Turner 145*5a736c9bSZachary TurnerLF_LABEL (0x000e) 146*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^ 147*5a736c9bSZachary Turner 148*5a736c9bSZachary TurnerLF_ARGLIST (0x1201) 149*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 150*5a736c9bSZachary Turner 151*5a736c9bSZachary TurnerLF_FIELDLIST (0x1203) 152*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 153*5a736c9bSZachary Turner 154*5a736c9bSZachary TurnerLF_ARRAY (0x1503) 155*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^ 156*5a736c9bSZachary Turner 157*5a736c9bSZachary TurnerLF_CLASS (0x1504) 158*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^ 159*5a736c9bSZachary Turner 160*5a736c9bSZachary TurnerLF_STRUCTURE (0x1505) 161*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 162*5a736c9bSZachary Turner 163*5a736c9bSZachary TurnerLF_INTERFACE (0x1519) 164*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 165*5a736c9bSZachary Turner 166*5a736c9bSZachary TurnerLF_UNION (0x1506) 167*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^ 168*5a736c9bSZachary Turner 169*5a736c9bSZachary TurnerLF_ENUM (0x1507) 170*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^ 171*5a736c9bSZachary Turner 172*5a736c9bSZachary TurnerLF_TYPESERVER2 (0x1515) 173*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^^ 174*5a736c9bSZachary Turner 175*5a736c9bSZachary TurnerLF_VFTABLE (0x151d) 176*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 177*5a736c9bSZachary Turner 178*5a736c9bSZachary TurnerLF_VTSHAPE (0x000a) 179*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 180*5a736c9bSZachary Turner 181*5a736c9bSZachary TurnerLF_BITFIELD (0x1205) 182*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 183*5a736c9bSZachary Turner 184*5a736c9bSZachary TurnerLF_FUNC_ID (0x1601) 185*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 186*5a736c9bSZachary Turner 187*5a736c9bSZachary TurnerLF_MFUNC_ID (0x1602) 188*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 189*5a736c9bSZachary Turner 190*5a736c9bSZachary TurnerLF_BUILDINFO (0x1603) 191*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 192*5a736c9bSZachary Turner 193*5a736c9bSZachary TurnerLF_SUBSTR_LIST (0x1604) 194*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^^ 195*5a736c9bSZachary Turner 196*5a736c9bSZachary TurnerLF_STRING_ID (0x1605) 197*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 198*5a736c9bSZachary Turner 199*5a736c9bSZachary TurnerLF_UDT_SRC_LINE (0x1606) 200*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^^^ 201*5a736c9bSZachary Turner 202*5a736c9bSZachary TurnerLF_UDT_MOD_SRC_LINE (0x1607) 203*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 204*5a736c9bSZachary Turner 205*5a736c9bSZachary TurnerLF_METHODLIST (0x1206) 206*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^ 207*5a736c9bSZachary Turner 208*5a736c9bSZachary TurnerLF_PRECOMP (0x1509) 209*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 210*5a736c9bSZachary Turner 211*5a736c9bSZachary TurnerLF_ENDPRECOMP (0x0014) 212*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^ 213*5a736c9bSZachary Turner 214*5a736c9bSZachary Turner.. _member_types: 215*5a736c9bSZachary Turner 216*5a736c9bSZachary TurnerMember Records 217*5a736c9bSZachary Turner-------------- 218*5a736c9bSZachary Turner 219*5a736c9bSZachary TurnerLF_BCLASS (0x1400) 220*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^ 221*5a736c9bSZachary Turner 222*5a736c9bSZachary TurnerLF_BINTERFACE (0x151a) 223*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^^ 224*5a736c9bSZachary Turner 225*5a736c9bSZachary TurnerLF_VBCLASS (0x1401) 226*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^ 227*5a736c9bSZachary Turner 228*5a736c9bSZachary TurnerLF_IVBCLASS (0x1402) 229*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 230*5a736c9bSZachary Turner 231*5a736c9bSZachary TurnerLF_VFUNCTAB (0x1409) 232*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 233*5a736c9bSZachary Turner 234*5a736c9bSZachary TurnerLF_STMEMBER (0x150e) 235*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 236*5a736c9bSZachary Turner 237*5a736c9bSZachary TurnerLF_METHOD (0x150f) 238*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^ 239*5a736c9bSZachary Turner 240*5a736c9bSZachary TurnerLF_MEMBER (0x150d) 241*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^ 242*5a736c9bSZachary Turner 243*5a736c9bSZachary TurnerLF_NESTTYPE (0x1510) 244*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^ 245*5a736c9bSZachary Turner 246*5a736c9bSZachary TurnerLF_ONEMETHOD (0x1511) 247*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 248*5a736c9bSZachary Turner 249*5a736c9bSZachary TurnerLF_ENUMERATE (0x1502) 250*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^^^^ 251*5a736c9bSZachary Turner 252*5a736c9bSZachary TurnerLF_INDEX (0x1404) 253*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^ 254*5a736c9bSZachary Turner 255*5a736c9bSZachary Turner.. _padding_records: 256*5a736c9bSZachary Turner 257*5a736c9bSZachary TurnerPadding Records 258*5a736c9bSZachary Turner--------------- 259*5a736c9bSZachary Turner 260*5a736c9bSZachary TurnerLF_PADn (0xf0 + n) 261*5a736c9bSZachary Turner^^^^^^^^^^^^^^^^^^ 262