]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
include, libctf: header and soname changes for CTFv4
authorNick Alcock <nick.alcock@oracle.com>
Thu, 24 Apr 2025 12:20:53 +0000 (13:20 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:07:41 +0000 (18:07 +0100)
These changes bump the current file format version to CTF_VERSION_4, and
introduce a new VERSION_5 identical with it to get the version integer and
the name identical again.  A great many changes are made to account for
the changes to handle CTFv4 (which is a BTF superset).

libctf will not compile after these changes, which is why it's been diked
out of the build system and forced-off until the series is complete.

Because all the CTF_K constants have changed values, this is necessarily an
ABI break: add a #define to make picking up this break at compile time
obvious.

Note that the ABI has broken by bumping the soname (deriving it now from
libctf/libtool-version) and folding all newer symbols in the symbol version
file into a new LIBCTF_2.0 version, which is now the only exported version.

include/ctf-api.h
include/ctf.h
libctf/Makefile.am
libctf/Makefile.in
libctf/libctf.ver
libctf/libtool-version [new file with mode: 0644]

index fa55a71ae2d52eaf79aeda8b8c7ca0c08f7c3ad4..afaa08c13da7c120b891bea1f95b588a7c388665 100644 (file)
@@ -34,6 +34,10 @@ extern "C"
 {
 #endif
 
+/* Version of the libctf API.  */
+
+#define LIBCTF_API_VERSION 2
+
 /* Clients can open one or more CTF containers and obtain a pointer to an
    opaque ctf_dict_t.  Types are identified by an opaque ctf_id_t token.
    They can also open or create read-only archives of CTF containers in a
index c066a28849a0499e9421a2dd44cdfe3afae5bcbd..cbbd0ea71af222706e56fbf15eeda6a9c9569e44 100644 (file)
@@ -50,28 +50,30 @@ extern "C"
    typically named .ctf.  Data structures are aligned so that a raw CTF file or
    CTF ELF section may be manipulated using mmap(2).
 
-   The CTF file or section itself has the following structure:
+   The CTF file or section is a superset of BTF, and has the following structure:
 
    +--------+--------+---------+----------+--------+----------+...
-   |  file  |  type  |  data   | function | object | function |...
-   | header | labels | objects |   info   | index  |  index   |...
-   +--------+--------+---------+----------+--------+----------+...
+   +   BTF  |   CTF  |  data   | function | object | function |...
+   | header | header | objects |   info   | index  |  index   |...
+   +--------+--------+----------+--------+-------------------+...
 
-   ...+----------+-------+--------+
-   ...| variable | data  | string |
-   ...|   info   | types | table  |
-      +----------+-------+--------+
+   ...+-------+--------+
+   ...| data  | string |
+   ...| types | table  |
+      +-------+--------+
 
    The file header stores a magic number and version information, encoding
-   flags, and the byte offset of each of the sections relative to the end of the
-   header itself.  If the CTF data has been uniquified against another set of
-   CTF data, a reference to that data also appears in the the header.  This
-   reference is the name of the label corresponding to the types uniquified
-   against.
-
-   Following the header is a list of labels, used to group the types included in
-   the data types section.  Each label is accompanied by a type ID i.  A given
-   label refers to the group of types whose IDs are in the range [0, i].
+   flags, and the byte offset and length of each of the sections relative to
+   the end of the header itself.  There are two headers: the BTF header contains
+   offsets relative to the end of the BTF header, and immediately following it
+   there may be a CTF header containing offsets relative to the end of the CTF
+   header.  If the BTF header is not followed by a CTFv4_MAGIC, no CTF header
+   is present and this dict is pure BTF (and cannot contain CTF-specific type
+   kinds).
+
+   If the CTF data has been uniquified against another set of CTF data, a
+   reference to that data also appears in the the header.  This reference is the
+   name of the parent dict containing the types uniquified against.
 
    Data object and function records (collectively, "symtypetabs") are stored in
    the same order as they appear in the corresponding symbol table, except that
@@ -126,10 +128,14 @@ extern "C"
 #define CTF_MAX_TYPE   0xfffffffe      /* Max type identifier value.  */
 #define CTF_MAX_PTYPE  0x7fffffff      /* Max parent type identifier value.  */
 #define CTF_MAX_NAME 0x7fffffff                /* Max offset into a string table.  */
-#define CTF_MAX_VLEN   0xffffff /* Max struct, union, enum members or args.  */
-
-/* See ctf_type_t */
-#define CTF_MAX_SIZE   0xfffffffe      /* Max size of a v2 type in bytes. */
+#define CTF_MAX_VLEN_V2        0xffffff /* Max struct, union, enum members or args.  */
+#define CTF_MAX_VLEN   0xffffffff /* Max struct, union, enum members or args:
+                                     may need CTFv4-only CTF_K_BIG.  */
+#define CTF_MAX_RAW_VLEN 0xffff /* Max BTF struct, union, enum members or args.  */
+
+/* See ctf_v3_type_t.  */
+#define CTF_MAX_SIZE   0xfffffffe      /* Max size of a v2+/BTF type in bytes. */
+#define CTF_MAX_RAW_SIZE 0xfffffffffffffffeULL /* Max size ofr a CTF_K_BIG type.  */
 #define CTF_LSIZE_SENT 0xffffffff      /* Sentinel for v2 ctt_size.  */
 
 # define CTF_MAX_TYPE_V1       0xffff  /* Max type identifier value.  */
@@ -143,19 +149,20 @@ extern "C"
    Every field in these structures must have corresponding code in the
    endianness-swapping machinery in libctf/ctf-open.c.  */
 
-/* UPTODO: v4/BTF preamble in different order! at least the magic number is in the
-   same place.  */
+/* Warning: not aligned with the BTF preamble, though most of the fields are
+   usually overlapping.  */
 
-typedef struct ctf_preamble
+typedef struct ctf_preamble_v3
 {
   unsigned short ctp_magic;    /* Magic number (CTF_MAGIC).  */
   unsigned char ctp_version;   /* Data format version number (CTF_VERSION).  */
   unsigned char ctp_flags;     /* Flags (see below).  */
-} ctf_preamble_t;
+} ctf_preamble_v3_t;
 
+/* Header for CTFv1 and v2.  */
 typedef struct ctf_header_v2
 {
-  ctf_preamble_t cth_preamble;
+  ctf_preamble_v3_t cth_preamble;
   uint32_t cth_parlabel;       /* Ref to name of parent lbl uniq'd against.  */
   uint32_t cth_parname;                /* Ref to basename of parent.  */
   uint32_t cth_lbloff;         /* Offset of label section.  */
@@ -167,9 +174,10 @@ typedef struct ctf_header_v2
   uint32_t cth_strlen;         /* Length of string section in bytes.  */
 } ctf_header_v2_t;
 
+/* Header for CTFv3 only.  */
 typedef struct ctf_header_v3
 {
-  ctf_preamble_t cth_preamble;
+  ctf_preamble_v3_t cth_preamble;
   uint32_t cth_parlabel;       /* Ref to name of parent lbl uniq'd against.  */
   uint32_t cth_parname;                /* Ref to basename of parent.  */
   uint32_t cth_cuname;         /* Ref to CU name (may be 0).  */
@@ -184,53 +192,91 @@ typedef struct ctf_header_v3
   uint32_t cth_strlen;         /* Length of string section in bytes.  */
 } ctf_header_v3_t;
 
+/* Derived from btf.h in the Linux kernel, but independent (to ensure that btf.h
+   changes do not change the CTF file format) and using userspace types.  */
+
+typedef struct ctf_btf_preamble
+{
+  uint16_t btf_magic;          /* BTF_MAGIC */
+  uint8_t btf_version;         /* Always 1, for now */
+  uint8_t btf_flags;           /* Always 0, for now */
+} ctf_btf_preamble_t;
+
+typedef struct ctf_btf_header
+{
+  ctf_btf_preamble_t bth_preamble;
+  uint32_t bth_hdr_len;                /* De-facto BTF version number */
+  uint32_t bth_type_off;       /* Offset of type section.  */
+  uint32_t bth_type_len;       /* Length of type section.  */
+  uint32_t bth_str_off;                /* Offset of string section.  */
+  uint32_t bth_str_len;                /* Length of string section.  */
+} ctf_btf_header_t;
+
+typedef struct ctf_preamble
+{
+  uint64_t ctp_magic_version;  /* Magic number (CTFv4_MAGIC) and version.  */
+  uint64_t ctp_flags;          /* Flags (see below).  */
+} ctf_preamble_t;
+
+/* Offsets in this header are relative to the end of the ctf_btf_header.  */
+
 typedef struct ctf_header
 {
+  ctf_btf_header_t btf;                /* Leading component is BTF. */
   ctf_preamble_t cth_preamble;
-  uint32_t cth_parlabel;       /* Ref to name of parent lbl uniq'd against.  */
-  uint32_t cth_parname;                /* Ref to basename of parent.  */
-  uint32_t cth_cuname;         /* Ref to CU name (may be 0).  */
+  uint32_t cth_cu_name;                /* Ref to CU name (may be 0).  */
+  uint32_t cth_parent_name;    /* Ref to basename of parent.  */
   uint32_t cth_parent_strlen;  /* cth_strlen of parent (may be 0).  */
-  uint32_t cth_parent_typemax; /* Number of types in parent (may be 0).  */
-  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_objtidxoff;     /* Offset of object index section.  */
-  uint32_t cth_funcidxoff;     /* Offset of function index section.  */
-  uint32_t cth_varoff;         /* Offset of variable 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.  */
+  uint32_t cth_parent_ntypes;  /* Number of types in parent (may be 0).  */
+  uint32_t cth_objt_off;       /* Offset of object section.  */
+  uint32_t cth_objt_len;       /* Length of object section.  */
+  uint32_t cth_func_off;       /* Offset of function section.  */
+  uint32_t cth_func_len;       /* Length of function section.  */
+  uint32_t cth_objtidx_off;    /* Offset of object index section.  */
+  uint32_t cth_objtidx_len;    /* Length of object index section.  */
+  uint32_t cth_funcidx_off;    /* Offset of function index section.  */
+  uint32_t cth_funcidx_len;    /* Length of function index section.  */
 } ctf_header_t;
 
-#define cth_magic   cth_preamble.ctp_magic
-#define cth_version cth_preamble.ctp_version
+/* The ctp_magic_version field is a magic number (high 48 bits) and a version
+   (low 16).  Of course this may be in the wrong endianness for the running
+   system. */
+#define CTH_MAGIC(hdr)   ((hdr->cth_preamble.ctp_magic_version) >> 16)
+#define CTH_VERSION(hdr) ((hdr->cth_preamble.ctp_magic_version) & (((uint64_t) ~0) >> 48))
 #define cth_flags   cth_preamble.ctp_flags
 
-#define CTF_MAGIC      0xdff2  /* Magic number identifying header.  */
+#define CTF_MAGIC      0xdff2  /* v3 and below: magic number identifying header.  */
+#define CTF_BTF_MAGIC  0xeb9f
+#define CTFv4_MAGIC    0xd167ae03a2c5          /* 48 bits */
 
 /* Data format version number.  */
 
-/* v1 upgraded to a later version is not quite the same as the native form,
-   because the boundary between parent and child types is different but not
-   recorded anywhere, and you can write it out again via ctf_compress_write(),
-   so we must track whether the thing was originally v1 or not.  If we were
-   writing the header from scratch, we would add a *pair* of version number
-   fields to allow for this, but this will do for now.  (A flag will not do,
-   because we need to encode both the version we came from and the version we
-   went to, not just "we were upgraded".)
+/* v1 upgraded to v2/v3 is not quite the same as the native form, because the
+   boundary between parent and child types is different but not recorded
+   anywhere, and you can write it out again via ctf_compress_write(), so we must
+   track whether the thing was originally v1 or not.  If we were writing the
+   header from scratch, we would add a *pair* of version number fields to allow
+   for this, but this will do for now.  (A flag will not do, because we need to
+   encode both the version we came from and the version we went to, not just "we
+   were upgraded".)
+
+   When upgrading to v4, we can simply record the boundary in
+   cth_parent_ntypes.
 
-   The same problem applies to v2 and v3 upgraded to v4, but here we can apply
-   some common sense and simply record the boundary in a new header field.  */
+   Version 5 is the same as version 4: it only exists to realign the version
+   numbers and the actual underlying integers.  */
 
 #define CTF_VERSION_1 1
 #define CTF_VERSION_1_UPGRADED_3 2
 #define CTF_VERSION_2 3
 #define CTF_VERSION_3 4
 
-#define CTF_VERSION_4 5
-#define CTF_VERSION CTF_VERSION_4 /* Current version.  */
-#define CTF_STABLE_VERSION 4
+#define CTF_VERSION_4 5                /* The same as 5.  */
+#define CTF_VERSION_5 5
+#define CTF_VERSION CTF_VERSION_5 /* Current version.  */
+#define CTF_STABLE_VERSION 5
+
+#define CTF_BTF_VERSION 1
 
 /* All of these flags bar CTF_F_COMPRESS and CTF_F_IDXSORTED are bug-workaround
    flags and are valid only in format v3: in v2 and below they cannot occur and
@@ -240,27 +286,26 @@ typedef struct ctf_header
 #define CTF_F_NEWFUNCINFO 0x2          /* New v3 func info section format.  */
 #define CTF_F_IDXSORTED 0x4            /* Index sections already sorted.  */
 #define CTF_F_DYNSTR 0x8               /* Strings come from .dynstr.  */
-#define CTF_F_MAX (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO | CTF_F_IDXSORTED        \
-                  | CTF_F_DYNSTR)
+#define CTF_F_MAX_3 (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO | CTF_F_IDXSORTED      \
+                    | CTF_F_DYNSTR)
 
