aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog7
-rw-r--r--include/ctf-api.h5
-rw-r--r--libctf/ChangeLog8
-rw-r--r--libctf/ctf-error.c2
-rw-r--r--libctf/ctf-lookup.c2
-rw-r--r--libctf/ctf-types.c85
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