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