-typedef struct ctf_lblent
-{
-  uint32_t ctl_label;          /* Ref to name of label.  */
-  uint32_t ctl_type;           /* Last type associated with this label.  */
-} ctf_lblent_t;
+#define CTF_F_MAX (CTF_F_COMPRESS | CTF_F_IDXSORTED)
 
-typedef struct ctf_varent
+  /* CTFv3 and below: variable entries.  */
+typedef struct ctf_varent_v3
 {
   uint32_t ctv_name;           /* Reference to name in string table.  */
   uint32_t ctv_type;           /* Index of type of this variable.  */
-} ctf_varent_t;
+} ctf_varent_v3_t;
+
+/* In format v2 and v3, type sizes, measured in bytes, come in two flavours.
+   Nearly all of them fit into a (UINT_MAX - 1), and thus can be stored in the
+   ctt_size member of a ctf_stype_v2_t.  The maximum value for these sizes is
+   CTF_MAX_SIZE.  Types larger than this must be stored in the ctf_lsize member
+   of a ctf_type_t.  Use of this member is indicated by the presence of
+   CTF_LSIZE_SENT in ctt_size.
 
-/* In format v2, type sizes, measured in bytes, come in two flavours.  Nearly
-   all of them fit into a (UINT_MAX - 1), and thus can be stored in the ctt_size
-   member of a ctf_stype_t.  The maximum value for these sizes is CTF_MAX_SIZE.
-   Types larger than this must be stored in the ctf_lsize member of a
-   ctf_type_t.  Use of this member is indicated by the presence of
-   CTF_LSIZE_SENT in ctt_size.  */
+   In CTFv4, the CTF_K_BIG prefixed kind is used for the same purpose.  */
 
 /* In v1, the same applies, only the limit is (USHRT_MAX - 1) and
    CTF_MAX_SIZE_V1, and CTF_LSIZE_SENT_V1 is the sentinel.  */
