libctf: introduce ctf_func_type_{info,args}, ctf_type_aname_raw
The first two of these allow you to get function type info and args out of the types section give a type ID: astonishingly, this was missing from libctf before now: so even though types of kind CTF_K_FUNCTION were supported, you couldn't find out anything about them. (The existing ctf_func_info and ctf_func_args only allow you to get info about functions in the function section, i.e. given symbol table indexes, not type IDs.) The second of these allows you to get the raw undecorated name out of the CTF section (strdupped for safety) without traversing subtypes to build a full C identifier out of it. It's useful for things that are already tracking the type kind etc and just need an unadorned name. include/ * ctf-api.h (ECTF_NOTFUNC): Fix description. (ctf_func_type_info): New. (ctf_func_type_args): Likewise. libctf/ * ctf-types.c (ctf_type_aname_raw): New. (ctf_func_type_info): Likewise. (ctf_func_type_args): Likewise. * ctf-error.c (_ctf_errlist): Fix description.
This commit is contained in:
parent
afe09f0b63
commit
12a0b67d28
6 changed files with 106 additions and 3 deletions
|
@ -369,6 +369,23 @@ ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
|
|||
return (rv >= 0 && (size_t) rv < len ? buf : NULL);
|
||||
}
|
||||
|
||||
/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
|
||||
new dynamcally-allocated string. */
|
||||
|
||||
char *
|
||||
ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
const ctf_type_t *tp;
|
||||
|
||||
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
|
||||
return NULL; /* errno is set for us. */
|
||||
|
||||
if (ctf_strraw (fp, tp->ctt_name) != NULL)
|
||||
return strdup (ctf_strraw (fp, tp->ctt_name));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Resolve the type down to a base type node, and then return the size
|
||||
of the type storage in bytes. */
|
||||
|
||||
|
@ -948,6 +965,74 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Given a type ID relating to a function type, return info on return types and
|
||||
arg counts for that function. */
|
||||
|
||||
int
|
||||
ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
|
||||
{
|
||||
const ctf_type_t *tp;
|
||||
uint32_t kind;
|
||||
const uint32_t *args;
|
||||
ssize_t size, increment;
|
||||
|
||||
if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
(void) ctf_get_ctt_size (fp, tp, &size, &increment);
|
||||
kind = LCTF_INFO_KIND (fp, tp->ctt_info);
|
||||
|
||||
if (kind != CTF_K_FUNCTION)
|
||||
return (ctf_set_errno (fp, ECTF_NOTFUNC));
|
||||
|
||||
fip->ctc_return = tp->ctt_type;
|
||||
fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
|
||||
fip->ctc_flags = 0;
|
||||
|
||||
args = (uint32_t *) ((uintptr_t) tp + increment);
|
||||
|
||||
if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
|
||||
{
|
||||
fip->ctc_flags |= CTF_FUNC_VARARG;
|
||||
fip->ctc_argc--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a type ID relating to a function type,, return the arguments for the
|
||||
function. */
|
||||
|
||||
int
|
||||
ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
|
||||
{
|
||||
const ctf_type_t *tp;
|
||||
const uint32_t *args;
|
||||
ssize_t size, increment;
|
||||
ctf_funcinfo_t f;
|
||||
|
||||
if (ctf_func_type_info (fp, type, &f) < 0)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
(void) ctf_get_ctt_size (fp, tp, &size, &increment);
|
||||
|
||||
args = (uint32_t *) ((uintptr_t) tp + increment);
|
||||
|
||||
for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
|
||||
*argv++ = *args++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Recursively visit the members of any type. This function is used as the
|
||||
engine for ctf_type_visit, below. We resolve the input type, recursively
|
||||
invoke ourself for each type member if the type is a struct or union, and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue