ctf(5)                           File Formats                           ctf(5)

NAME
       ctf - Compact C Type Format

SYNOPSIS
       #include <ctf.h>

DESCRIPTION
       CTF  (Compact C Type Format) is designed to be a compact representation
       of the C programming language's type information,  focused  on  serving
       the  needs  of  dynamic tracing, debuggers, and other in-situ and post-
       mortem introspection tools. CTF data is generally included in  ELF  ob-
       jects,  in  a  section named .SUNW_ctf, of type SHT_SUNW_CTF, to ensure
       that the data is accessible in a running process and in subsequent core
       dumps, if generated.


       The CTF data contained in each file has information  about  the  layout
       and  sizes  of C types, including intrinsic types, enumerations, struc-
       tures, typedefs, and unions, that are used by the corresponding ELF ob-
       ject. The CTF data may also include  information  about  the  types  of
       global  objects  and  the return type and arguments of functions in the
       symbol table.


       Because CTF is often embedded inside object files,  rather  than  in  a
       standalone file, it can also be referred to as a container.


       On  Oracle Solaris systems, CTF data is consumed by DTrace and mdb. See
       dtrace(8), and mdb(1). Programmatic access  to  CTF  data  is  obtained
       through the shared object libctf.


       The  CTF file format consists of a header, followed by sections provid-
       ing information for  labels,  objects  (data),  functions,  types,  and
       strings.  The  header  starts  with a preamble field that describes the
       version, followed by links to other files, and the offsets  within  the
       file at which the following sections can be accessed. The first section
       that  follows  the header is the label section, which provides a way of
       identifying similar groups of CTF data across multiple files.  This  is
       followed  by  the object information section, which describes the types
       of global symbols. The subsequent section is the  function  information
       section,  which  describes the return types and arguments of functions.
       The next section is the type information section, which  describes  the
       format  and  layout  of the C types used in the object, and finally the
       last section is the string section, which contains the names of  types,
       enumerations, members, and labels.


       To  be  well formed, a CTF file need only contain the header, but to be
       minimally useful, the type and string sections must also be present.


       A CTF file may contain the full set of type information required by the
       associated object, or it may optionally provide a subset, and reference
       another CTF file which provides the remaining types. When  a  CTF  file
       refers  to another file, it is called the child, and the file it refers
       to is called the parent. A given file may only refer to a  single  par-
       ent.  This  process  is  called  uniquification because it ensures each
       child only has type information that is unique to it. A common  example
       of  this is that most Solaris kernel modules are uniquified against the
       genunix kernel module. This provides organizational  and  space  saving
       benefits, as the CTF for each such module only describes the types that
       are  unique  to it, and the common types shared from the kernel are not
       duplicated.