@@ -308,7 +353,7 @@ typedef struct ctf_type_v1
 } ctf_type_v1_t;
 
 
-typedef struct ctf_stype
+typedef struct ctf_v2_stype
 {
   uint32_t ctt_name;           /* Reference to name in string table.  */
   uint32_t ctt_info;           /* Encoded kind, variant length (see below).  */
@@ -326,9 +371,9 @@ typedef struct ctf_stype
     uint32_t ctt_type;         /* Reference to another type.  */
   };
 #endif
-} ctf_stype_t;
+} ctf_stype_v2_t;
 
-typedef struct ctf_type
+typedef struct ctf_type_v2
 {
   uint32_t ctt_name;           /* Reference to name in string table.  */
   uint32_t ctt_info;           /* Encoded kind, variant length (see below).  */
@@ -348,6 +393,27 @@ union
 #endif
   uint32_t ctt_lsizehi;                /* High 32 bits of type size in bytes.  */
   uint32_t ctt_lsizelo;                /* Low 32 bits of type size in bytes.  */
+} ctf_type_v2_t;
+
+/* Identical to btf_type.  */
+typedef struct ctf_type
+{
+  uint32_t ctt_name;           /* Reference to name in string table.  */
+  uint32_t ctt_info;           /* Encoded kind, variant length (see below).  */
+#ifndef __GNUC__
+union
+  {
+    uint32_t _size;            /* Always CTF_LSIZE_SENT.  */
+    uint32_t _type;            /* Do not use.  */
+  } _u;
+#else
+  __extension__
+  union
+  {
+    uint32_t ctt_size;         /* Always CTF_LSIZE_SENT.  */
+    uint32_t ctt_type;         /* Do not use.  */
+  };
+#endif
 } ctf_type_t;
 
 #ifndef __GNUC__
