1#include <sys/cdefs.h>
2__FBSDID("$FreeBSD: releng/10.3/usr.bin/gprof/kernel.c 246783 2013-02-14 08:16:03Z charnier $");
3
4#include <sys/param.h>
5#include <sys/linker.h>
6#include <sys/sysctl.h>
7#include <sys/errno.h>
8
9#include <err.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "gprof.h"
14
15/* Things which get -E excluded by default. */
16static char	*excludes[] = { ".mcount", "_mcleanup", NULL };
17
18int
19kernel_getnfile(const char *unused __unused, char ***defaultEs)
20{
21	char *namelist;
22	size_t len;
23	char *name;
24
25	if (sysctlbyname("kern.function_list", NULL, &len, NULL, 0) == -1)
26		err(1, "sysctlbyname: function_list size");
27	for (;;) {
28		namelist = malloc(len);
29		if (namelist == NULL)
30			err(1, "malloc");
31		if (sysctlbyname("kern.function_list", namelist, &len, NULL,
32		   0) == 0)
33			break;
34		if (errno == ENOMEM)
35			free(namelist);
36		else
37			err(1, "sysctlbyname: function_list");
38	}
39	nname = 0;
40	for (name = namelist; *name != '\0'; name += strlen(name) + 1)
41		nname++;
42	/* Allocate memory for them, plus a terminating entry. */
43	if ((nl = (nltype *)calloc(nname + 1, sizeof(nltype))) == NULL)
44		errx(1, "Insufficient memory for symbol table");
45	npe = nl;
46	for (name = namelist; *name != '\0'; name += strlen(name) + 1) {
47		struct kld_sym_lookup ksl;
48
49		ksl.version = sizeof(ksl);
50		ksl.symname = name;
51		if (kldsym(0, KLDSYM_LOOKUP, &ksl))
52			err(1, "kldsym(%s)", name);
53		/* aflag not supported */
54		if (uflag && strchr(name, '.') != NULL)
55			continue;
56		npe->value = ksl.symvalue;
57		npe->name = name;
58		npe++;
59	}
60	npe->value = -1;
61
62	*defaultEs = excludes;
63	return (0);
64}
65