diff options
author | Brian Feldman <green@FreeBSD.org> | 2001-10-30 15:54:09 +0000 |
---|---|---|
committer | Brian Feldman <green@FreeBSD.org> | 2001-10-30 15:54:09 +0000 |
commit | 3fc980b13595d56a312a2a0c752f76902a72b2f7 (patch) | |
tree | 3af54369ee3af34acc584ccf59baf1a0dc95e078 /usr.bin/gprof/kernel.c | |
parent | a296c021c2ebee992e76d036d2c3f699588d4a7b (diff) |
Add -K support to gprof(1), which enables dynamic symbol resolution from
the currently-running kernel (and supercedes an executable file argument
given). With this change, properly-compiled KLD modules are now
able to be profiled.
Obtained from: NAI Labs CBOSS project
Funded by: DARPA
Notes
Notes:
svn path=/head/; revision=85739
Diffstat (limited to 'usr.bin/gprof/kernel.c')
-rw-r--r-- | usr.bin/gprof/kernel.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/usr.bin/gprof/kernel.c b/usr.bin/gprof/kernel.c new file mode 100644 index 000000000000..c8df0d0a5c31 --- /dev/null +++ b/usr.bin/gprof/kernel.c @@ -0,0 +1,64 @@ +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/linker.h> +#include <sys/sysctl.h> +#include <sys/errno.h> + +#include <err.h> +#include <stdlib.h> + +#include "gprof.h" + +/* Things which get -E excluded by default. */ +static char *excludes[] = { ".mcount", "_mcleanup", NULL }; + +int +kernel_getnfile(const char *unused, char ***defaultEs) +{ + char *namelist; + size_t len; + char *name; + + if (sysctlbyname("kern.function_list", NULL, &len, NULL, 0) == -1) + err(1, "sysctlbyname: function_list size"); + for (;;) { + namelist = malloc(len); + if (namelist == NULL) + err(1, "malloc"); + if (sysctlbyname("kern.function_list", namelist, &len, NULL, + 0) == 0) + break; + if (errno == ENOMEM) + free(namelist); + else + err(1, "sysctlbyname: function_list"); + } + nname = 0; + for (name = namelist; *name != '\0'; name += strlen(name) + 1) + nname++; + /* Allocate memory for them, plus a terminating entry. */ + if ((nl = (nltype *)calloc(nname + 1, sizeof(nltype))) == NULL) + errx(1, "Insufficient memory for symbol table"); + npe = nl; + for (name = namelist; *name != '\0'; name += strlen(name) + 1) { + struct kld_sym_lookup ksl; + + ksl.version = sizeof(ksl); + ksl.symname = name; + if (kldsym(0, KLDSYM_LOOKUP, &ksl)) + err(1, "kldsym(%s)", name); + /* aflag not supported */ + if (uflag && strchr(name, '.') != NULL) + continue; + npe->value = ksl.symvalue; + npe->name = name; + npe++; + } + npe->value = -1; + + *defaultEs = excludes; +} |