@@ -368,12 +434,24 @@ union
                ------------------------
                15   11    10    9     0
 
-   v2:
+   v2 and v3:
                ------------------------
    ctt_info:   | kind | isroot | vlen |
                ------------------------
                31    26    25  24     0
 
+   v4 and BTF:
+
+   * bits  0-15: vlen (e.g. # of struct's members)
+   * bits 16-23: unused
+   * bits 24-28: kind (e.g. int, ptr, array...etc)
+   * bits 29-30: unused
+   * bit     31: kind_flag, currently used by
+   *             struct, union, enum, fwd and enum64
+
+   Types requiring larger bits use prefix kinds, CTF_K_PREFIX
+   below.
+
    CTF_V1 and V2 _INFO_VLEN have the same interface:
 
    kind = CTF_*_INFO_KIND(c.ctt_info);     <-- CTF_K_* value (see below)
@@ -391,15 +469,19 @@ union
 
 #define CTF_V2_INFO_KIND(info)         (((info) & 0xfc000000) >> 26)
 #define CTF_V2_INFO_ISROOT(info)       (((info) & 0x2000000) >> 25)
-#define CTF_V2_INFO_VLEN(info)         (((info) & CTF_MAX_VLEN))
+#define CTF_V2_INFO_VLEN(info)         (((info) & CTF_MAX_VLEN_V2))
+
+#define CTF_INFO_KFLAG(info)           (((info) & 0x80000000) >> 31)
+#define CTF_INFO_KIND(info)            (((info) >> 24) & 0x1f)
+#define CTF_INFO_VLEN(info)            (((info) & CTF_MAX_RAW_VLEN))
 
 #define CTF_NAME_STID(name)            ((name) >> 31)
 #define CTF_NAME_OFFSET(name)          ((name) & CTF_MAX_NAME)
 #define CTF_SET_STID(name, stid)       ((name) | ((unsigned int) stid) << 31)
 
-/* V2 only. */
-#define CTF_TYPE_INFO(kind, isroot, vlen) \
-       (((kind) << 26) | (((isroot) ? 1 : 0) << 25) | ((vlen) & CTF_MAX_VLEN))
+/* V4 only. */
+#define CTF_TYPE_INFO(kind, kflag, vlen) \
+       (((kind) << 24) | (((kflag) ? 1 : 0) << 31) | ((vlen) & CTF_MAX_RAW_VLEN))
 
 #define CTF_TYPE_NAME(stid, offset) \
        (((stid) << 31) | ((offset) & CTF_MAX_NAME))
@@ -419,43 +501,105 @@ union
 #define CTF_V1_TYPE_TO_INDEX(id)       ((id) & CTF_MAX_PTYPE_V1)
 #define CTF_V1_INDEX_TO_TYPE(id, child) ((child) ? ((id) | (CTF_MAX_PTYPE_V1+1)) : (id))
 
-/* Valid for both V1 and V2. */
-#define CTF_TYPE_LSIZE(cttp) \
+/* Valid for V1 -- V3, but not V4. */
+#define CTF_V3_TYPE_LSIZE(cttp) \
        (((uint64_t)(cttp)->ctt_lsizehi) << 32 | (cttp)->ctt_lsizelo)
+
+/* Valid for v4 as well: splits sizes into prefix-type and non-prefix-type
+   portions.  */
 #define CTF_SIZE_TO_LSIZE_HI(size)     ((uint32_t)((uint64_t)(size) >> 32))
 #define CTF_SIZE_TO_LSIZE_LO(size)     ((uint32_t)(size))
 
+#define CTF_VLEN_TO_VLEN_HI(vlen)      ((uint16_t)((uint32_t)(vlen) >> 16))
+#define CTF_VLEN_TO_VLEN_LO(vlen)      ((uint16_t)(vlen))
+
+/* CTF_STRTAB_1 not valid in BTF, since strtab offsets high enough to be in
+   strtab 1 have no meaning there.  */
 #define CTF_STRTAB_0   0       /* String table id 0 (in-CTF).  */
 #define CTF_STRTAB_1   1       /* String table id 1 (ELF strtab).  */
 
 /* Values for CTF_TYPE_KIND().  If the kind has an associated data list,
    CTF_INFO_VLEN() will extract the number of elements in the list, and
-   the type of each element is shown in the comments below. */
+   the type of each element is shown in the comments below.  */
 
-#define CTF_K_UNKNOWN  0       /* Unknown type (used for padding and
+#define CTF_V3_K_UNKNOWN 0     /* Unknown type (used for padding and
                                   unrepresentable types).  */
