xref: /freebsd/usr.bin/gprof/kernel.c (revision af2637db52bc5520a60ae6cb276c792a5ebe8073)
1e026a48cSDavid E. O'Brien #include <sys/cdefs.h>
2e026a48cSDavid E. O'Brien __FBSDID("$FreeBSD$");
33fc980b1SBrian Feldman 
43fc980b1SBrian Feldman #include <sys/param.h>
53fc980b1SBrian Feldman #include <sys/linker.h>
63fc980b1SBrian Feldman #include <sys/sysctl.h>
73fc980b1SBrian Feldman #include <sys/errno.h>
83fc980b1SBrian Feldman 
93fc980b1SBrian Feldman #include <err.h>
103fc980b1SBrian Feldman #include <stdlib.h>
118b061e14SStefan Farfeleder #include <string.h>
123fc980b1SBrian Feldman 
133fc980b1SBrian Feldman #include "gprof.h"
143fc980b1SBrian Feldman 
153fc980b1SBrian Feldman /* Things which get -E excluded by default. */
163fc980b1SBrian Feldman static char	*excludes[] = { ".mcount", "_mcleanup", NULL };
173fc980b1SBrian Feldman 
183fc980b1SBrian Feldman int
19*af2637dbSPhilippe Charnier kernel_getnfile(const char *unused __unused, char ***defaultEs)
203fc980b1SBrian Feldman {
213fc980b1SBrian Feldman 	char *namelist;
223fc980b1SBrian Feldman 	size_t len;
233fc980b1SBrian Feldman 	char *name;
243fc980b1SBrian Feldman 
253fc980b1SBrian Feldman 	if (sysctlbyname("kern.function_list", NULL, &len, NULL, 0) == -1)
263fc980b1SBrian Feldman 		err(1, "sysctlbyname: function_list size");
273fc980b1SBrian Feldman 	for (;;) {
283fc980b1SBrian Feldman 		namelist = malloc(len);
293fc980b1SBrian Feldman 		if (namelist == NULL)
303fc980b1SBrian Feldman 			err(1, "malloc");
313fc980b1SBrian Feldman 		if (sysctlbyname("kern.function_list", namelist, &len, NULL,
323fc980b1SBrian Feldman 		   0) == 0)
333fc980b1SBrian Feldman 			break;
343fc980b1SBrian Feldman 		if (errno == ENOMEM)
353fc980b1SBrian Feldman 			free(namelist);
363fc980b1SBrian Feldman 		else
373fc980b1SBrian Feldman 			err(1, "sysctlbyname: function_list");
383fc980b1SBrian Feldman 	}
393fc980b1SBrian Feldman 	nname = 0;
403fc980b1SBrian Feldman 	for (name = namelist; *name != '\0'; name += strlen(name) + 1)
413fc980b1SBrian Feldman 		nname++;
423fc980b1SBrian Feldman 	/* Allocate memory for them, plus a terminating entry. */
433fc980b1SBrian Feldman 	if ((nl = (nltype *)calloc(nname + 1, sizeof(nltype))) == NULL)
443fc980b1SBrian Feldman 		errx(1, "Insufficient memory for symbol table");
453fc980b1SBrian Feldman 	npe = nl;
463fc980b1SBrian Feldman 	for (name = namelist; *name != '\0'; name += strlen(name) + 1) {
473fc980b1SBrian Feldman 		struct kld_sym_lookup ksl;
483fc980b1SBrian Feldman 
493fc980b1SBrian Feldman 		ksl.version = sizeof(ksl);
503fc980b1SBrian Feldman 		ksl.symname = name;
513fc980b1SBrian Feldman 		if (kldsym(0, KLDSYM_LOOKUP, &ksl))
523fc980b1SBrian Feldman 			err(1, "kldsym(%s)", name);
533fc980b1SBrian Feldman 		/* aflag not supported */
543fc980b1SBrian Feldman 		if (uflag && strchr(name, '.') != NULL)
553fc980b1SBrian Feldman 			continue;
563fc980b1SBrian Feldman 		npe->value = ksl.symvalue;
573fc980b1SBrian Feldman 		npe->name = name;
583fc980b1SBrian Feldman 		npe++;
593fc980b1SBrian Feldman 	}
603fc980b1SBrian Feldman 	npe->value = -1;
613fc980b1SBrian Feldman 
623fc980b1SBrian Feldman 	*defaultEs = excludes;
6358f45f54SBrian Feldman 	return (0);
643fc980b1SBrian Feldman }
65