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