summaryrefslogtreecommitdiffstats
path: root/usr.bin/gprof/kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/gprof/kernel.c')
-rw-r--r--usr.bin/gprof/kernel.c64
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 0000000..c8df0d0
--- /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;
+}
OpenPOWER on IntegriCloud