diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/ctfdump/ctfdump.c | 80 |
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 |