123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- =====================================
- CodeView Type Records
- =====================================
- .. contents::
- :local:
- .. _types_intro:
- Introduction
- ============
- This document describes the usage and serialization format of the various
- CodeView type records that LLVM understands. This document does not describe
- every single CodeView type record that is defined. In some cases, this is
- because the records are clearly deprecated and can only appear in very old
- software (e.g. the 16-bit types). On other cases, it is because the records
- have never been observed in practice. This could be because they are only
- generated for non-C++ code (e.g. Visual Basic, C#), or because they have been
- made obsolete by newer records, or any number of other reasons. However, the
- records we describe here should cover 99% of type records that one can expect
- to encounter when dealing with modern C++ toolchains.
- Record Categories
- =================
- We can think of a sequence of CodeView type records as an array of variable length
- `leaf records`. Each such record describes its own length as part of a fixed-size
- header, as well as the kind of record it is. Leaf records are either padded to 4
- bytes (if this type stream appears in a TPI/IPI stream of a PDB) or not padded at
- all (if this type stream appears in the ``.debug$T`` section of an object file).
- Padding is implemented by inserting a decreasing sequence of `<_padding_records>`
- that terminates with ``LF_PAD0``.
- The final category of record is a ``member record``. One particular leaf type --
- ``LF_FIELDLIST`` -- contains a series of embedded records. While the outer
- ``LF_FIELDLIST`` describes its length (like any other leaf record), the embedded
- records -- called ``member records`` do not.
- .. _leaf_types:
- Leaf Records
- ------------
- All leaf records begin with the following 4 byte prefix:
- .. code-block:: c++
- struct RecordHeader {
- uint16_t RecordLen; // Record length, not including this 2 byte field.
- uint16_t RecordKind; // Record kind enum.
- };
- LF_POINTER (0x1002)
- ^^^^^^^^^^^^^^^^^^^
- **Usage:** Describes a pointer to another type.
- **Layout:**
- .. code-block:: none
- .--------------------.-- +0
- | Referent Type |
- .--------------------.-- +4
- | Attributes |
- .--------------------.-- +8
- | Member Ptr Info | Only present if |Attributes| indicates this is a member pointer.
- .--------------------.-- +E
- Attributes is a bitfield with the following layout:
- .. code-block:: none
- .-----------------------------------------------------------------------------------------------------.
- | Unused | Flags | Size | Modifiers | Mode | Kind |
- .-----------------------------------------------------------------------------------------------------.
- | | | | | | |
- 0x100 +0x16 +0x13 +0xD +0x8 +0x5 +0x0
- where the various fields are defined by the following enums:
- .. code-block:: c++
- enum class PointerKind : uint8_t {
- Near16 = 0x00, // 16 bit pointer
- Far16 = 0x01, // 16:16 far pointer
- Huge16 = 0x02, // 16:16 huge pointer
- BasedOnSegment = 0x03, // based on segment
- BasedOnValue = 0x04, // based on value of base
- BasedOnSegmentValue = 0x05, // based on segment value of base
- BasedOnAddress = 0x06, // based on address of base
- BasedOnSegmentAddress = 0x07, // based on segment address of base
- BasedOnType = 0x08, // based on type
- BasedOnSelf = 0x09, // based on self
- Near32 = 0x0a, // 32 bit pointer
- Far32 = 0x0b, // 16:32 pointer
- Near64 = 0x0c // 64 bit pointer
- };
- enum class PointerMode : uint8_t {
- Pointer = 0x00, // "normal" pointer
- LValueReference = 0x01, // "old" reference
- PointerToDataMember = 0x02, // pointer to data member
- PointerToMemberFunction = 0x03, // pointer to member function
- RValueReference = 0x04 // r-value reference
- };
- enum class PointerModifiers : uint8_t {
- None = 0x00, // "normal" pointer
- Flat32 = 0x01, // "flat" pointer
- Volatile = 0x02, // pointer is marked volatile
- Const = 0x04, // pointer is marked const
- Unaligned = 0x08, // pointer is marked unaligned
- Restrict = 0x10, // pointer is marked restrict
- };
- enum class PointerFlags : uint8_t {
- WinRTSmartPointer = 0x01, // pointer is a WinRT smart pointer
- LValueRefThisPointer = 0x02, // pointer is a 'this' pointer of a member function with ref qualifier (e.g. void X::foo() &)
- RValueRefThisPointer = 0x04 // pointer is a 'this' pointer of a member function with ref qualifier (e.g. void X::foo() &&)
- };
- The ``Size`` field of the Attributes bitmask is a 1-byte value indicating the
- pointer size. For example, a `void*` would have a size of either 4 or 8 depending
- on the target architecture. On the other hand, if ``Mode`` indicates that this is
- a pointer to member function or pointer to data member, then the size can be any
- implementation defined number.
- The ``Member Ptr Info`` field of the ``LF_POINTER`` record is only present if the
- attributes indicate that this is a pointer to member.
- Note that "plain" pointers to primitive types are not represented by ``LF_POINTER``
- records, they are indicated by special reserved :ref:`TypeIndex values <type_indices>`.
- LF_MODIFIER (0x1001)
- ^^^^^^^^^^^^^^^^^^^^
- LF_PROCEDURE (0x1008)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_MFUNCTION (0x1009)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_LABEL (0x000e)
- ^^^^^^^^^^^^^^^^^
- LF_ARGLIST (0x1201)
- ^^^^^^^^^^^^^^^^^^^
- LF_FIELDLIST (0x1203)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_ARRAY (0x1503)
- ^^^^^^^^^^^^^^^^^
- LF_CLASS (0x1504)
- ^^^^^^^^^^^^^^^^^
- LF_STRUCTURE (0x1505)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_INTERFACE (0x1519)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_UNION (0x1506)
- ^^^^^^^^^^^^^^^^^
- LF_ENUM (0x1507)
- ^^^^^^^^^^^^^^^^
- LF_TYPESERVER2 (0x1515)
- ^^^^^^^^^^^^^^^^^^^^^^^
- LF_VFTABLE (0x151d)
- ^^^^^^^^^^^^^^^^^^^
- LF_VTSHAPE (0x000a)
- ^^^^^^^^^^^^^^^^^^^
- LF_BITFIELD (0x1205)
- ^^^^^^^^^^^^^^^^^^^^
- LF_FUNC_ID (0x1601)
- ^^^^^^^^^^^^^^^^^^^
- LF_MFUNC_ID (0x1602)
- ^^^^^^^^^^^^^^^^^^^^
- LF_BUILDINFO (0x1603)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_SUBSTR_LIST (0x1604)
- ^^^^^^^^^^^^^^^^^^^^^^^
- LF_STRING_ID (0x1605)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_UDT_SRC_LINE (0x1606)
- ^^^^^^^^^^^^^^^^^^^^^^^^
- LF_UDT_MOD_SRC_LINE (0x1607)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- LF_METHODLIST (0x1206)
- ^^^^^^^^^^^^^^^^^^^^^^
- LF_PRECOMP (0x1509)
- ^^^^^^^^^^^^^^^^^^^
- LF_ENDPRECOMP (0x0014)
- ^^^^^^^^^^^^^^^^^^^^^^
- .. _member_types:
- Member Records
- --------------
- LF_BCLASS (0x1400)
- ^^^^^^^^^^^^^^^^^^
- LF_BINTERFACE (0x151a)
- ^^^^^^^^^^^^^^^^^^^^^^
- LF_VBCLASS (0x1401)
- ^^^^^^^^^^^^^^^^^^^
- LF_IVBCLASS (0x1402)
- ^^^^^^^^^^^^^^^^^^^^
- LF_VFUNCTAB (0x1409)
- ^^^^^^^^^^^^^^^^^^^^
- LF_STMEMBER (0x150e)
- ^^^^^^^^^^^^^^^^^^^^
- LF_METHOD (0x150f)
- ^^^^^^^^^^^^^^^^^^
- LF_MEMBER (0x150d)
- ^^^^^^^^^^^^^^^^^^
- LF_NESTTYPE (0x1510)
- ^^^^^^^^^^^^^^^^^^^^
- LF_ONEMETHOD (0x1511)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_ENUMERATE (0x1502)
- ^^^^^^^^^^^^^^^^^^^^^
- LF_INDEX (0x1404)
- ^^^^^^^^^^^^^^^^^
- .. _padding_records:
- Padding Records
- ---------------
- LF_PADn (0xf0 + n)
- ^^^^^^^^^^^^^^^^^^
|