-#define CTF_K_INTEGER  1       /* Variant data is CTF_INT_DATA (see below).  */
-#define CTF_K_FLOAT    2       /* Variant data is CTF_FP_DATA (see below).  */
-#define CTF_K_POINTER  3       /* ctt_type is referenced type.  */
-#define CTF_K_ARRAY    4       /* Variant data is single ctf_array_t.  */
-#define CTF_K_FUNCTION 5       /* ctt_type is return type, variant data is
+#define CTF_V3_K_INTEGER 1     /* Variant data is CTF_INT_DATA (see below).  */
+#define CTF_V3_K_FLOAT   2     /* Variant data is CTF_FP_DATA (see below).  */
+#define CTF_V3_K_POINTER 3     /* ctt_type is referenced type.  */
+#define CTF_V3_K_ARRAY   4     /* Variant data is single ctf_array_t.  */
+#define CTF_V3_K_FUNCTION 5    /* ctt_type is return type, variant data is
                                   list of argument types (unsigned short's for v1,
                                   uint32_t's for v2).  */
-#define CTF_K_STRUCT   6       /* Variant data is list of ctf_member_t's.  */
-#define CTF_K_UNION    7       /* Variant data is list of ctf_member_t's.  */
-#define CTF_K_ENUM     8       /* Variant data is list of ctf_enum_t's.  */
-#define CTF_K_FORWARD  9       /* No additional data; ctt_name is tag.  */
-#define CTF_K_TYPEDEF  10      /* ctt_type is referenced type.  */
-#define CTF_K_VOLATILE 11      /* ctt_type is base type.  */
-#define CTF_K_CONST    12      /* ctt_type is base type.  */
-#define CTF_K_RESTRICT 13      /* ctt_type is base type.  */
-#define CTF_K_SLICE    14      /* Variant data is a ctf_slice_t.  */
-
-#define CTF_K_MAX      63      /* Maximum possible (V2) CTF_K_* value.  */
+#define CTF_V3_K_STRUCT  6     /* Variant data is list of ctf_member_t's.  */
+#define CTF_V3_K_UNION   7     /* Variant data is list of ctf_member_t's.  */
+#define CTF_V3_K_ENUM    8     /* Variant data is list of ctf_enum_t's.  */
+#define CTF_V3_K_FORWARD 9     /* No additional data; ctt_name is tag.  */
+#define CTF_V3_K_TYPEDEF 10    /* ctt_type is referenced type.  */
+#define CTF_V3_K_VOLATILE 11   /* ctt_type is base type.  */
+#define CTF_V3_K_CONST   12    /* ctt_type is base type.  */
+#define CTF_V3_K_RESTRICT 13   /* ctt_type is base type.  */
+#define CTF_V3_K_SLICE   14    /* Variant data is a ctf_slice_t.  */
+
+#define CTF_V3_K_MAX   14      /* Maximum possible (V3) CTF_K_* value.  */
+
+/* Values for CTF_TYPE_KIND() for BTF, shared by CTFv4.  Kind names as unchanged
+   as possible, since they are user-exposed, but their values all differ.  */
+
+#define CTF_K_UNKNOWN  0       /* Unknown type (used for padding and
+                                  unrepresentable and suppressed types).  */
+#define CTF_K_INTEGER  1       /* Variant data is CTF_INT_DATA (see below).  */
+#define CTF_K_POINTER  2       /* ctt_type is referenced type.  */
+#define CTF_K_ARRAY    3       /* Variant data is single ctf_array_t.  */
+#define CTF_K_STRUCT   4       /* Variant data is list of ctf_member_t's;
+                                  kind_flag 1 if bitfields present.  */
+#define CTF_K_UNION    5       /* Ditto.  */
+#define CTF_K_ENUM     6       /* Variant data is list of ctf_enum_t's: if 0,
+                                  this is a forward.  kflag 1 is signed.  */
+#define CTF_K_FORWARD  7       /* No additional data; kind_flag 1 for unions.  */
+#define CTF_K_TYPEDEF  8       /* ctt_type is referenced type.  */
+#define CTF_K_VOLATILE 9       /* ctt_type is base type.  */
+#define CTF_K_CONST    10      /* ctt_type is base type.  */
+#define CTF_K_RESTRICT 11      /* ctt_type is base type.  */
+#define CTF_K_FUNC_LINKAGE 12  /* Literal vlen field is ctf_linkage_t.ctl.linkage;
+                                  ctt_type is CTF_K_FUNCTION.  Named.  */
+#define CTF_K_FUNCTION 13      /* ctt_type is return type, variant data is
+                                  list of ctf_param_t.  Unnamed.  */
+#define CTF_K_VAR      14      /* Variable.  ctt_type is variable type.
+                                  Variant data is ctf_linkage_t.  */
+#define CTF_K_DATASEC  15      /* Variant data is list of ctf_var_secinfo_t.  */
+#define CTF_K_BTF_FLOAT 16     /* No data beyond a size.  */
+#define CTF_K_DECL_TAG 17      /* ctt_type is referenced type.  Variant data is
+                                  ctf_decl_tag_t.  */
+#define CTF_K_TYPE_TAG 18      /* ctt_type is referenced type.  */
+#define CTF_K_ENUM64  19       /* Variant data is list of ctf_enum64_t.  kflag
+                                  1 is signed.  */
+
+/* Values for CTF_TYPE_KIND() for CTFv4.  Count down from the top of the ID
+   space, */
+
+#define CTF_K_FLOAT   31       /* Variant data is a CTF_FP_* value.  */
+#define CTF_K_SLICE   30       /* Variant data is a ctf_slice_t.  */
+#define CTF_K_BIG     29       /* Prefix type.
+                                  vlen is high 16 bits of type vlen;
+                                  size is high 32 bits of type size.  */
+#define CTF_K_CONFLICTING 28   /* Prefix type.  Name is disambiguator for
+                                  conflicting type (e.g. translation unit
+                                  name).
+
+                                  If a type is both CONFLICTING and BIG,
+                                  CONFLICTING will always prefix BIG.  */
+#define CTF_BTF_K_MAX  19      /* Maximum possible (V4) BTF_K_* value.  */
+#define CTF_K_MAX      31      /* Maximum possible (V4) CTF_K_* value.  */
+
+
+#define CTF_PREFIX_KIND(kind) ((kind) == CTF_K_BIG || (kind) == CTF_K_CONFLICTING)
 
 /* Values for ctt_type when kind is CTF_K_INTEGER.  The flags, offset in bits,
    and size in bits are encoded as a single word using the following macros.
-   (However, you can also encode the offset and bitness in a slice.)  */
+   (However, you can also encode the offset and bitness in a slice, or directly
+   in a struct: many clients, e.g. libbpf, do not allow nonzero bit offsets
+   or bits values in base types at all.)  */
 
 #define CTF_INT_ENCODING(data) (((data) & 0xff000000) >> 24)
 #define CTF_INT_OFFSET(data)   (((data) & 0x00ff0000) >> 16)
@@ -467,7 +611,6 @@ union
 #define CTF_INT_SIGNED 0x01    /* Integer is signed (otherwise unsigned).  */
 #define CTF_INT_CHAR   0x02    /* Character display format.  */
 #define CTF_INT_BOOL   0x04    /* Boolean display format.  */
