libctf: ctf-lookup: support prefixes in ctf_lookup_by_id

ctf_lookup_by_id now has a new optional suffix argument, which,
if set, returns the suffix of a prefixed type: the ctf_type_t it
returns remains (as ever) the first one in the type (i.e. it
may be a prefix type).  This is most convenient because the prefix
is the ctf_type_t that LCTF_KIND and other LCTF functions taking
ctf_type_t's expect.

Callers not yet adjusted.
This commit is contained in:
Nick Alcock
2025-04-24 14:17:19 +01:00
parent a80b903b45
commit 2ef9554023
2 changed files with 38 additions and 9 deletions

View File

@@ -622,8 +622,9 @@ extern ctf_id_t ctf_index_to_type (const ctf_dict_t *, uint32_t);
#define LCTF_PRESERIALIZED 0x0020 /* Already serialized all but the strtab. */ #define LCTF_PRESERIALIZED 0x0020 /* Already serialized all but the strtab. */
extern ctf_dynhash_t *ctf_name_table (ctf_dict_t *, int); extern ctf_dynhash_t *ctf_name_table (ctf_dict_t *, int);
extern const ctf_type_t *ctf_lookup_by_id (ctf_dict_t **, ctf_id_t);
extern ctf_id_t ctf_lookup_variable_here (ctf_dict_t *fp, const char *name); extern ctf_id_t ctf_lookup_variable_here (ctf_dict_t *fp, const char *name);
extern const ctf_type_t *ctf_lookup_by_id (ctf_dict_t **, ctf_id_t,
const ctf_type_t **suffix);
extern ctf_id_t ctf_lookup_by_sym_or_name (ctf_dict_t *, unsigned long symidx, extern ctf_id_t ctf_lookup_by_sym_or_name (ctf_dict_t *, unsigned long symidx,
const char *symname, int try_parent, const char *symname, int try_parent,
int is_function); int is_function);

View File

@@ -371,12 +371,16 @@ ctf_lookup_by_name (ctf_dict_t *fp, const char *name)
return ctf_lookup_by_name_internal (fp, NULL, name); return ctf_lookup_by_name_internal (fp, NULL, name);
} }
/* Return the pointer to the internal CTF type data corresponding to the /* Return the pointer to the internal CTF type data corresponding to the given
given type ID. If the ID is invalid, the function returns NULL. type ID. If the ID is invalid, the function returns NULL. The type data
returned is the prefix, if this is a a prefixed kind: if SUFFIX is set, also
provide the suffix. If there is no prefix, the SUFFIX is the same as the
return value. (See ctf-open.c's dictops for why.)
This function is not exported outside of the library. */ This function is not exported outside of the library. */
const ctf_type_t * const ctf_type_t *
ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type) ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type, const ctf_type_t **suffix)
{ {
ctf_dict_t *fp = *fpp; ctf_dict_t *fp = *fpp;
ctf_id_t idx; ctf_id_t idx;
@@ -388,14 +392,38 @@ ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type)
} }
idx = ctf_type_to_index (fp, type); idx = ctf_type_to_index (fp, type);
if (idx > 0 && (unsigned long) idx <= fp->ctf_typemax) if ((unsigned long) idx > fp->ctf_typemax)
{ {
*fpp = fp; /* Possibly the parent CTF dict. */ ctf_set_errno (*fpp, ECTF_BADID);
return (LCTF_INDEX_TO_TYPEPTR (fp, idx)); return NULL;
} }
(void) ctf_set_errno (*fpp, ECTF_BADID); *fpp = fp; /* Possibly the parent CTF dict. */
return NULL; if (idx > fp->ctf_stypes)
{
ctf_dtdef_t *dtd;
dtd = ctf_dtd_lookup (fp, ctf_index_to_type (fp, idx));
if (suffix)
*suffix = dtd->dtd_data;
return dtd->dtd_buf;
}
else
{
ctf_type_t *tp = fp->ctf_txlate[idx];
if (suffix)
{
ctf_type_t *suff;
suff = tp;
while (LCTF_IS_PREFIXED_INFO (suff->ctt_info))
suff++;
*suffix = suff;
}
return tp;
}
} }
typedef struct ctf_lookup_idx_key typedef struct ctf_lookup_idx_key