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 #include <string.h> 12 13 #include "gprof.h" 14 15 /* Things which get -E excluded by default. */ 16 static char *excludes[] = { ".mcount", "_mcleanup", NULL }; 17 18 int 19 kernel_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