-#define CTF_INT_VARARGS        0x08    /* Varargs display format.  */
 
 /* Use CTF_CHAR to produce a char that agrees with the system's native
    char signedness.  */
@@ -477,9 +620,10 @@ union
 # define CTF_CHAR (CTF_INT_CHAR | CTF_INT_SIGNED)
 #endif
 
-/* Values for ctt_type when kind is CTF_K_FLOAT.  The encoding, offset in bits,
-   and size in bits are encoded as a single word using the following macros.
-   (However, you can also encode the offset and bitness in a slice.)  */
+/* Values for ctt_type when kind is CTF_K_FLOAT in CTFv3 and below.  The
+   encoding, offset in bits, and size in bits are encoded as a single word using
+   the following macros.  (However, you can also encode the offset and bitness
+   in a slice.)  */
 
 #define CTF_FP_ENCODING(data)  (((data) & 0xff000000) >> 24)
 #define CTF_FP_OFFSET(data)    (((data) & 0x00ff0000) >> 16)
@@ -488,15 +632,23 @@ union
 #define CTF_FP_DATA(encoding, offset, bits) \
        (((encoding) << 24) | ((offset) << 16) | (bits))
 
-/* Variant data when kind is CTF_K_FLOAT is an encoding in the top eight bits.  */
-#define CTF_FP_ENCODING(data)  (((data) & 0xff000000) >> 24)
+/* Variant data when kind is CTF_K_FLOAT is an encoding in the top eight bits.
+   In v4, it's a straight encoding of the CTF_FP_* type.  Dicts translated from
+   v3 lose their offset and bits flags (which were meaningless anyway). */
+#define CTF_V3_FP_ENCODING(data)       (((data) & 0xff000000) >> 24)
 
+#define CTF_FP_UNKNOWN  0      /* Unknown encoding.  */
 #define CTF_FP_SINGLE  1       /* IEEE 32-bit float encoding.  */
 #define CTF_FP_DOUBLE  2       /* IEEE 64-bit float encoding.  */
 #define CTF_FP_CPLX    3       /* Complex encoding.  */
 #define CTF_FP_DCPLX   4       /* Double complex encoding.  */
 #define CTF_FP_LDCPLX  5       /* Long double complex encoding.  */
 #define CTF_FP_LDOUBLE 6       /* Long double encoding.  */
+
+#define CTF_FP_MAX     6       /* Maximum possible CTF_FP_* value.  */
+
+/* CTFv3 and below only.  Never generated by GCC.  */
+
 #define CTF_FP_INTRVL  7       /* Interval (2x32-bit) encoding.  */
 #define CTF_FP_DINTRVL 8       /* Double interval (2x64-bit) encoding.  */
 #define CTF_FP_LDINTRVL        9       /* Long double interval (2x128-bit) encoding.  */
@@ -504,17 +656,16 @@ union
 #define CTF_FP_DIMAGRY 11      /* Long imaginary (64-bit) encoding.  */
 #define CTF_FP_LDIMAGRY        12      /* Long double imaginary (128-bit) encoding.  */
 
-#define CTF_FP_MAX     12      /* Maximum possible CTF_FP_* value */
+#define CTF_V3_FP_MAX  12      /* Maximum possible CTF_FP_* value in v3 and
+                                  below.  */
 
 /* A slice increases the offset and reduces the bitness of the referenced
-   ctt_type, which must be a type which has an encoding (fp, int, or enum).  We
+   ctt_type, which must be a type which has an encoding (int or enum).  We
    also store the referenced type in here, because it is easier to keep the
    ctt_size correct for the slice than to shuffle the size into here and keep
    the ctt_type where it is for other types.
 
-   In a future version, where we loosen requirements on alignment in the CTF
-   file, the cts_offset and cts_bits will be chars: but for now they must be
-   shorts or everything after a slice will become unaligned.  */
+   CTFv4 only, not BTF.  */
 
 typedef struct ctf_slice
 {
@@ -537,7 +688,9 @@ typedef struct ctf_array
   uint32_t cta_nelems;         /* Number of elements.  */
 } ctf_array_t;
 
-/* Most structure members have bit offsets that can be expressed using a short.
+/* (CTF < v4.)
+
+   Most structure members have bit offsets that can be expressed using a short.
    Some don't.  ctf_member_t is used for structs which cannot contain any of
    these large offsets, whereas ctf_lmember_t is used in the latter case.  If
    any member of a given struct has an offset that cannot be expressed using a
@@ -573,7 +726,7 @@ typedef struct ctf_member_v2
   uint32_t ctm_name;           /* Reference to name in string table.  */
   uint32_t ctm_offset;         /* Offset of this member in bits.  */
   uint32_t ctm_type;           /* Reference to type of member.  */
-} ctf_member_t;
+} ctf_member_v2_t;
 
 typedef struct ctf_lmember_v2
 {
@@ -581,19 +734,95 @@ typedef struct ctf_lmember_v2
   uint32_t ctlm_offsethi;      /* High 32 bits of member offset in bits.  */
   uint32_t ctlm_type;          /* Reference to type of member.  */
   uint32_t ctlm_offsetlo;      /* Low 32 bits of member offset in bits.  */
-} ctf_lmember_t;
+} ctf_lmember_v2_t;
 
