summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/ctfdump/ctfdump.c80
1 files changed, 77 insertions, 3 deletions
diff --git a/usr/src/cmd/ctfdump/ctfdump.c b/usr/src/cmd/ctfdump/ctfdump.c
index a2e668d266..d54b50c6e7 100644
--- a/usr/src/cmd/ctfdump/ctfdump.c
+++ b/usr/src/cmd/ctfdump/ctfdump.c
@@ -121,7 +121,7 @@ ctfdump_printf(ctfdump_arg_t arg, const char *fmt, ...)
va_end(ap);
}
-static void
+static void __NORETURN
ctfdump_fatal(const char *fmt, ...)
{
va_list ap;
@@ -987,8 +987,82 @@ ctfsrc_function(ctf_idname_t *idn)
static int
idname_compare(const void *lhs, const void *rhs)
{
- return (strcmp(((ctf_idname_t *)lhs)->ci_name,
- ((ctf_idname_t *)rhs)->ci_name));
+ int ret;
+ char lname[MAX_NAMELEN] = {0};
+ char rname[MAX_NAMELEN] = {0};
+ const ctf_idname_t *l = lhs;
+ const ctf_idname_t *r = rhs;
+ uint_t arity = 0;
+
+ if ((ret = strcmp(l->ci_name, r->ci_name)) != 0)
+ return (ret);
+
+ /* If the names match, try arity */
+ if (l->ci_funcinfo.ctc_argc < r->ci_funcinfo.ctc_argc)
+ return (-1);
+ else if (l->ci_funcinfo.ctc_argc > r->ci_funcinfo.ctc_argc)
+ return (1);
+ else
+ arity = l->ci_funcinfo.ctc_argc;
+
+ /* If arity doesn't help, try return type */
+ (void) strlcpy(lname, "unknown_t", sizeof (lname));
+ (void) strlcpy(rname, "unknown_t", sizeof (rname));
+ (void) ctf_type_name(g_fp, l->ci_funcinfo.ctc_return, lname,
+ sizeof (lname));
+ (void) ctf_type_name(g_fp, r->ci_funcinfo.ctc_return, rname,
+ sizeof (rname));
+
+ if ((ret = strcmp(lname, rname)) != 0)
+ return (ret);
+
+ /* if return type doesn't help, try parameter types */
+ if (arity == 0)
+ return (0);
+
+ ctf_id_t *largs = calloc(arity, sizeof (ctf_id_t));
+ ctf_id_t *rargs = calloc(arity, sizeof (ctf_id_t));
+
+ if ((largs == NULL) || (rargs == NULL)) {
+ free(rargs);
+ free(largs);
+ ctfdump_fatal("failed to alloc argument ids for sorting: "
+ " %s\n", strerror(errno));
+ }
+
+ if (ctf_func_args(g_fp, l->ci_symidx, arity, largs) == CTF_ERR) {
+ free(rargs);
+ free(largs);
+ ctfdump_fatal("failed to get arguments for function "
+ "%s: %s\n", l->ci_name,
+ ctf_errmsg(ctf_errno(g_fp)));
+ }
+
+ if (ctf_func_args(g_fp, r->ci_symidx, arity, rargs) == CTF_ERR) {
+ free(rargs);
+ free(largs);
+ ctfdump_fatal("failed to get arguments for function "
+ "%s: %s\n", r->ci_name,
+ ctf_errmsg(ctf_errno(g_fp)));
+ }
+
+ for (uint_t i = 0; i < arity; i++) {
+ (void) strlcpy(lname, "unknown_t", sizeof (lname));
+ (void) ctf_type_name(g_fp, largs[i], lname, sizeof (lname));
+
+ (void) strlcpy(rname, "unknown_t", sizeof (rname));
+ (void) ctf_type_name(g_fp, rargs[i], rname, sizeof (rname));
+
+ if ((ret = strcmp(lname, rname)) != 0) {
+ free(rargs);
+ free(largs);
+ return (ret);
+ }
+ }
+
+ free(rargs);
+ free(largs);
+ return (0);
}
static void