aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2022-03-07 13:44:02 +0000
committerMark Johnston <markj@FreeBSD.org>2022-04-18 16:38:22 +0000
commit6e6983ee2b722a4d931bc1829870a22e5853951d (patch)
treeb4d4cf87b345367ec4e31bdb95fb79f9e5ae881f
parent30700bc80e8e156672acec9f880b09825a1ebb05 (diff)
downloadsrc-6e6983ee2b722a4d931bc1829870a22e5853951d.tar.gz
src-6e6983ee2b722a4d931bc1829870a22e5853951d.zip
ctf: Add definitions for CTFv3
These are based on definitions added to binutils' libctf. Specifically: - Type IDs are now encoded in 32 bits rather than 16, changing the layout of ctf_type_t, ctf_array_t, ctf_member_t and ctf_lmember_t. - Type info is encoded in 32 bits rather than 16. The type "kind" is extended from 5 bits to 6, and the type "vlen" is extended from 10 bits to 25. The main upside is that we remove the current limit, imposed by CTFv2, of 2^{15} distinct types in the main kernel executable. Other limits, such as that on the number of elements in an enum, imposed by the vlen limit, are also raised. This change adds v2 and v3 flavours of macros and type definitions which differ between the two versions. Compatibility is preserved for now by having generic names refer to the v2 definitions, so, e.g., ctf_type_t is still a v2 type. No functional change intended. Approved by: re (gjb) Reviewed by: Domagoj Stolfa Sponsored by: The FreeBSD Foundation (cherry picked from commit 994297b01b98816bea1abf45ae4bac1bc69ee7a0) (cherry picked from commit 9818e5ebf3376ee5dbd01afe24e9972d9201633e)
-rw-r--r--cddl/contrib/opensolaris/lib/libctf/common/ctf.5208
-rw-r--r--sys/sys/ctf.h139
2 files changed, 227 insertions, 120 deletions
diff --git a/cddl/contrib/opensolaris/lib/libctf/common/ctf.5 b/cddl/contrib/opensolaris/lib/libctf/common/ctf.5
index d9f41de6a9ca..1d747bbbea13 100644
--- a/cddl/contrib/opensolaris/lib/libctf/common/ctf.5
+++ b/cddl/contrib/opensolaris/lib/libctf/common/ctf.5
@@ -11,7 +11,7 @@
.\"
.\" Copyright (c) 2014 Joyent, Inc.
.\"
-.Dd Sep 26, 2014
+.Dd February 28, 2022
.Dt CTF 5
.Os
.Sh NAME
@@ -65,11 +65,11 @@ data can be obtained through libctf.
The
.Nm
file format is broken down into seven different sections.
-The first section is the
+The first two sections are the
.Sy preamble
and
.Sy header ,
-which describes the version of the
+which describe the version of the
.Nm
file, the links it has to other
.Nm
@@ -129,15 +129,22 @@ and the type information that comes from the
module.
This means that a module only has types that are unique to itself and the most
common types in the kernel are not duplicated.
+Uniquification is not used when building kernel modules on
+.Fx .
.Sh FILE FORMAT
This documents version
-.Em two
+.Em three
of the
.Nm
file format.
-All applications and tools on
-.Fx
-currently produce and operate on this version.
+The
+.Xr ctfconvert 1
+and
+.Xr ctfmerge 1
+utilities emit
+.Nm
+version 3, and all other applications and libraries can operate on
+versions 2 and 3.
.Lp
The file format can be summarized with the following image, the
following sections will cover this in more detail.
@@ -164,7 +171,7 @@ following sections will cover this in more detail.
||||||| +-- magic - vers flags
||||||| | | | |
||||||| +------+------+------+------+
-+---------| 0xcf | 0xf1 | 0x02 | 0x00 |
++---------| 0xcf | 0xf1 | 0x03 | 0x00 |
|||||| +------+------+------+------+
|||||| 0 1 2 3 4
||||||
@@ -191,7 +198,7 @@ following sections will cover this in more detail.
|||| +------+------+------+-----+
+----------| 0x00 | 0x42 | 0x36 | ... |
||| +------+------+------+-----+
- ||| cth_objtoff +0x2 +0x4 +0x6 cth_funcoff
+ ||| cth_objtoff +0x4 +0x8 +0xc cth_funcoff
|||
||| + CTF_TYPE_INFO + CTF_TYPE_INFO
||| | + Return type |
@@ -199,7 +206,7 @@ following sections will cover this in more detail.
||| +--------+------+------+-----+
+---------| 0x2c10 | 0x08 | 0x0c | ... |
|| +--------+------+------+-----+
- || cth_funcff +0x2 +0x4 +0x6 cth_typeoff
+ || cth_funcff +0x4 +0x8 +0xc cth_typeoff
||
|| + ctf_stype_t for type 1
|| | integer + integer encoding
@@ -208,7 +215,7 @@ following sections will cover this in more detail.
|| +--------------------+-----------+-----+
+--------| 0x19 * 0xc01 * 0x0 | 0x1000000 | ... |
| +--------------------+-----------+-----+
- | cth_typeoff +0x08 +0x0c cth_stroff
+ | cth_typeoff +0x0c +0x10 cth_stroff
|
| +--- str 0
| | +--- str 1 + str 2
@@ -265,7 +272,7 @@ member defines the version of the
.Nm
file.
The current version is
-.Li 2 .
+.Li 3 .
It is possible to encounter an unsupported version.
In that case, software should not try to parse the format, as it may have
changed.
@@ -296,7 +303,7 @@ always refer to the
.Sy uncompressed
data.
.Lp
-In version two of the
+In versions two and three of the
.Nm
file format, the
.Sy header
@@ -327,7 +334,7 @@ typedef struct ctf_header {
After the
.Sy preamble ,
the next two members
-.Em cth_parlablel
+.Em cth_parlabel
and
.Em cth_parname ,
are used to identify the parent.
@@ -364,7 +371,7 @@ file.
The difference between members indicates the size of the section itself.
Different offsets have different alignment requirements.
The start of the
-.Em cth_objotoff
+.Em cth_objtoff
and
.Em cth_funcoff
must be two byte aligned, while the sections
@@ -381,9 +388,9 @@ section, one should subtract the offset of the section from the following one.
For example, the size of the
.Sy types
section can be calculated by subtracting
-.Em cth_stroff
+.Em cth_typeoff
from
-.Em cth_typeoff .
+.Em cth_stroff .
.Lp
Finally, the member
.Em cth_strlen
@@ -402,16 +409,20 @@ Through the
data, types are referred to by identifiers.
A given
.Nm
-file supports up to 32767 (0x7fff) types.
+file supports up to 2147483646 (0x7ffffffe) types.
+.Nm
+version 2 had a much smaller limit of 32767 types.
The first valid type identifier is 0x1.
When a given
.Nm
file is a child, indicated by a non-zero entry for the
.Sy header Ns 's
.Em cth_parname ,
-then the first valid type identifier is 0x8000 and the last is 0xffff.
-In this case, type identifiers 0x1 through 0x7fff are references to the
+then the first valid type identifier is 0x80000000 and the last is 0xfffffffe.
+In this case, type identifiers 0x1 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.
.Lp
The type identifier zero is a sentinel value used to indicate that there
is no type information available or it is an unknown type.
@@ -444,7 +455,7 @@ container.
Every
.Nm
type begins with metadata encoded into a
-.Sy uint16_t .
+.Sy uint32_t .
This encoded information tells us three different pieces of information:
.Bl -bullet -offset indent -compact
.It
@@ -455,16 +466,9 @@ Whether this type is a root type or not
The length of the variable data
.El
.Lp
-The 16 bits that make up the encoding are broken down such that you have
-five bits for the kind, one bit for indicating whether or not it is a
-root type, and 10 bits for the variable length.
-This is laid out as follows:
-.Bd -literal -offset indent
-+--------------------+
-| kind | root | vlen |
-+--------------------+
-15 11 10 9 0
-.Ed
+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.
.Lp
The current version of the file format defines 14 different kinds.
The interpretation of these different kinds will be discussed in the section
@@ -502,7 +506,7 @@ That type is not considered a
type.
If a type is a
.Sy root
-type, then it will have bit 10 set.
+type, then it will have bit 25 set.
.Lp
The variable length section is specific to each kind and is discussed in the
section
@@ -512,13 +516,13 @@ The following macros are useful for constructing and deconstructing the encoded
type information:
.Bd -literal -offset indent
-#define CTF_MAX_VLEN 0x3ff
-#define CTF_INFO_KIND(info) (((info) & 0xf800) >> 11)
-#define CTF_INFO_ISROOT(info) (((info) & 0x0400) >> 10)
-#define CTF_INFO_VLEN(info) (((info) & CTF_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_TYPE_INFO(kind, isroot, vlen) \\
- (((kind) << 11) | (((isroot) ? 1 : 0) << 10) | ((vlen) & CTF_MAX_VLEN))
+#define CTF_V3_TYPE_INFO(kind, isroot, vlen) \\
+ (((kind) << 26) | (((isroot) ? 1 : 0) << 25) | ((vlen) & CTF_V3_MAX_VLEN))
.Ed
.Ss The Label Section
When consuming
@@ -536,6 +540,11 @@ releases, that they are not used together by tools, particularly when a child
needs to refer to a type in the parent.
Because they are linked using the type identifiers, if the wrong parent is used
then the wrong type will be encountered.
+Note that this mechanism is not currently used on
+.Fx .
+In particular, kernel modules built on
+.Fx
+each contain a complete type graph.
.Lp
Each label is encoded in the file format using the following eight byte
structure:
@@ -573,7 +582,7 @@ The object section provides a mapping from ELF symbols of type
.Sy STT_OBJECT
in the symbol table to a type identifier.
Every entry in this section is a
-.Sy uint16_t
+.Sy uint32_t
which contains a type identifier as described in the section
.Sx Type Identifiers .
If there is no information for an object, then the type identifier 0x0
@@ -617,14 +626,17 @@ section and skipping the correct symbols:
#include <stdio.h>
/*
- * Given the start of the object section in the CTF file, the number of symbols,
+ * Given the start of the object section in a CTFv3 file, the number of symbols,
* and the ELF Data sections for the symbol table and the string table, this
* prints the type identifiers that correspond to objects. Note, a more robust
* implementation should ensure that they don't walk beyond the end of the CTF
* object section.
+ *
+ * An implementation that handles CTFv2 must take into account the fact that
+ * type identifiers are 16 bits wide rather than 32 bits wide.
*/
static int
-walk_symbols(uint16_t *objtoff, Elf_Data *symdata, Elf_Data *strdata,
+walk_symbols(uint32_t *objtoff, Elf_Data *symdata, Elf_Data *strdata,
long nsyms)
{
long i;
@@ -667,9 +679,9 @@ Unlike with objects, because functions have a variable number of arguments, they
start with a type encoding as defined in
.Sx Type Encoding ,
which is the size of a
-.Sy uint16_t .
+.Sy uint32_t .
For functions which have no type information available, they are encoded as
-.Li CTF_TYPE_INFO(CTF_K_UNKNOWN, 0, 0) .
+.Li CTF_V3_TYPE_INFO(CTF_K_UNKNOWN, 0, 0) .
Functions with arguments are encoded differently.
Here, the variable length is turned into the number of arguments in the
function.
@@ -677,12 +689,12 @@ If a function is a
.Sy varargs
type function, then the number of arguments is increased by one.
Functions with type information are encoded as:
-.Li CTF_TYPE_INFO(CTF_K_FUNCTION, 0, nargs) .
+.Li CTF_V3_TYPE_INFO(CTF_K_FUNCTION, 0, nargs) .
.Lp
For functions that have no type information, nothing else is encoded, and the
next function is encoded.
For functions with type information, the next
-.Sy uint16_t
+.Sy uint32_t
is encoded with the type identifier of the return type of the function.
It is followed by each of the type identifiers of the arguments, if any exist,
in the order that they appear in the function.
@@ -723,29 +735,29 @@ The base of the type information comes in two forms, a short form and a long
form, each of which may be followed by a variable number of arguments.
The following definitions describe the short and long forms:
.Bd -literal
-#define CTF_MAX_SIZE 0xfffe /* max size of a type in bytes */
-#define CTF_LSIZE_SENT 0xffff /* sentinel for ctt_size */
-#define CTF_MAX_LSIZE UINT64_MAX
+#define CTF_V3_MAX_SIZE 0xfffffffe /* max size of a type in bytes */
+#define CTF_V3_LSIZE_SENT 0xffffffff /* sentinel for ctt_size */
+#define CTF_V3_MAX_LSIZE UINT64_MAX
-typedef struct ctf_stype {
+struct ctf_stype_v3 {
uint32_t ctt_name; /* reference to name in string table */
- uint16_t ctt_info; /* encoded kind, variant length */
+ uint32_t ctt_info; /* encoded kind, variant length */
union {
- uint16_t _size; /* size of entire type in bytes */
- uint16_t _type; /* reference to another type */
+ uint32_t _size; /* size of entire type in bytes */
+ uint32_t _type; /* reference to another type */
} _u;
-} ctf_stype_t;
+};
-typedef struct ctf_type {
+struct ctf_type_v3 {
uint32_t ctt_name; /* reference to name in string table */
- uint16_t ctt_info; /* encoded kind, variant length */
+ uint32_t ctt_info; /* encoded kind, variant length */
union {
- uint16_t _size; /* always CTF_LSIZE_SENT */
- uint16_t _type; /* do not use */
+ uint32_t _size; /* always CTF_LSIZE_SENT */
+ uint32_t _type; /* do not use */
} _u;
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_t;
+};
#define ctt_size _u._size /* for fundamental types that have a size */
#define ctt_type _u._type /* for types that reference another type */
@@ -754,29 +766,29 @@ typedef struct ctf_type {
Type sizes are stored in
.Sy bytes .
The basic small form uses a
-.Sy uint16_t
+.Sy uint32_t
to store the number of bytes.
-If the number of bytes in a structure would exceed 0xfffe, then the alternate
-form, the
-.Sy ctf_type_t ,
+If the number of bytes in a structure would exceed 0xfffffffe, then the
+alternate form, the
+.Sy struct ctf_type_v3 ,
is used instead.
To indicate that the larger form is being used, the member
.Em ctt_size
is set to value of
-.Sy CTF_LSIZE_SENT
-(0xffff).
+.Sy CTF_V3_LSIZE_SENT
+(0xffffffff).
In general, when going through the type section, consumers use the
-.Sy ctf_type_t
+.Sy struct ctf_type_v3
structure, but pay attention to the value of the member
.Em ctt_size
-to determine whether they should increment their scan by the size of the
-.Sy ctf_stype_t
+to determine whether they should increment their scan by the size of
+.Sy struct ctf_stype_v3
or
-.Sy ctf_type_t .
+.Sy struct ctf_type_v3 .
Not all kinds of types use
.Sy ctt_size .
Those which do not, will always use the
-.Sy ctf_stype_t
+.Sy struct ctf_stype_v3
structure.
The individual sections for each kind have more information.
.Lp
@@ -798,7 +810,7 @@ The next member, the
is encoded as described in the section
.Sx Type Encoding .
The type's kind tells us how to interpret the remaining data in the
-.Sy ctf_type_t
+.Sy struct ctf_type_v3
and any variable length data that may exist.
The rest of this section will be broken down into the interpretation of the
various kinds.
@@ -936,11 +948,11 @@ With arrays, the
member is set to zero.
The structure that follows an array is defined as:
.Bd -literal
-typedef struct ctf_array {
- uint16_t cta_contents; /* reference to type of array contents */
- uint16_t cta_index; /* reference to type of array index */
+struct ctf_array_v3 {
+ uint32_t cta_contents; /* reference to type of array contents */
+ uint32_t cta_index; /* reference to type of array index */
uint32_t cta_nelems; /* number of elements */
-} ctf_array_t;
+};
.Ed
.Lp
The
@@ -948,7 +960,7 @@ The
and
.Em cta_index
members of the
-.Sy ctf_array_t
+.Sy struct ctf_array_v3
are type identifiers which are encoded as per the section
.Sx Type Identifiers .
The member
@@ -971,17 +983,23 @@ member is not used here.
The variable argument list contains the type identifiers for the arguments of
the function, if any.
Each one is represented by a
-.Sy uint16_t
+.Sy uint32_t
and encoded according to the
.Sx Type Identifiers
section.
If the function's last argument is of type varargs, then it is also written out,
but the type identifier is zero.
This is included in the count of the function's arguments.
-An extra type identifier may follow the argument and return type identifiers
-in order to maintain four-byte alignment for the following type definition.
+In
+.Nm
+version 2, an extra type identifier may follow the argument and return type
+identifiers in order to maintain four-byte alignment for the following type
+definition.
Such a type identifier is not included in the argument count and has a value
of zero.
+In
+.Nm
+version 3, four-byte alignment occurs naturally and no padding is used.
.Ss Encoding of Structures and Unions
Structures and Unions, which are encoded with
.Sy CTF_K_STRUCT
@@ -1000,23 +1018,22 @@ is the size of the structure and union.
There are two different structures which are used to encode members in the
variable list.
When the size of a structure or union is greater than or equal to the large
-member threshold, 8192, then a different structure is used to encode the member,
-all members are encoded using the same structure.
+member threshold, 536870912, then a different structure is used to encode the
+member; all members are encoded using the same structure.
The structure for members is as follows:
.Bd -literal
-typedef struct ctf_member {
+struct ctf_member_v3 {
uint32_t ctm_name; /* reference to name in string table */
- uint16_t ctm_type; /* reference to type of member */
- uint16_t ctm_offset; /* offset of this member in bits */
-} ctf_member_t;
+ uint32_t ctm_type; /* reference to type of member */
+ uint32_t ctm_offset; /* offset of this member in bits */
+};
-typedef struct ctf_lmember {
+struct ctf_lmember_v3 {
uint32_t ctlm_name; /* reference to name in string table */
- uint16_t ctlm_type; /* reference to type of member */
- uint16_t ctlm_pad; /* padding */
+ uint32_t ctlm_type; /* reference to type of member */
uint32_t ctlm_offsethi; /* high 32 bits of member offset in bits */
uint32_t ctlm_offsetlo; /* low 32 bits of member offset in bits */
-} ctf_lmember_t;
+};
.Ed
.Lp
Both the
@@ -1045,13 +1062,13 @@ at which the member 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 8192 bytes, the
-normal structure,
-.Sy ctf_member_t ,
+When the size of the overall structure is strictly less than 536870912 bytes,
+the normal structure,
+.Sy struct ctf_member_v3 ,
is used and the offset in bits is stored in the member
.Em ctm_offset .
-However, when the size of the structure is greater than or equal to 8192 bytes,
-then the number of bits is split into two 32-bit quantities.
+However, when the size of the structure is greater than or equal to 536870912
+bytes, then the number of bits is split into two 32-bit quantities.
One member,
.Em ctlm_offsethi ,
represents the upper 32 bits of the offset, while the other member,
@@ -1114,7 +1131,7 @@ actual type in the parent, otherwise the definition may be in another
.Nm
container or may not be known at all.
The only member of the
-.Sy ctf_type_t
+.Sy struct ctf_type_v3
that matters for a forward declaration is the
.Em ctt_name
which points to the name of the forward reference in the string table as
@@ -1216,6 +1233,9 @@ The type of the section must be
The section should have a link set to the symbol table and its address
alignment must be 4.
.Sh SEE ALSO
+.Xr ctfconvert 1 ,
+.Xr ctfdump 1 ,
+.Xr ctfmerge 1 ,
.Xr dtrace 1 ,
.Xr elf 3 ,
.Xr gelf 3 ,
diff --git a/sys/sys/ctf.h b/sys/sys/ctf.h
index e6a806143d51..4072e318320c 100644
--- a/sys/sys/ctf.h
+++ b/sys/sys/ctf.h
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
+ * Copyright (c) 2022 The FreeBSD Foundation
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -57,16 +58,25 @@ typedef struct ctf_lblent {
__uint32_t ctl_typeidx;
} ctf_lblent_t;
-typedef struct ctf_stype {
+struct ctf_stype_v2 {
__uint32_t ctt_name;
__uint16_t ctt_info;
union {
__uint16_t _size;
__uint16_t _type;
} _u;
-} ctf_stype_t;
+};
-typedef struct ctf_type {
+struct ctf_stype_v3 {
+ __uint32_t ctt_name;
+ __uint32_t ctt_info;
+ union {
+ __uint32_t _size;
+ __uint32_t _type;
+ } _u;
+};
+
+struct ctf_type_v2 {
__uint32_t ctt_name;
__uint16_t ctt_info;
union {
@@ -75,32 +85,63 @@ typedef struct ctf_type {
} _u;
__uint32_t ctt_lsizehi;
__uint32_t ctt_lsizelo;
-} ctf_type_t;
+};
+
+struct ctf_type_v3 {
+ __uint32_t ctt_name;
+ __uint32_t ctt_info;
+ union {
+ __uint32_t _size;
+ __uint32_t _type;
+ } _u;
+ __uint32_t ctt_lsizehi;
+ __uint32_t ctt_lsizelo;
+};
#define ctt_size _u._size
#define ctt_type _u._type
-typedef struct ctf_array {
+struct ctf_array_v2 {
__uint16_t cta_contents;
__uint16_t cta_index;
__uint32_t cta_nelems;
-} ctf_array_t;
+};
-typedef struct ctf_member {
+struct ctf_array_v3 {
+ __uint32_t cta_contents;
+ __uint32_t cta_index;
+ __uint32_t cta_nelems;
+};
+
+struct ctf_member_v2 {
__uint32_t ctm_name;
__uint16_t ctm_type;
__uint16_t ctm_offset;
-} ctf_member_t;
+};
+
+struct ctf_member_v3 {
+ __uint32_t ctm_name;
+ __uint32_t ctm_type;
+ __uint32_t ctm_offset;
+};
-typedef struct ctf_lmember {
+struct ctf_lmember_v2 {
__uint32_t ctlm_name;
__uint16_t ctlm_type;
__uint16_t ctlm_pad;
__uint32_t ctlm_offsethi;
__uint32_t ctlm_offsetlo;
-} ctf_lmember_t;
+};
-#define CTF_LSTRUCT_THRESH 8192
+struct ctf_lmember_v3 {
+ __uint32_t ctlm_name;
+ __uint32_t ctlm_type;
+ __uint32_t ctlm_offsethi;
+ __uint32_t ctlm_offsetlo;
+};
+
+#define CTF_V2_LSTRUCT_THRESH (1 << 13)
+#define CTF_V3_LSTRUCT_THRESH (1 << 29)
typedef struct ctf_enum {
__uint32_t cte_name;
@@ -109,23 +150,41 @@ typedef struct ctf_enum {
#define CTF_MAGIC 0xcff1
#define CTF_VERSION CTF_VERSION_2
+#define CTF_VERSION_3 3
#define CTF_VERSION_2 2
#define CTF_VERSION_1 1
#define CTF_MAX_NAME 0x7fffffff
-#define CTF_MAX_VLEN 0x03ff
-#define CTF_MAX_SIZE 0xfffe
-#define CTF_LSIZE_SENT (CTF_MAX_SIZE + 1) /* sentinel for cts vs ctt */
-#define CTF_PARENT_SHIFT 15
-#define CTF_MAX_TYPE 0xffff
-#define CTF_TYPE_ISPARENT(id) ((id) < 0x8000)
-#define CTF_TYPE_ISCHILD(id) ((id) > 0x7fff)
-#define CTF_TYPE_TO_INDEX(t) ((t) & 0x7fff)
-#define CTF_INDEX_TO_TYPE(t, c) (((t) & 0x7fff) | ((c) != 0 ? 0x8000 : 0))
+#define CTF_V2_MAX_VLEN 0x03ff
+#define CTF_V2_MAX_SIZE 0xfffe
+#define CTF_V2_LSIZE_SENT (CTF_V2_MAX_SIZE + 1) /* sentinel for cts vs ctt */
+
+#define CTF_V3_MAX_VLEN 0x00ffffff
+#define CTF_V3_MAX_SIZE 0xfffffffeu
+#define CTF_V3_LSIZE_SENT (CTF_V3_MAX_SIZE + 1)
+
+#define CTF_V2_PARENT_SHIFT 15
+#define CTF_V2_MAX_TYPE 0xffff
+#define CTF_V2_TYPE_ISPARENT(id) ((id) < 0x8000)
+#define CTF_V2_TYPE_ISCHILD(id) ((id) > 0x7fff)
+#define CTF_V2_TYPE_TO_INDEX(type) ((type) & 0x7fff)
+#define CTF_V2_INDEX_TO_TYPE(type, ischild) \
+ (((type) & 0x7fff) | ((ischild) != 0 ? 0x8000 : 0))
+#define CTF_V2_TYPE_INFO(kind, isroot, vlen) \
+ (((kind) << 11) | ((isroot) != 0 ? (1 << 10) : 0) | \
+ ((vlen) & CTF_V2_MAX_VLEN))
-#define CTF_TYPE_INFO(k, r, l) \
- ((k) << 11) | ((r) != 0 ? (1 << 10) : 0) | ((l) & ((1 << 10) - 1))
+#define CTF_V3_PARENT_SHIFT 31
+#define CTF_V3_MAX_TYPE 0xfffffffeu
+#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(type) ((type) & 0x7fffffffu)
+#define CTF_V3_INDEX_TO_TYPE(type, ischild) \
+ (((type) & 0x7fffffffu) | ((ischild) != 0 ? 0x80000000u : 0))
+#define CTF_V3_TYPE_INFO(kind, isroot, vlen) \
+ (((kind) << 26) | ((isroot) != 0 ? (1 << 25) : 0) | \
+ ((vlen) & CTF_V3_MAX_VLEN))
#define CTF_STRTAB_0 0
#define CTF_STRTAB_1 1
@@ -135,9 +194,14 @@ typedef struct ctf_enum {
/*
* Info macro.
*/
-#define CTF_INFO_VLEN(i) (((i) & CTF_MAX_VLEN))
-#define CTF_INFO_ISROOT(i) (((i) & 0x0400) >> 10)
-#define CTF_INFO_KIND(i) (((i) & 0xf800) >> 11)
+#define CTF_V2_INFO_VLEN(i) ((i) & CTF_V2_MAX_VLEN)
+#define CTF_V2_INFO_ISROOT(i) (((i) & 0x0400) >> 10)
+#define CTF_V2_INFO_KIND(i) (((i) & 0xf800) >> 11)
+
+#define CTF_V3_INFO_VLEN(i) ((i) & CTF_V3_MAX_VLEN)
+#define CTF_V3_INFO_ISROOT(i) (((i) & 0x02000000) >> 25)
+#define CTF_V3_INFO_KIND(i) (((i) & 0xfc000000) >> 26)
+
#define CTF_K_UNKNOWN 0
#define CTF_K_INTEGER 1
#define CTF_K_FLOAT 2
@@ -152,7 +216,7 @@ typedef struct ctf_enum {
#define CTF_K_VOLATILE 11
#define CTF_K_CONST 12
#define CTF_K_RESTRICT 13
-#define CTF_K_MAX 31
+#define CTF_K_MAX 63
/*
* Integer/Float Encoding macro.
@@ -211,4 +275,27 @@ typedef struct ctf_enum {
#define CTF_OFFSET_TO_LMEMHI(off) ((__uint32_t)((__uint64_t)(off) >> 32))
#define CTF_OFFSET_TO_LMEMLO(off) ((__uint32_t)(off))
+/*
+ * Compatibility for pre-v3 code.
+ */
+typedef struct ctf_array_v2 ctf_array_t;
+typedef struct ctf_member_v2 ctf_member_t;
+typedef struct ctf_lmember_v2 ctf_lmember_t;
+typedef struct ctf_type_v2 ctf_type_t;
+typedef struct ctf_stype_v2 ctf_stype_t;
+
+#define CTF_INFO_KIND CTF_V2_INFO_KIND
+#define CTF_INFO_VLEN CTF_V2_INFO_VLEN
+#define CTF_INFO_ISROOT CTF_V2_INFO_ISROOT
+#define CTF_TYPE_INFO CTF_V2_TYPE_INFO
+#define CTF_TYPE_ISPARENT CTF_V2_TYPE_ISPARENT
+#define CTF_TYPE_ISCHILD CTF_V2_TYPE_ISCHILD
+#define CTF_TYPE_TO_INDEX CTF_V2_TYPE_TO_INDEX
+#define CTF_INDEX_TO_TYPE CTF_V2_INDEX_TO_TYPE
+#define CTF_LSIZE_SENT CTF_V2_LSIZE_SENT
+#define CTF_LSTRUCT_THRESH CTF_V2_LSTRUCT_THRESH
+#define CTF_MAX_SIZE CTF_V2_MAX_SIZE
+#define CTF_MAX_TYPE CTF_V2_MAX_TYPE
+#define CTF_MAX_VLEN CTF_V2_MAX_VLEN
+
#endif /* _SYS_CTF_H_ */