-#define        CTF_LMEM_OFFSET(ctlmp) \
+#define        CTF_V3_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))
+#define        CTF_V3_OFFSET_TO_LMEMHI(offset) ((uint32_t)((uint64_t)(offset) >> 32))
+#define        CTF_V3_OFFSET_TO_LMEMLO(offset) ((uint32_t)(offset))
+
+/* Aligned with btf_member.  */
+typedef struct ctf_member
+{
+  uint32_t ctm_name;           /* Reference to name in string table.  */
+  uint32_t ctm_type;           /* Reference to type of member.  */
+  uint32_t ctm_offset;         /* Offset of this member in bits; possibly bit
+                                  offset.  In CTF_KIND_BIG, offset from the
+                                  *previous* member.  */
+} ctf_member_t;
+
+/* Used when the CTF_KIND_{STRUCT,UNION} kind_flag is on, indicating
+   bitfields.  Bit offset and size override offsets from the underlying
+   encoding, including slices.  */
+
+#define CTF_MAX_BIT_OFFSET 0xffffff
+#define CTF_MEMBER_BIT_SIZE(val) ((val) >> 24)
+#define CTF_MEMBER_BIT_OFFSET(val) ((val) & CTF_MAX_BIT_OFFSET)
+#define CTF_MEMBER_MAKE_BIT_OFFSET(size, offset) ((size) << 24 | offset)
+
+/* Data sections, aligned with btf_var_secinfo.
+
+   TODO: Do we want a CTFv4 extended variant with 64-bit size for
+   CTF_KIND_BIG?  */
+typedef struct ctf_var_secinfo
+{
+  uint32_t cvs_type;
+  uint32_t cvs_offset;
+  uint32_t cvs_size;           /* If 0, use type size.  */
+} ctf_var_secinfo_t;
+
+/* Linkages, aligned with enum btf_func_linkage.  */
+#define CTF_VAR_STATIC 0
+#define CTF_VAR_GLOBAL_ALLOCATED 1
+#define CTF_VAR_GLOBAL_EXTERN 2
+
+#define CTF_FUNC_STATIC 0
+#define CTF_FUNC_GLOBAL 1
+#define CTF_FUNC_EXTERN 2
+
+/* Kind-independent linkage constants.  Values must match those above.  */
+#define CTF_LINKAGE_STATIC 0
+#define CTF_LINKAGE_GLOBAL 1
+#define CTF_LINKAGE_EXTERN 2
+
+/* Linkage of a CTF_K_FUNC_LINKAGE and CTF_K_VAR (holds CTF_FUNC_*
+   or CTF_VAR_*, depending; CTF_K_FUNC_LINKAGE is literally just
+   the ctl_linkage field, stuffed into the vlen).  */
+typedef struct ctf_linkage
+{
+  uint32_t ctl_linkage;
+} ctf_linkage_t;
+
+/* Parameter data for CTF_K_FUNCTION.  Aligned with btf_param.  */
+
+typedef struct ctf_param
+{
+  uint32_t cfp_name;
+  uint32_t cfp_type;
+} ctf_param_t;
+
+/* Variant data of CTF_K_DECL_TAG.  component_idx != -1 means that this tag
+   applies to the given member or func argument.  */
+
+typedef struct ctf_decl_tag
+{
+  int32_t cdt_component_idx;
+} ctf_decl_tag_t;
 
 typedef struct ctf_enum
 {
   uint32_t cte_name;           /* Reference to name in string table.  */
-  int32_t cte_value;           /* Value associated with this name.  */
+  uint32_t cte_value;          /* Value associated with this name.  */
 } ctf_enum_t;
 
+typedef struct ctf_enum64
+{
+  uint32_t cte_name;           /* Reference to name in string table.  */
+  uint32_t cte_val_low;                /* Low word of value.  */
+  uint32_t cte_val_high;       /* High word of value.  (May actually be
+                                  unsigned.)  */
+} ctf_enum64_t;
+
 /* The ctf_archive is a collection of ctf_dict_t's stored together. The format
    is suitable for mmap()ing: this control structure merely describes the
    mmap()ed archive (and overlaps the first few bytes of it), hence the
index 46b8a6e1ed41fcab7998a272b9142b8cb3d62f9b..1620df61e80ab40b7d656c8849fe17ceb3dbefbe 100644 (file)
@@ -52,7 +52,8 @@ noinst_LTLIBRARIES = libctf.la libctf-nobfd.la
 endif
 
 libctf_nobfd_la_LIBADD = @CTF_LIBADD@ $(ZLIB)
-libctf_ldflags_nover = -version-info 0:0:0 @SHARED_LDFLAGS@
+libctf_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
+libctf_ldflags_nover = $(libctf_version_info) @SHARED_LDFLAGS@
 libctf_nobfd_la_LDFLAGS = $(libctf_ldflags_nover) @VERSION_FLAGS_NOBFD@
 libctf_nobfd_la_CPPFLAGS = $(AM_CPPFLAGS) -DNOBFD=1
 libctf_nobfd_la_SOURCES = ctf-api.c ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c ctf-error.c \
@@ -123,4 +124,6 @@ EXTRA_DEJAGNU_SITE_CONFIG = development.exp
 
 DISTCLEANFILES += site.exp development.exp
 
+EXTRA_DIST = libtool-version libctf.ver
+
 include doc/local.mk
index e17a87cca5be289bff8ee58dbbff9564eb55e068..298def58996690893298bbd35a77230242538b14 100644 (file)
@@ -604,7 +604,8 @@ AM_CFLAGS = -std=gnu99 @ac_libctf_warn_cflags@ @warn@ @c_warn@ @WARN_PEDANTIC@ @
 @INSTALL_LIBBFD_TRUE@include_HEADERS = $(INCDIR)/ctf.h $(INCDIR)/ctf-api.h
 @INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libctf.la libctf-nobfd.la
 libctf_nobfd_la_LIBADD = @CTF_LIBADD@ $(ZLIB)
-libctf_ldflags_nover = -version-info 0:0:0 @SHARED_LDFLAGS@
+libctf_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
+libctf_ldflags_nover = $(libctf_version_info) @SHARED_LDFLAGS@
 libctf_nobfd_la_LDFLAGS = $(libctf_ldflags_nover) @VERSION_FLAGS_NOBFD@
 libctf_nobfd_la_CPPFLAGS = $(AM_CPPFLAGS) -DNOBFD=1
 libctf_nobfd_la_SOURCES = ctf-api.c ctf-archive.c ctf-dump.c \
@@ -642,6 +643,7 @@ CC_FOR_TARGET = ` \
 # development.sh is used to determine -Werror default.
 CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/development.sh
 EXTRA_DEJAGNU_SITE_CONFIG = development.exp
+EXTRA_DIST = libtool-version libctf.ver
 @BUILD_INFO_TRUE@AM_MAKEINFOFLAGS = --no-split
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
index 40b1f7adf1bc6dd3d7d8541ed2e1c8ea525d892a..b3d844ae58e95cf4efc3876e469d8e9f0bc73101 100644 (file)
    along with this program; see the file COPYING.  If not see
    <http://www.gnu.org/licenses/>.  */
 
