libctf, create, types: encoding, BTF floats

This adds support for the nearly useless BTF_KIND_FLOAT, under the name
CTF_K_BTF_FLOAT.  At the same time we fix up the ctf_add_encoding and
ctf_type_encoding machinery for the new API changes.

I expect this to change a bit: Ali Bahrami reckons I've oversimplified the
CTFv4 encoding representation and need to reintroduce at least a width.

New API:

ctf_id_t ctf_add_btf_float (ctf_dict_t *, uint32_t,
                            const char *, const ctf_encoding_t *);
This commit is contained in:
Nick Alcock
2025-04-24 17:28:34 +01:00
parent 03609073b0
commit 2c1a0a70d1
4 changed files with 46 additions and 36 deletions

View File

@@ -135,7 +135,9 @@ typedef enum ctf_sect_names
/* Encoding information for integers, floating-point values, and certain other /* Encoding information for integers, floating-point values, and certain other
intrinsics can be obtained by calling ctf_type_encoding, below. The flags intrinsics can be obtained by calling ctf_type_encoding, below. The flags
field will contain values appropriate for the type defined in <ctf.h>. */ field will contain values appropriate for the type defined in <ctf.h>.
For floats, only the first of these fields is meaningful. */
typedef struct ctf_encoding typedef struct ctf_encoding
{ {
@@ -846,6 +848,8 @@ extern ctf_id_t ctf_add_enum64 (ctf_dict_t *, uint32_t, const char *);
extern ctf_id_t ctf_add_enum_encoded (ctf_dict_t *, uint32_t, const char *, extern ctf_id_t ctf_add_enum_encoded (ctf_dict_t *, uint32_t, const char *,
const ctf_encoding_t *); const ctf_encoding_t *);
extern ctf_id_t ctf_add_enum (ctf_dict_t *, uint32_t, const char *); extern ctf_id_t ctf_add_enum (ctf_dict_t *, uint32_t, const char *);
extern ctf_id_t ctf_add_btf_float (ctf_dict_t *, uint32_t,
const char *, const ctf_encoding_t *);
extern ctf_id_t ctf_add_float (ctf_dict_t *, uint32_t, extern ctf_id_t ctf_add_float (ctf_dict_t *, uint32_t,
const char *, const ctf_encoding_t *); const char *, const ctf_encoding_t *);
extern ctf_id_t ctf_add_forward (ctf_dict_t *, uint32_t, const char *, extern ctf_id_t ctf_add_forward (ctf_dict_t *, uint32_t, const char *,

View File

@@ -668,32 +668,29 @@ ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
if (name == NULL || name[0] == '\0') if (name == NULL || name[0] == '\0')
return (ctf_set_typed_errno (fp, ECTF_NONAME)); return (ctf_set_typed_errno (fp, ECTF_NONAME));
if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT)) if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT
return CTF_ERR; /* errno is set for us. */ || kind == CTF_K_BTF_FLOAT))
return CTF_ERR; /* errno is set for us. */
if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t), if (kind == CTF_K_BTF_FLOAT)
&dtd)) == CTF_ERR) vlen = 0;
if ((dtd = ctf_add_generic (fp, flag, name, kind, 0, vlen, 0, NULL)) == NULL)
return CTF_ERR; /* errno is set for us. */ return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0); dtd->dtd_data->ctt_info = CTF_TYPE_INFO (kind, 0, 0);
dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT) dtd->dtd_data->ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT) / CHAR_BIT);
/ CHAR_BIT);
switch (kind)
{
case CTF_K_INTEGER:
encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
break;
case CTF_K_FLOAT:
encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
break;
default:
/* ctf_assert is opaque with -fno-inline. This dead code avoids
a warning about "encoding" being used uninitialized. */
return CTF_ERR;
}
memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
return type; if (kind != CTF_K_BTF_FLOAT)
{
encoding = ep->cte_format;
if (kind == CTF_K_INTEGER)
encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
}
return dtd->dtd_type;
} }
ctf_id_t ctf_id_t
@@ -770,7 +767,7 @@ ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
kind = ctf_type_kind_unsliced (fp, resolved_ref); kind = ctf_type_kind_unsliced (fp, resolved_ref);
if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
(kind != CTF_K_ENUM) (kind != CTF_K_ENUM) && (kind != CTF_K_BTF_FLOAT)
&& (ref != 0)) && (ref != 0))
return (ctf_set_typed_errno (fp, ECTF_NOTINTFP)); return (ctf_set_typed_errno (fp, ECTF_NOTINTFP));
@@ -805,6 +802,13 @@ ctf_add_float (ctf_dict_t *fp, uint32_t flag,
return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT)); return (ctf_add_encoded (fp, flag, name, ep, CTF_K_FLOAT));
} }
ctf_id_t
ctf_add_btf_float (ctf_dict_t *fp, uint32_t flag,
const char *name, const ctf_encoding_t *ep)
{
return (ctf_add_encoded (fp, flag, name, ep, CTF_K_BTF_FLOAT));
}
ctf_id_t ctf_id_t
ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref) ctf_add_pointer (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref)
{ {

View File

@@ -871,6 +871,7 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
case CTF_K_FLOAT: case CTF_K_FLOAT:
case CTF_K_TYPEDEF: case CTF_K_TYPEDEF:
/* Integers, floats, and typedefs must always be named types. */ /* Integers, floats, and typedefs must always be named types. */
case CTF_K_BTF_FLOAT:
if (name[0] == '\0') if (name[0] == '\0')
{ {
@@ -1387,24 +1388,19 @@ int
ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep) ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
{ {
ctf_dict_t *ofp = fp; ctf_dict_t *ofp = fp;
ctf_dtdef_t *dtd; const ctf_type_t *tp, *suffix;
const ctf_type_t *tp;
ssize_t increment;
const unsigned char *vlen; const unsigned char *vlen;
uint32_t data; uint32_t data;
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL)
return -1; /* errno is set for us. */ return -1; /* errno is set for us. */
if ((dtd = ctf_dynamic_type (ofp, type)) != NULL) if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
vlen = dtd->dtd_vlen; return (ctf_set_typed_errno (ofp, ECTF_NOTYPE));
else
{
ctf_get_ctt_size (fp, tp, NULL, &increment);
vlen = (const unsigned char *) ((uintptr_t) tp + increment);
}
switch (LCTF_INFO_KIND (fp, tp->ctt_info)) vlen = ctf_vlen (fp, type, tp, NULL);
switch (LCTF_KIND (fp, tp))
{ {
case CTF_K_INTEGER: case CTF_K_INTEGER:
data = *(const uint32_t *) vlen; data = *(const uint32_t *) vlen;
@@ -1424,6 +1420,11 @@ ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
ep->cte_offset = 0; ep->cte_offset = 0;
ep->cte_bits = 0; ep->cte_bits = 0;
break; break;
case CTF_K_BTF_FLOAT:
ep->cte_format = 0;
ep->cte_offset = 0;
ep->cte_bits = suffix->ctt_size * CHAR_BIT;
break;
case CTF_K_SLICE: case CTF_K_SLICE:
{ {
const ctf_slice_t *slice; const ctf_slice_t *slice;

View File

@@ -116,6 +116,7 @@ LIBCTF_2.0 {
ctf_add_enum64; ctf_add_enum64;
ctf_add_enum64_encoded; ctf_add_enum64_encoded;
ctf_add_float; ctf_add_float;
ctf_add_btf_float;
ctf_add_forward; ctf_add_forward;
ctf_add_function; ctf_add_function;
ctf_add_integer; ctf_add_integer;