diff options
-rw-r--r-- | include/ChangeLog | 7 | ||||
-rw-r--r-- | include/ctf-api.h | 5 | ||||
-rw-r--r-- | libctf/ChangeLog | 8 | ||||
-rw-r--r-- | libctf/ctf-error.c | 2 | ||||
-rw-r--r-- | libctf/ctf-lookup.c | 2 | ||||
-rw-r--r-- | libctf/ctf-types.c | 85 |
6 files changed, 106 insertions, 3 deletions
diff --git a/include/ChangeLog b/include/ChangeLog index 8954558..07e0c5c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2019-07-18 Nick Alcock <nick.alcock@oracle.com> + + * ctf-api.h (ECTF_NOTFUNC): Fix description. + (ctf_func_type_info): New. + (ctf_func_type_args): Likewise. + (ctf_type_aname_raw): Likewise. + 2019-07-16 Jan Beulich <jbeulich@suse.com> * opcode/i386.h (POP_SEG386_SHORT): New. diff --git a/include/ctf-api.h b/include/ctf-api.h index 3acbc91..1a0d47e 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -160,7 +160,7 @@ enum ECTF_NAMELEN, /* Buffer is too small to hold type name. */ ECTF_NOTYPE, /* No type found corresponding to name. */ ECTF_SYNTAX, /* Syntax error in type name. */ - ECTF_NOTFUNC, /* Symtab entry does not refer to a function. */ + ECTF_NOTFUNC, /* Symbol entry or type is not a function. */ ECTF_NOFUNCDAT, /* No func info available for function. */ ECTF_NOTDATA, /* Symtab entry does not refer to a data obj. */ ECTF_NOTYPEDAT, /* No type info available for object. */ @@ -277,6 +277,8 @@ extern int ctf_version (int); extern int ctf_func_info (ctf_file_t *, unsigned long, ctf_funcinfo_t *); extern int ctf_func_args (ctf_file_t *, unsigned long, uint32_t, ctf_id_t *); +extern int ctf_func_type_info (ctf_file_t *, ctf_id_t, ctf_funcinfo_t *); +extern int ctf_func_type_args (ctf_file_t *, ctf_id_t, uint32_t, ctf_id_t *); extern ctf_id_t ctf_lookup_by_name (ctf_file_t *, const char *); extern ctf_id_t ctf_lookup_by_symbol (ctf_file_t *, unsigned long); @@ -284,6 +286,7 @@ extern ctf_id_t ctf_lookup_variable (ctf_file_t *, const char *); extern ctf_id_t ctf_type_resolve (ctf_file_t *, ctf_id_t); extern char *ctf_type_aname (ctf_file_t *, ctf_id_t); +extern char *ctf_type_aname_raw (ctf_file_t *, ctf_id_t); extern ssize_t ctf_type_lname (ctf_file_t *, ctf_id_t, char *, size_t); extern char *ctf_type_name (ctf_file_t *, ctf_id_t, char *, size_t); extern ssize_t ctf_type_size (ctf_file_t *, ctf_id_t); diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 1770f99..4170762 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,11 @@ +2019-07-18 Nick Alcock <nick.alcock@oracle.com> + + * 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. + * ctf-lookup.c: Fix file description. + 2019-06-28 Nick Alcock <nick.alcock@oracle.com> * ctf-create.c (ctf_create): Fix off-by-one error. diff --git a/libctf/ctf-error.c b/libctf/ctf-error.c index af3a6c7..660a30a 100644 --- a/libctf/ctf-error.c +++ b/libctf/ctf-error.c @@ -48,7 +48,7 @@ static const char *const _ctf_errlist[] = { "Input buffer is too small for type name", /* ECTF_NAMELEN */ "No type information available for that name", /* ECTF_NOTYPE */ "Syntax error in type name", /* ECTF_SYNTAX */ - "Symbol table entry is not a function", /* ECTF_NOTFUNC */ + "Symbol table entry or type is not a function", /* ECTF_NOTFUNC */ "No function information available for symbol", /* ECTF_NOFUNCDAT */ "Symbol table entry is not a data object", /* ECTF_NOTDATA */ "No type information available for symbol", /* ECTF_NOTYPEDAT */ diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c index 4089ad9..40eaf9c 100644 --- a/libctf/ctf-lookup.c +++ b/libctf/ctf-lookup.c @@ -1,4 +1,4 @@ -/* Type lookup. +/* Symbol, variable and name lookup. Copyright (C) 2019 Free Software Foundation, Inc. This file is part of libctf. diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index dc158e2..5068ff1 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -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 |