From: Nick Alcock Date: Fri, 25 Apr 2025 10:47:07 +0000 (+0100) Subject: libctf: types: access to raw type data X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4837852527158d74151671fd4bd6bc7f47421491;p=thirdparty%2Fbinutils-gdb.git libctf: types: access to raw type data This new API lets users ask for the raw type data associated with a type (either the whole lot including prefixes, or just the suffix if this is not a CTF_K_BIG type), and then they can manipulate it using ctf.h functions or whatever else they like. Doing this does not preclude using libctf querying functions at the same time (just don't change the type! It's const for a reason). New API: +const ctf_type_t *ctf_type_data (ctf_dict_t *, ctf_id_t, int prefix); This function was unimplementable before the DTD changes, because the ctf_type_t and vlen were separated in memory: but now they're always stored in a single buffer, it's reliable and simple, indeed trivial. --- diff --git a/include/ctf-api.h b/include/ctf-api.h index 09b6e7a6890..a23e1da0ace 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -264,6 +264,7 @@ typedef struct ctf_snapshot_id _CTF_ITEM (ECTF_NODATASEC, "Variable not found in datasec.") \ _CTF_ITEM (ECTF_NOTDECLTAG, "This function requires a decl tag.") \ _CTF_ITEM (ECTF_NOTTAG, "This function requires a type or decl tag.") \ + _CTF_ITEM (ECTF_TOOLARGE, "Prefix required for correct representation.") #define ECTF_BASE 1000 /* Base value for libctf errnos. */ @@ -276,7 +277,7 @@ _CTF_ERRORS #undef _CTF_FIRST }; -#define ECTF_NERR (ECTF_NOTSERIALIZED - ECTF_BASE + 1) /* Count of CTF errors. */ +#define ECTF_NERR (ECTF_TOOLARGE - ECTF_BASE + 1) /* Count of CTF errors. */ /* The CTF data model is inferred to be the caller's data model or the data model of the given object, unless ctf_setmodel is explicitly called. */ @@ -651,6 +652,16 @@ extern ssize_t ctf_type_lname (ctf_dict_t *, ctf_id_t, char *, size_t); extern char *ctf_type_name (ctf_dict_t *, ctf_id_t, char *, size_t); +/* Retrieve raw (BTF or CTF-format) type data for the type with a given ID. + The vlen follows the record returned in the usual way for a type. + + If PREFIX is 0, return only the data for the type itself: if the type is too + large to be accurately represented without a CTF_K_BIG prefix, this will + fail with ECTF_TOOLARGE. Otherwise, return the entire type, includiung + any prefixes. */ + +extern const ctf_type_t *ctf_type_data (ctf_dict_t *, ctf_id_t, int prefix); + /* Return the size or alignment of a type. Types with no meaningful size, like function types, return 0 as their size; incomplete types set ECTF_INCOMPLETE. The type is resolved for you, so cvr-quals and typedefs can be passsed in. */ diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 59dd7754fc6..4ff32c2f847 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -1019,6 +1019,35 @@ ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name) ctf_dynhash_lookup (ctf_name_table (fp, kind), name); } +/* Retrieve raw type data. */ + +const ctf_type_t * +ctf_type_data (ctf_dict_t *fp, ctf_id_t type, int prefix) +{ + const ctf_type_t *tp, *suffix, *big; + + if (fp->ctf_flags & LCTF_NO_STR) + { + ctf_set_errno (fp, ECTF_NOPARENT); + return NULL; + } + + if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL) + return NULL; /* errno is set for us. */ + + if (!prefix && ((big = ctf_find_prefix (fp, tp, CTF_K_BIG)) != NULL) + && ((CTF_INFO_VLEN (big->ctt_info) != 0) || (big->ctt_size != 0))) + { + ctf_set_errno (fp, ECTF_TOOLARGE); + return NULL; + } + + if (prefix) + return tp; + else + return suffix; +} + /* Lookup the given type ID and return its name as a new dynamically-allocated string. */ diff --git a/libctf/libctf.ver b/libctf/libctf.ver index c8525b5f1d5..24480f37b86 100644 --- a/libctf/libctf.ver +++ b/libctf/libctf.ver @@ -85,6 +85,7 @@ LIBCTF_2.0 { ctf_type_visit; ctf_type_cmp; ctf_type_compat; + ctf_type_data; ctf_tag; ctf_decl_tag;