-LIBCTF_1.0 {
+LIBCTF_2.0 {
     global:
        /* In libctf and libctf-nobfd.  */
 
+       ctf_dict_open;
+       ctf_dict_open_sections;
        ctf_bufopen;
        ctf_simple_open;
        ctf_create;
        ctf_close;
        ctf_ref;
+       ctf_dict_close;
        ctf_file_close;
 
        ctf_cuname;
@@ -32,6 +35,7 @@ LIBCTF_1.0 {
        ctf_parent_file;
        ctf_parent_name;
        ctf_parent_name_set;
+       ctf_parent_dict;
        ctf_type_isparent;
        ctf_type_ischild;
 
@@ -53,6 +57,11 @@ LIBCTF_1.0 {
 
        ctf_lookup_by_name;
        ctf_lookup_by_symbol;
+       ctf_symbol_next;
+       ctf_lookup_by_symbol_name;
+       ctf_arc_lookup_symbol;
+       ctf_arc_lookup_symbol_name;
+
        ctf_lookup_variable;
 
        ctf_type_resolve;
@@ -82,6 +91,9 @@ LIBCTF_1.0 {
 
        ctf_label_topmost;
        ctf_label_info;
+       ctf_lookup_enumerator;
+       ctf_lookup_enumerator_next;
+       ctf_arc_lookup_enumerator_next;
 
        ctf_member_iter;
        ctf_enum_iter;
@@ -114,6 +126,7 @@ LIBCTF_1.0 {
        ctf_add_union;
        ctf_add_struct_sized;
        ctf_add_union_sized;
+       ctf_add_unknown;
        ctf_add_volatile;
 
        ctf_add_enumerator;
@@ -133,6 +146,10 @@ LIBCTF_1.0 {
        ctf_gzwrite;
        ctf_compress_write;
        ctf_getdatasect;
+       ctf_getsymsect;
+       ctf_getstrsect;
+       ctf_symsect_endianness;
+       ctf_arc_symsect_endianness;
 
        ctf_arc_write;
        ctf_arc_write_fd;
@@ -145,6 +162,7 @@ LIBCTF_1.0 {
        ctf_archive_next;
        ctf_archive_raw_iter;
        ctf_get_arc;
+       ctf_arc_flush_caches;
 
        ctf_dump;
 
@@ -161,6 +179,13 @@ LIBCTF_1.0 {
        ctf_link_shuffle_syms;
        ctf_link_write;
 
+       ctf_link_add_linker_symbol;
+       ctf_add_objt_sym;
+       ctf_add_func_sym;
+
+       ctf_dict_set_flag;
+       ctf_dict_get_flag;
+
        ctf_fdopen;                             /* libctf only.  */
        ctf_open;                               /* libctf only.  */
        ctf_arc_open;                           /* libctf only.  */
@@ -169,41 +194,3 @@ LIBCTF_1.0 {
     local:
        *;
 };
-
-LIBCTF_1.1 {
-    global:
-       ctf_dict_open;
-       ctf_dict_open_sections;
-       ctf_dict_close;
-       ctf_parent_dict;
-
-       ctf_symbol_next;
-       ctf_add_objt_sym;
-       ctf_add_func_sym;
-
-       ctf_link_add_linker_symbol;
-
-       ctf_arc_lookup_symbol;
-       ctf_arc_flush_caches;
-
-       ctf_getsymsect;
-       ctf_getstrsect;
-       ctf_symsect_endianness;
-       ctf_arc_symsect_endianness;
-} LIBCTF_1.0;
-
-LIBCTF_1.2 {
-    global:
-       ctf_lookup_by_symbol_name;
-       ctf_arc_lookup_symbol_name;
-       ctf_add_unknown;
-} LIBCTF_1.1;
-
-LIBCTF_1.3 {
-    global:
-       ctf_lookup_enumerator;
-       ctf_lookup_enumerator_next;
-       ctf_arc_lookup_enumerator_next;
-       ctf_dict_set_flag;
-       ctf_dict_get_flag;
-} LIBCTF_1.2;
diff --git a/libctf/libtool-version b/libctf/libtool-version
new file mode 100644 (file)
index 0000000..fd2d2c4
--- /dev/null
@@ -0,0 +1,30 @@
+# This file is used to maintain libtool version info for libctf.  See
+# the libtool manual to understand the meaning of the fields.  This is
+# a separate file so that version updates don't involve re-running
+# automake.
+#
+# Here are a set of rules to help you update your library version
+# information:
+#
+# 1. Start with version information of `0:0:0' for each libtool library.
+#
+# 2. Update the version information only immediately before a public
+#    release of your software. More frequent updates are unnecessary,
+#    and only guarantee that the current interface number gets larger
+#    faster.
+#
+# 3. If the library source code has changed at all since the last
+#    update, then increment revision (`c:r:a' becomes `c:r+1:a').
+#
+# 4. If any interfaces have been added, removed, or changed since the
+#    last update, increment current, and set revision to 0.
+#
+# 5. Increase the age value only if the changes made to the ABI are backward
+#    compatible.
+#    a. If any interfaces have been added since the last public release,
+#       then increment age.
+#    b. If any interfaces have been removed since the last public release,
+#       then set age to 0.
+#
+# CURRENT:REVISION:AGE
+1:0:0