FILE FORMAT
       This document describes versions 2 and 3 of the CTF  file  format.  The
       versions  are  very  similar, offering the same features, and differing
       primarily in that version 3 is able to support a greatly expanded  num-
       ber  of  identifiers,  and to describe larger types. All cases in which
       the two versions differ are explicitly noted. When no  CTF  version  is
       specified,  the  description applies equally to both versions. The ctf-
       convert(1), ctfmerge(1), and ld(1) utilities are capable  of  producing
       either  version  2  or 3. Unless explicitly requested, CTF version 3 is
       produced by default. The libctf library provides access to CTF data  in
       a  version independent manner. Applications that obtain CTF through the
       use of libctf are therefore able to read all versions of CTF.


       Every CTF file begins with a header that describes the remainder of the
       file. The first field in the header is the preamble, which  is  defined
       as follows.

         typedef struct ctf_preamble {
                 uint16_t ctp_magic;     /* magic number (CTF_MAGIC) */
                 uint8_t ctp_version;    /* format version (CTF_VERSION) */
                 uint8_t ctp_flags;      /* flags (see below) */
         } ctf_preamble_t;



       This  preamble, which is four bytes long and must be four byte aligned,
       identifies a CTF file, and provides the format  version  employed.  All
       versions  of CTF are guaranteed to retain this definition of the pream-
       ble, and to place it at the top of the  file,  ensuring  that  all  CTF
       reading  applications  can  always  identify  all  versions of CTF. The
       ctp_version and ctp_flags fields are single byte  values,  and  can  be
       read  directly  by  both big and little endian machines without concern
       for byte order. The fields in a preamble are as follows:

       ctp_magic

           A magic number that serves to identify the file as a CTF container.
           Valid magic numbers are:


             #define CTF_MAGIC       0xcff1 /* identifying magic number */
             #define CTF_MAGIC_XLATE 0xf1cf /* CTF_MAGIC (rev. byte order) */

           A value of CTF_MAGIC indicates a CTF  file,  while  CTF_MAGIC_XLATE
           indicates  a  CTF  file that was produced on a machine that employs
           the opposite byteorder from that of the examining machine.  If  an-
           other  value is encountered, then the file should not be treated as
           CTF file.


       ctp_version

           The CTF format version. The following versions  are  currently  de-
           fined.


             #define CTF_VERSION_1   1
             #define CTF_VERSION_2   2
             #define CTF_VERSION_3   3
             #define CTF_VERSION     CTF_VERSION_3   /* current version */

           The  current  version  is  3. It is possible to encounter an unsup-
           ported version. In that case, software should not try to parse  the
           format, as it may have changed.


       ctp_flags

           ctp_flags  describes aspects of the file which modify its interpre-
           tation. Flags are defined independently for  each  version,  so  in
           principle, the value of ctp_version must be taken into account when
           evaluating ctp_flags. However, all versions of CTF to date define a
           single flag which is the same in all versions:


             #define CTF_F_COMPRESS  0x1     /* data buffer is compressed */

           The  flag  CTF_F_COMPRESS  indicates that the body of the file, all
           the data following the header has been compressed  using  the  libz
           compression library deflate algorithm. See libz(3). If this flag is
           not  present,  then the body has not been compressed and no special
           action is needed to interpret it. All offsets into the data, as de-
           scribed by the CTF header, always refer to the uncompressed data.



       The first field in the header, for all CTF versions, is always the pre-
       amble, described above. The remainder of the header can differ for each
       version. However, versions 2 and 3 both use the following common defin-
       ition. In addition to the preamble, this header  describes  whether  or
       not the CTF file is the child of another CTF file, and provides the po-
       sition  and  size of the sections that follow the header. The structure
       for the header starts with the preamble, and has an overall size of  36
       bytes.

         typedef struct ctf_header {
                 ctf_preamble_t cth_preamble;
                 uint32_t cth_parlabel;  /* ref to parent lbl uniq'd against */
                 uint32_t cth_parname;   /* ref to basename of parent */
                 uint32_t cth_lbloff;    /* offset of label section */
                 uint32_t cth_objtoff;   /* offset of object section */
                 uint32_t cth_funcoff;   /* offset of function section */
                 uint32_t cth_typeoff;   /* offset of type section */
                 uint32_t cth_stroff;    /* offset of string section */
                 uint32_t cth_strlen;    /* length of string section in bytes */
         } ctf_header_t;



       After  the preamble, the next two fields, cth_parlabel and cth_parname,
       are used to identify the parent. The value of both fields  are  offsets
       into  the  string section which point to the start of a null-terminated
       string. For more information on the encoding  of  strings,  see  String
       Identifiers.  If  the  value of either is 0, then there is no entry for
       that field. If the field cth_parlabel  is  set,  then  the  ctf_parname
       field  must  be set, otherwise it will not be possible to find the par-
       ent. If ctf_parname is set, it is not necessary to define cth_parlabel,
       as the parent may not have a label. For more information on labels  and
       their interpretation, see The Label Section.


       The  remaining  header fields, excepting cth_strlen, provide the offset
       of each section, relative to the end of the header. To convert such  an
       offset  into  an  offset  taken relative to the top of the CTF file, it
       suffices to add the size of ctf_header_t (36 bytes) to the  offset.  To
       calculate  the  size  of a given section, excepting the string section,
       subtract the offset of the section from the that of the following  one.
       For  example,  the  size  of the type section can be calculated by sub-
       tracting cth_typeoff from cth_stroff.


       The offsets reflect the alignment requirements for  each  section.  The
       cth_objtoff  and  cth_funcoff sections must be two-byte aligned for CTF
       version 2, and four-byte aligned for version 3. The sections cth_lbloff
       and cth_typeoff must be four-byte aligned for both  CTF  versions.  The
       section cth_stroff has no alignment requirements.


       Finally,  cth_strlen  provides  the length of the string section. Since
       the string section is the last section in a CTF file,  its  offset  and
       size  can  be used to determine the uncompressed size of the entire CTF
       file: sizeof (ctf_header_t) + hdr->cth_stroff + hdr->cth_strlen.

   Type Identifiers
       CTF data types are referred to using integer values known as type iden-
       tifiers. In all versions of CTF, type identifier 0 is a sentinel  value
       used  to  indicate that there is no type information available or it is
       an unknown type. The first valid type identifier is 1. When a given CTF
       file is a child, indicated by a  non-zero  entry  for  the  cth_parname
       field  of  the  header, then the most significant bit of the type ID is
       set. Macros are provided for detecting whether a given ID is for a par-
       ent or child, and for manipulating the child bit.


       Type identifiers are unsigned 16-bit  values  in  CTF  version  2,  and
       32-bit  values  in version 3. As such, their range, and the bit used to
       identify child types differ. However, the same general approach is used
       for both.

       CTF Version 2


             #define CTF_V2_TYPE_ISPARENT(_id)  ((_id) < 0x8000)
             #define CTF_V2_TYPE_ISCHILD(_id)  ((_id) > 0x7fff)
             #define CTF_V2_TYPE_TO_INDEX(_id) ((_id) & 0x7fff)
             #define CTF_V2_INDEX_TO_TYPE(_id, _ischild) \
                 ((_ischild) ? ((_id) | 0x8000) : (_id))

           CTF version 2 uses 16-bit unsigned integers to represent type  IDs,
           and  supports  up  to 32767 (0x7fff) types. In child CTF files, the
           first valid type identifier is 0x8000 and the last  is  0xffff.  In
           this  case, type identifiers 1 through 0x7fff are references to the
           parent.


       CTF Version 3


             #define CTF_V3_TYPE_ISPARENT(_id) ((uint32_t)(_id) < 0x80000000u)
             #define CTF_V3_TYPE_ISCHILD(_id)  ((uint32_t)(_id) > 0x7fffffffu)
             #define CTF_V3_TYPE_TO_INDEX(_id) ((_id) & 0x7fffffffu)
             #define CTF_V3_INDEX_TO_TYPE(_id, _ischild) \
                 (((_id) & 0x7fffffffu) | ((_ischild) != 0 ? 0x80000000u : 0))

           CTF version 3 uses 32-bit unsigned integers to represent type  IDs,
           and  supports  up  to  2147483646  (0x7ffffffe) types. In child CTF
           files, the first valid type identifier is 0x80000000 and  the  last
           is  0xfffffffe. In this case, type identifiers 1 through 0x7ffffffe
           are references to the parent. 0x7fffffff  and  0xffffffff  are  not
           treated  as valid type identifiers so as to enable the use of -1 as
           an error value.


   String Identifiers
       String identifiers are encoded as 32-bit unsigned integers which  spec-
       ify  an offset into a string table. The CTF format supports two differ-
       ent string tables which have an identifier of 0 or 1.  This  identifier
       is  stored  in the high-order bit of the offset. Therefore, the maximum
       supported offset into one of these tables is 0x7ffffffff.


       Table identifier 0 refers to the string section that is  included  with
       the  CTF  file,  which is located using the cth_stroff field of the CTF
       header. String table identifier 1 refers to the ELF string table  asso-
       ciated with the symbol table from the associated ELF object.

   Type Encoding
       Every CTF type begins with metadata encoded into an integer value. This
       value  is  a 16-bit unsigned integer in CTF version 2, and a 32-bit un-
       signed integer in CTF version 3. This encoded information provides  the
       following information:

           o      The kind of the type.


           o      Whether this type is a root type or not.


           o      The length of the variable data.


       CTF Version 2

           The  16  bits  that  make up the encoding are broken down into five
           bits for the kind (bits 11 to 15), one bit for the root  type  flag
           (bit 10), and 10 bits for the length of the variable data.

             +------+--------+------+
             | kind | isroot | vlen |
             +------+--------+------+
             15   11    10    9     0



       CTF Version 3

           The 32 bits that make up the encoding are broken down into six bits
           for  the  kind (bits 26 to 31), one bit for the root type flag (bit
           25), and 25 bits for the length of the variable data.

             +--------+--------+----------------------------+
             | kind   | isroot | vlen                       |
             +--------+--------+----------------------------+
             31     26    25    24                          0




       CTF currently defines the following 15 different kinds. The interpreta-
       tion of these different kinds is discussed in The Type  Section.  If  a
       kind  is  encountered  that is not in this list, the CTF file should be
       considered to be invalid.

         #define CTF_K_UNKNOWN   0
         #define CTF_K_INTEGER   1
         #define CTF_K_FLOAT     2
         #define CTF_K_POINTER   3
         #define CTF_K_ARRAY     4
         #define CTF_K_FUNCTION  5
         #define CTF_K_STRUCT    6
         #define CTF_K_UNION     7
         #define CTF_K_ENUM      8
         #define CTF_K_FORWARD   9
         #define CTF_K_TYPEDEF   10
         #define CTF_K_VOLATILE  11
         #define CTF_K_CONST     12
         #define CTF_K_RESTRICT  13
         #define CTF_K_SLICE     14



       Programs directly reference many types; however, other types are refer-
       enced indirectly because they are part of some other  structure.  Types
       that  are  referenced  directly  and  used are called root types. Other
       types may be used indirectly, for example, a program  may  reference  a
       structure  directly,  but not one of its members which has a type. That
       type is not considered a root type. If a type is a root type,  then  it
       will have the root flag set.


       The  meaning of the variable length (vlen) is specific to each kind and
       is discussed in The Type Section.


       The following macros are useful for constructing and deconstructing the
       encoded info word. Note that there are different macros for CTF version
       2 and version 3, each used to encode the details of the info  word  for
       that version.

         #define CTF_V2_MAX_VLEN         0x3ff /* max # variant data items */
         #define CTF_V2_INFO_KIND(_info)   (((_info) & 0xf800) >> 11)
         #define CTF_V2_INFO_ISROOT(_info) (((_info) & 0x0400) >> 10)
         #define CTF_V2_INFO_VLEN(_info)   (((_info) & CTF_V2_MAX_VLEN))
         #define CTF_V2_TYPE_INFO(_kind, _isroot, _vlen) \
                 (((_kind) << 11) | (((_isroot) ? 1 : 0) << 10) | \
                 ((_vlen) & CTF_V2_MAX_VLEN))

         #define CTF_V3_MAX_VLEN           0x00ffffff
         #define CTF_V3_INFO_KIND(info)    (((info) & 0xfc000000) >> 26)
         #define CTF_V3_INFO_ISROOT(info)  (((info) & 0x02000000) >> 25)
         #define CTF_V3_INFO_VLEN(info)    (((info) & CTF_V3_MAX_VLEN))

         #define CTF_V3_TYPE_INFO(kind, isroot, vlen) \
                 (((kind) << 26) | (((isroot) ? 1 : 0) << 25) | \
                 ((vlen) & CTF_V3_MAX_VLEN))


   The Label Section
       When consuming CTF data, it is often useful to know whether two differ-
       ent  CTF containers come from the same source base and version. For ex-
       ample, many kernel modules are built against  a  single  collection  of
       source  code.  A  label  is encoded into the CTF files that corresponds
       with the particular build. This ensures that if  files  on  the  system
       were to become mixed up from multiple releases, that they will not used
       together  by  tools, particularly when a child needs to refer to a type
       in the parent. Labels are used to prevent such a parent/child  mismatch
       from occurring.


       Each label is encoded in the file format using the following eight byte
       structure:

         typedef struct ctf_lblent {
                 uint32_t ctl_label;     /* ref to name of label */
                 uint32_t ctl_typeidx;   /* last type associated with label */
         } ctf_lblent_t;



       Each  label has two different components, a name and a type identifier.
       The name is encoded in the ctl_label field which is in the  format  de-
       fined  in  String  Identifiers.  Generally, the names of all labels are
       found in the internal string section.


       The type identifier encoded in the ctl_typeidx field refers to the last
       type identifier that a label refers to in the current file. Labels only
       refer to types in the current file, if the CTF file is a child, then it
       will have the same label as its parent; however, its  label  will  only
       refer to its types, not its parent's.


       It  is  also  possible,  though rather uncommon, for a CTF file to have
       multiple labels. Labels are  placed  one  after  another,  every  eight
       bytes.  When  multiple  labels  are present, types may only belong to a
       single label.

   The Object Section
       The object section provides a mapping from ELF symbols of type  STT_OB-
       JECT  in  the  symbol  table, to a corresponding type identifier. These
       type identifiers are 16-bit unsigned integers in  CTF  version  2,  and
       32-bit unsigned integers in CTF version 3, encoded as described in Type
       Identifiers.  If  there  is no information for an object, then the type
       identifier 0 is stored for that entry.


       To interpret the object section requires access  to  the  corresponding
       symbol table in the associated ELF object. Starting with the first sym-
       bol  in  the  symbol  table, each symbol is checked in turn to find the
       STT_OBJECT symbols that correspond to entries in  the  object  section.
       Not  every symbol found in the ELF symbol table is used. When searching
       the symbol table, a symbol is skipped if it matches any of the  follow-
       ing conditions:

           o      The type is not STT_OBJECT.


           o      The section index is SHN_UNDEF.


           o      The name offset is 0, indicating no name.


           o      The  section index is SHN_ABS and the value of the symbol is
                  0.


           o      The symbol name is _START_ or _END_.



       The entries in the object section are written  in  the  same  order  as
       their  corresponding  symbols  in  the symbol table, so each identified
       symbol corresponds to the next available object section entry. The num-
       ber of entries in the object section must correspond to the  number  of
       STT_OBJECT symbols found.

   The Function Section
       The  function section of a CTF file encodes the types of both the func-
       tion's arguments and the function's return value. This section consists
       of 16-bit unsigned integer values for CTF version 2, and of 32-bit  un-
       signed integer values for CTF version 3. Similar to The Object Section,
       the  function  section  encodes  information  for  all  symbols of type
       STT_FUNCTION, excepting those that fit specific criteria.  Unlike  with
       objects,  because  functions have a variable number of arguments, their
       entries start with a type encoding as defined in Type Encoding.


       Functions which have no type information available are encoded as  fol-
       lows. In this case, the entry is complete, and nothing else is written.
       The next integer in the section starts the next entry:

         CTF_V2_TYPE_INFO(CTF_K_UNKNOWN, 0, 0)  /* CTF version 2 */
         CTF_V3_TYPE_INFO(CTF_K_UNKNOWN, 0, 0)  /* CTF version 3 */



       Functions with type information are encoded as:

         CTF_V2_TYPE_INFO(CTF_K_FUNCTION, 0, nargs)  /* CTF version 2 */
         CTF_V3_TYPE_INFO(CTF_K_FUNCTION, 0, nargs)  /* CTF version 3 */



       The encoding variable length (vlen) is used to convey the number of ar-
       guments to the function. If a function is a varargs type function, then
       the number of arguments is increased by one.


       The  next  integer  written  provides the type identifier of the return
       type of the function, and is followed by a type identifier for each ar-
       gument, if any exist, in the order that they appear  in  the  function.
       When  a  function  has a final varargs argument, it is encoded with the
       type identifier 0.


       In the same manner as described in The Object Section, the  entries  in
       the  function section match the order of the STT_FUNCTION symbols found
       in the symbol table. The rules for matching symbol to entry  are  simi-
       lar,  but  slightly  different  than those for objects. While iterating
       over the symbol table, if any of the  following  conditions  are  true,
       then the symbol is skipped and no corresponding entry is written:

           o      The type is not STT_FUNCTION.


           o      The section index is SHN_UNDEF.


           o      The name offset is 0, indicating no name.


           o      The symbol name is _START_ or _END_.


   The Type Section
       The  type  section  is the heart of the CTF data, providing information
       for the types used in the corresponding object. Each entry consists  of
       a  type structure, potentially followed by kind-specific variable data.
       There are two forms of type structure, a shorter one used for most pur-
       poses, and a longer one used for larger sizes. The variable data,  when
       present,  follows  immediately  after the type structure. The short and
       long form of type structure are defined as follows. The CTF  version  2
       and 3 versions of these structures differ in that version 2 uses 16-bit
       integers for some fields, while version 3 widens those fields. The ver-
       sion  2  and  3  variants of each structure are shown side by side, and
       differences are shown in boldface, to facilitate comparison.

         #define CTF_V2_MAX_SIZE      0xfffe  /* max size of a type (bytes) */
         #define CTF_V2_LSIZE_SENT    0xffff  /* sentinel for ctt_size */

         #define CTF_V3_MAX_SIZE      0xfffffffe
         #define CTF_V3_LSIZE_SENT    0xffffffff


                                         |
                                         |
         typedef struct ctf_stype_v2 {   |   struct ctf_stype_v3 {
                 uint32_t ctt_name;      |           uint32_t ctt_name;
                 uint16_t ctt_info;      |           uint32_t ctt_info;
                 union {                 |           union {
                         uint16_t _size; |                   uint32_t _size;
                         uint16_t _type; |                   uint32_t _type;
                 } _u;                   |           } _u;
         } ctf_stype_v2_t;               |   } ctf_stype_v3;
                                         |
         typedef struct ctf_type_v2 {    |   typedef struct ctf_type_v3 {
                 uint32_t ctt_name;      |           uint32_t ctt_name;
                 uint16_t ctt_info;      |           uint32_t ctt_info;
                 union {                 |           union {
                         uint16_t _size; |                   uint32_t _size;
                         uint16_t _type; |                   uint32_t _type;
                 } _u;                   |           } _u;
                 uint32_t ctt_lsizehi;   |           uint32_t ctt_lsizehi;
                 uint32_t ctt_lsizelo;   |           uint32_t ctt_lsizelo;
         } ctf_type_v2_t;                |   } ctf_type_v3_t;
                                         |
                                         |


         #define ctt_size _u._size    /* for types that have a size */
         #define ctt_type _u._type    /* for types that ref. another type */



       The long form is identical to the short, with the addition of 2  fields
       at  the  end used to encode large sizes. Due to their common layout, it
       is common for code that reads types to use a pointer to the large  form
       to  access  the data, paying attention to the type kind and size to de-
       termine how to read the size, and the amount to increment  the  pointer
       between items.


       Types  are  written  out in order, with no padding in between them. The
       type ID for each type is implicit in its position within the type  sec-
       tion. The first type entry has type ID 1, the second has type ID 2, and
       so  forth.  In a child object, the type ID has its child bit set, so in
       that case, the first identifier will have value 0x8000 for CTF  version
       2, or 0x80000000 for CTF version 3.


       ctt_name is encoded as described in String Identifiers. The string that
       it  points  to  is the name of the type. If the identifier points to an
       empty string (one that consists solely of a null terminator)  then  the
       type does not have a name. This is common with anonymous structures and
       unions that only have a typedef to identify them, as well as for point-
       ers and qualifiers.


       ctt_info,  is  encoded  as  described in Type Encoding. The type's kind
       tells us how to interpret the remaining data in the type structure, and
       any variable length (vlen) data that may exist.


       Each type record has a kind. Some kinds convey size information,  while
       others  reference  another  type.  The ctt_size and ctt_type fields are
       held in a union, so only one or the other can be used. The  field  used
       is  determined  by  the kind. The kind-specific sections below describe
       the specific details.


       The following kinds use ctt_type. CTF_K_UNKNOWN and  CTF_K_FORWARD  al-
       ways  set it to 0. The other types use it to hold a referenced type ID.
       The short type structure is always used for these types.

         #define CTF_K_UNKNOWN   0
         #define CTF_K_FORWARD   9

         #define CTF_K_POINTER   3
         #define CTF_K_FUNCTION  5
         #define CTF_K_TYPEDEF   10
         #define CTF_K_VOLATILE  11
         #define CTF_K_CONST     12
         #define CTF_K_RESTRICT  13



       The following kinds convey sizes, and  use  ctt_size.  The  short  type
       structure  is used for sizes that fit within its limits, and the larger
       type structure is used otherwise.

         #define CTF_K_INTEGER   1
         #define CTF_K_FLOAT     2
         #define CTF_K_ARRAY     4
         #define CTF_K_STRUCT    6
         #define CTF_K_UNION     7
         #define CTF_K_ENUM      8
         #define CTF_K_SLICE     14



       Type sizes are measured in bytes. When the size to be represented  will
       fit  in  ctt_size, the short form of the type structure is used. If the
       size is too large to fit, then a special sentinel value is  written  to
       ctt_size  to  indicate that fact, and the large form of the type struc-
       ture is used. Although versions 2 and 3 use  different  structures  and
       macros, the same approach applies to both.

       CTF Version 2

           CTF  version 2 defines ctt_size as a uint16_t value. If the size to
           be represented is less than or equal to  CTF_V2_MAX_SIZE  (0xfffe),
           then the short type structure, ctf_stype_v2 is used. Otherwise, the
           large form, ctf_type_v2, is used, ctt_size is set to a special sen-
           tinel  value  CTF_V2_LSIZE_SENT  (0xffff),  and the size is instead
           written to ctt_lsizehi and ctt_lsizelo.

                     ctf_type_v2 ctt;

                     if (size > CTF_V2_MAX_SIZE) {             /* 0xfffe */
                             ctt.ctt_size = CTF_V2_LSIZE_SENT; /* 0xffff */
                             ctt.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
                             ctt.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
                     } else {
                             ctt.ctt_size = size;
                     }



       CTF Version 3

           CTF version 3 defines ctt_size as a uint32_t value. If the size  to
           be   represented   is   less   than  or  equal  to  CTF_V3_MAX_SIZE
           (0xfffffffe), then the short type structure, ctf_stype_v3 is  used.
           Otherwise, the large form, ctf_type_v3, is used, ctt_size is set to
           a  special  sentinel  value CTF_V3_LSIZE_SENT (0xffffffff), and the
           size is instead written to ctt_lsizehi and ctt_lsizelo.

                     ctf_type_v3 ctt;

                     if (size > CTF_V3_MAX_SIZE) {             /* 0xfffffffe */
                             ctt.ctt_size = CTF_V3_LSIZE_SENT; /* 0xffffffff */
                             ctt.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
                             ctt.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
                     } else {
                             ctt.ctt_size = size;
                     }



   Encoding of Integer Types (CTF_K_INTEGER)
       Integers, which are of type CTF_K_INTEGER, have no variable length  ar-
       guments, and should specify a vlen of 0. The type structure is followed
       by a 32-bit unsigned integer which describes the encoding. The ctt_size
       field  describes the size of the integer, in bytes. In general, integer
       sizes will be rounded up to the closest power of two.


       The integer encoding contains three different pieces of information:

           o      The encoding of the integer.


           o      The offset in bits of the type.


           o      The size in bits of the type.



       This encoding can be expressed through the following macros:

         #define CTF_INT_ENCODING(data)  (((data) & 0xff000000) >> 24)
         #define CTF_INT_OFFSET(data)    (((data) & 0x00ff0000) >> 16)
         #define CTF_INT_BITS(data)      (((data) & 0x0000ffff))

         #define CTF_INT_DATA(encoding, offset, bits) \
                 (((encoding) << 24) | ((offset) << 16) | (bits))



       The following flags are defined for the encoding:

         #define CTF_INT_SIGNED          0x01
         #define CTF_INT_CHAR            0x02
         #define CTF_INT_BOOL            0x04
         #define CTF_INT_VARARGS         0x08



       By default, an  integer  is  considered  to  be  unsigned,  unless  the
       CTF_INT_SIGNED flag set. The flag CTF_INT_CHAR indicates that the inte-
       ger  is of a type that stores character data. For example, CTF_INT_CHAR
       is set for the intrinsic C type char. CTF_INT_BOOL indicates  that  the
       integer represents a boolean type. For example, CTF_INT_BOOL is set for
       the  intrinsic C type _Bool. CTF_INT_VARARGS indicates that the integer
       is used as part of a variable number of  arguments.  This  encoding  is
       rather uncommon.


       The offset and size of a CTF_K_INTEGER can be overridden by a preceding
       CTF_K_SLICE type. See Encoding of Slice Types (CTF_K_SLICE).


       A  CTF_K_INTEGER type with both the offset and size set to 0 represents
       the C language void type. The CTF_K_SLICE type  cannot  be  applied  to
       this special case of CTF_K_INTEGER.

   Encoding of Float Types (CTF_K_FLOAT)
       Floats,  which  are  of  type CTF_K_FLOAT, are similar to their integer
       counterparts. They have no variable length arguments, specify a vlen of
       0, and the type structure is followed  by  a  32-bit  unsigned  integer
       which describes the kind of float. The ctt_size field provides the size
       of  the  float,  in  bytes. The float encoding provides three different
       pieces of information:

           o      The specific kind of float.


           o      The offset in bits of the float.


           o      The size in bits of the float.



       This encoding can be expressed through the following macros:

         #define CTF_FP_ENCODING(data)   (((data) & 0xff000000) >> 24)
         #define CTF_FP_OFFSET(data)     (((data) & 0x00ff0000) >> 16)
         #define CTF_FP_BITS(data)       (((data) & 0x0000ffff))

         #define CTF_FP_DATA(encoding, offset, bits) \
                 (((encoding) << 24) | ((offset) << 16) | (bits))



       Unlike CTF_K_INTEGER, which uses flags to describe various  attributes,
       CTF_K_FLOAT uses a simple integer to identify the floating format, each
       of which fully describes all attributes of a specific floating format.

         #define CTF_FP_SINGLE   1       /* IEEE 32-bit float */
         #define CTF_FP_DOUBLE   2       /* IEEE 64-bit float */
         #define CTF_FP_CPLX     3       /* Complex */
         #define CTF_FP_DCPLX    4       /* Double complex */
         #define CTF_FP_LDCPLX   5       /* Long double complex */
         #define CTF_FP_LDOUBLE  6       /* Long double */
         #define CTF_FP_INTRVL   7       /* Interval (2x32-bit) */
         #define CTF_FP_DINTRVL  8       /* Double interval (2x64-bit) */
         #define CTF_FP_LDINTRVL 9       /* Long double interval (2x128-bit) */
         #define CTF_FP_IMAGRY   10      /* Imaginary (32-bit) */
         #define CTF_FP_DIMAGRY  11      /* Long imaginary (64-bit) */
         #define CTF_FP_LDIMAGRY 12      /* Long double imaginary (128-bit) */


   Encoding of Array Types (CTF_K_ARRAY)
       Arrays,  which  are of type CTF_K_ARRAY, have no variable list entries,
       and therefore set vlen to 0. The type structure is followed by a struc-
       ture which describes the number of elements in the array  (cta_nelems),
       the  type  identifier  of the elements in the array (cta_contents), and
       the type identifier of the index of the array (cta_index). With arrays,
       ctt_size is set to 0.


       The CTF version 2 and 3 versions of this structure differ in that  ver-
       sion  2  uses  16-bit  integers for some fields, while version 3 widens
       those fields. The version 2 and 3 variants of each structure are  shown
       side  by side, and the differences are shown in boldface, to facilitate
       comparison.

                                        |
                                        |
         typedef struct ctf_array_v2 {  |   typedef struct ctf_array_v3 {
                 uint16_t cta_contents; |           uint32_t cta_contents;
                 uint16_t cta_index;    |           uint32_t cta_index;
                 uint32_t cta_nelems;   |           uint32_t cta_nelems;
         } ctf_array_v2_t;              |   } ctf_array_v3_t;
                                        |
                                        |



       cta_contents and cta_index are type identifiers, encoded  as  described
       in  Type  Identifiers. cta_nelems is an unsigned count of the number of
       elements. This count will be 0 when describing C99 flexible array  mem-
       bers.

   Encoding of Function Types (CTF_K_FUNCTION)
       Function  types,  which  are  of  kind CTF_K_FUNCTION, use the variable
       length (vlen) to provide the number of arguments in the function.  When
       the function has a final argument which is a varargs, then the argument
       count  is  incremented by one to account for the variable argument. The
       ctt_type field is used to hold the type identifier of the function  re-
       turn type.


       The variable data holds a list of type identifiers for the arguments of
       the  function,  if any. For CTF version 2, each argument is represented
       by a 16-bit uint16_t value, while for CTF version 3, each argument is a
       32-bit uint32_t value. Each is encoded as  described  in  Type  Identi-
       fiers.  If the function's last argument is of type varargs, it is writ-
       ten using type identifier 0.


       In CTF version 2, an extra type identifier with value 0 is  added  fol-
       lowing  the  final  argument, if needed to maintain four-byte alignment
       for the data that follows. If present, this pad value is  not  included
       in  the  argument  count.  In CTF version 3, four-byte alignment occurs
       naturally and no padding is used.

   Encoding of Structure (CTF_K_STRUCT) and Union (CTF_K_UNION) Types
       Structures  and  Unions,  which  are  encoded  with  CTF_K_STRUCT   and
       CTF_K_UNION  respectively,  are  very similar constructs in C. As such,
       their encoding in CTF is also very similar. The main difference between
       structures and unions is that members of a structure are  laid  out  in
       memory,  in  order,  one after the other, while in a union, all members
       share the same memory.


       The variable length (vlen) for structures and unions specifies the num-
       ber of members. The value of ctt_size is set to the size of the  struc-
       ture or union. As with the type structure, the structure used to encode
       members come in two forms, a smaller one one that serves most uses, and
       a  large  form used for larger sizes. The overall size of the struct or
       union determines which form is used to encode members in  the  variable
       list.  The  following definitions describe these two member structures.
       The CTF version 2 and 3 versions of these  structures  differ  in  that
       version  2 uses 16-bit integers for some fields, while version 3 widens
       those fields. The version 2 and 3 variants of each structure are  shown
       side by side, and differences are shown in boldface, to facilitate com-
       parison.

         #define CTF_V2_LSTRUCT_THRESH   (1 << 13)   /* 8192 */
         #define CTF_V3_LSTRUCT_THRESH   (1 << 29)   /* 536870912 */

         #define CTF_LMEM_OFFSET(_ctlmp) \
                 (((uint64_t)(_ctlmp)->ctlm_offsethi) << 32 | \
                 (_ctlmp)->ctlm_offsetlo)
         #define CTF_OFFSET_TO_LMEMHI(_offset)   \
                 ((uint32_t)((uint64_t)(_offset) >> 32))
         #define CTF_OFFSET_TO_LMEMLO(_offset)   ((uint32_t)(_offset))


                                         |
                                         |
         typedef struct ctf_member_v2 {  |   typedef struct ctf_member_v3 {
                 uint32_t ctm_name;      |           uint32_t ctm_name;
                 uint16_t ctm_type;      |           uint32_t ctm_type;
                 uint16_t ctm_offset;    |           uint32_t ctm_offset;
         } ctf_member_v2_t;              |   ctf_member_v3_t;
                                         |
         typedef struct ctf_lmember_v2 { |   typedef struct ctf_lmember_v3 {
                 uint32_t ctlm_name;     |           uint32_t ctlm_name;
                 uint16_t ctlm_type;     |           uint32_t ctlm_type;
                 uint16_t ctlm_pad;      |
                 uint32_t ctlm_offsethi; |           uint32_t ctlm_offsethi;
                 uint32_t ctlm_offsetlo; |           uint32_t ctlm_offsetlo;
         } ctf_lmember_v2_t;             |   ctf_lmember_v3_t;
                                         |
                                         |



       When  the  size of a structure or union is greater than or equal to the
       large   member   threshold   defined   for   the   version    of    CTF
       (CTF_V*_LSTRUCT_THRESH),  then  the  large lmember structure is used to
       encode members, rather than the smaller member structure.  All  members
       are encoded using the same structure.


       Both  ctm_name  and ctlm_name refer to the name of the member. The name
       is encoded as an offset into the string table as  described  in  String
       Identifiers.  The members ctm_type and ctlm_type both refer to the type
       of the member. They are encoded as described in Type Identifiers.


       The last piece of information that is present is the offset  which  de-
       scribes  the  offset  in memory at which the member begins. For unions,
       this value will always be 0 because each member of a union has an  off-
       set  of 0. For structures, this is the offset in bits at which the mem-
       ber begins. Note that a compiler may lay out a type with padding.  This
       means that the difference in offset between two consecutive members may
       be  larger  than  the  size of the member. When the size of the overall
       structure is strictly less than the large member threshold, the smaller
       member structure is used, and the offset in bits is stored in the  mem-
       ber  ctm_offset.  However,  when  the size of the structure exceeds the
       large member threshold, the larger member structure is  used,  and  the
       number  of  bits  is  split  into  two  32-bit  quantities. One member,
       ctlm_offsethi, represents the upper 32 bits of the  offset,  while  the
       other  member,  ctlm_offsetlo, represents the lower 32 bits of the off-
       set. These can be joined together to get a 64-bit sized offset in  bits
       using the CTF_LMEM_OFFSET macro shown above.

   Encoding of Enumeration Types (CTF_K_ENUM)
       Enumerations,  which are of kind CTF_K_ENUM, map integer values to sym-
       bolic names. The mappings are referred to as enumerators.  Enumerations
       use the variable length (vlen) to specify the number of enumerators. In
       C,  an enumeration is always equivalent to the intrinsic type int, thus
       the value of ctt_size will be the size of an int, which on Solaris sys-
       tems is always 4.


       Each enumerator is described by the following structure in the variable
       list:

         typedef struct ctf_enum {
                 uint32_t cte_name;  /* reference to name in strtab */
                 int32_t cte_value;  /* value associated with this name */
         } ctf_enum_t;



       cte_name refers to the name of the enumerator's value, and  is  encoded
       according  to  the rules described in String Identifiers. The cte_value
       field provides the integer value of this enumerator.


       Unlike CTF_K_INTEGER, CTF_K_ENUM does not specify an encoding,  as  the
       encoding  would always be that of a C int. However, the offset and size
       of a CTF_K_ENUM can be overridden by a preceding CTF_K_SLICE type.  See
       Encoding of Slice Types (CTF_K_SLICE).

   Encoding of Forward References (CTF_K_FORWARD)
       Forward  references,  which  are  of kind CTF_K_FORWARD, refer to types
       which may not have a definition at all, only a name. If the CTF file is
       a child, then it may be that the forward is resolved to an actual  type
       in  the  parent,  otherwise  the  definition may be in another CTF con-
       tainer, or may not be known at all. The only field of the  type  struc-
       ture  that  is used for a forward declaration is ctt_name, which points
       to the name of the forward reference in the string table. The  ctt_type
       field  should  be set to 0. This type has no variable list entries, and
       vlen is set to 0. There is no other information  recorded  for  forward
       references.

   Encoding of Pointers, Typedefs, Volatile, Const, and Restrict
       Pointers,  typedefs, volatile, const, and restrict all refer to another
       type. In the case of typedefs, they provide an  alternate  name,  while
       volatile, const, and restrict change how the type is interpreted in the
       C  programming  language.  This  covers  the  CTF  kinds CTF_K_POINTER,
       CTF_K_TYPEDEF, CTF_K_VOLATILE, CTF_K_RESTRICT, and  CTF_K_CONST.  These
       types have no variable list entries, and vlen is set to 0. The ctt_type
       field is used to refer to the modified base type.

   Encoding of Slice Types (CTF_K_SLICE)
       Slices, which are of kind CTF_K_SLICE, override the offset and width of
       a  referenced integer (CTF_K_INTEGER) or enumeration (CTF_K_ENUM) type.
       Slices are used to represent bitfields in  structure  or  union  types,
       when  the width of the field differs from that of the underlying refer-
       enced type.


       Slices are nameless, and have no variable list  entries,  so  ctt_name,
       and  vlen  are  set to 0. The type structure is followed by a structure
       which specifies the referenced type, and the overriding offset and size
       to be applied to that type. For slices, ctt_size is set to  the  number
       of  bytes  required to represent the size given by cts_bits, rounded up
       to the nearest power of 2.


       The CTF version 2 and 3 versions of this structure differ in that  ver-
       sion  2  uses  16-bit  integers for some fields, while version 3 widens
       those fields. The version 2 and 3 variants of each structure are  shown
       side  by side, and the differences are shown in boldface, to facilitate
       comparison.

                                       |
                                       |
         typedef struct ctf_slice_v2 { |   typedef struct ctf_slice_v3 {
                 uint16_t cts_type;    |           uint32_t cts_type;
                 uint16_t cts_offset;  |           uint16_t cts_offset;
                 uint16_t cts_bits;    |           uint16_t cts_bits;
                 uint16_t cts_pad;     |
         } ctf_slice_v2_t;             |   } ctf_slice_v3_t;
                                       |
                                       |



       cts_type refers to the type modified by the slice. The  cts_offset  and
       cts_bits  fields  provides  the  offset  and size of the modified type,
       specified in bits.

   Encoding of Unknown Types (CTF_K_UNKNOWN)
       Types with the kind CTF_K_UNKNOWN are used to indicate gaps in the type
       identifier space. Such entries consume an identifier, but do not define
       anything. Nothing should refer to these gap identifiers.  The  ctt_name
       and  ctt_type fields should be set to 0. This type has no variable list
       entries, and vlen is set to 0.

   Dependencies Between Types
       C types can be imagined as a directed, cyclic,  graph.  Structures  and
       unions  may  refer  to each other in a way that creates a cyclic depen-
       dency. In cases such as these, the entire type section must be read  in
       and  processed.  Consumers  must not assume that every type can be laid
       out in dependency order; they cannot.

   The String Section
       The string section is the final section of a  CTF  file.  This  section
       contains the strings that are referenced throughout the other sections.
       CTF string tables are modeled after ELF string table sections, and fol-
       low the same rules.


       The  string  table is an array of 8-bit character bytes. Each string is
       written to the table in turn, including a NULL termination.  The  order
       of  the  strings  within the table, relative to each other, is unspeci-
       fied, and should not be relied on. All references to the  string  table
       are  made  by  specifying  the offset of its first character. The first
       byte in the string table is always a null termination, so offset 0  al-
       ways represents an empty string.


       Generally, all characters in the string table come from the 7-bit ASCII
       character set, as most C compilers limit the characters used in identi-
       fiers  to  this  range. However, any extended characters sets should be
       written as UTF-8.

   Data Encoding and ELF Considerations
       CTF data is generally included in ELF objects. The ELF header specifies
       information that identifies the machine architecture, and  byte  order,
       for the file. A CTF container inside such an object must be written us-
       ing the same byte order as that of the ELF object.


       Other  than  byte order, CTF is a machine independent format, and there
       should be no other differences between architectures. Where this  docu-
       ment  refer  to non-fixed size C integral types, definitions that match
       those of the ILP32, and LP64 models should be assumed.


       When placing a CTF container within an ELF object,  there  are  conven-
       tions that must be followed in order for that CTF data to be usable. In
       particular,  a  given  ELF object should only contain a single CTF sec-
       tion. Multiple containers should be merged together into a single  one.
       See ctfmerge(1).


       The  CTF  file should be included in its own ELF section. The section's
       name must be .SUNW_ctf. The type of the section should be SHT_SUNW_CTF,
       although for compatibility with historical use,  SHT_PROGBITS  is  also
       allowed. The section header for the ELF section containing the CTF data
       should  link  to  the  symbol  table  (sh_link), and specify an address
       alignment of 4 (sh_addralign).


       The symbol table associated to the .SUNW_ctf  section  by  the  sh_link
       section  header field must be one of the three supported symbol tables,
       .symtab   (SHT_SYMTAB),   .dynsym   (SHT_DYNSYM),   or    .SUNW_ldynsym
       (SHT_SUNW_LDYNSYM). When the .SUNW_ldynsym is specified, the actual as-
       sociation is to the concatenation of the .SUNW_ldynsym and .dynsym sym-
       bol tables, treated as a single logical table.

HISTORY
       The  CTF  version 2 format has been used in the construction of Solaris
       since Sun Solaris 9. Version 1, the initial  development  version,  was
       never included in a user visible release.


       The  required  ELF section type for .SUNW_ctf sections was changed from
       SHT_PROGBITS to SHT_SUNW_CTF in the  Oracle  Solaris  11.4.75  release.
       Support  for  existing objects with CTF in SHT_PROGBITS sections is re-
       tained to to support historical usage.


       Support for CTF version 3, was added in the Oracle Solaris 11.4.81  re-
       lease.

SEE ALSO
       ctfconvert(1),   ctfdump(1),   ctfmerge(1),   ld(1),  mdb(1),  libz(3),
       dtrace(8)

Oracle Solaris 11.4             2 February 2026                         ctf(5)