(update of http://marc.theaimsgroup.com/?l=openbsd-misc&m=115914181032738&w=2)
Polishing. --- /dev/null Mon Sep 25 16:30:26 2006 +++ sys/conf/gen_addr_etext Mon Sep 25 15:41:13 2006 @@ -0,0 +1,19 @@ +#!/bin/sh +f=addr_etext.h +l='#define ADDR_ETEXT \' +if [ $# = 0 ]; then + echo "$l" > $f + echo '((u_long)KERNBASE + (1<<16))' >> $f + exit 0 +fi +if [ $# = 1 ]; then + a="0x$(nm -gp "$1" | awk '/ etext$/{print $1}')UL" + [ -z "$a" ] && exit 2 + b=$(sed -n 2p < $f) + [ -z "$b" ] && exit 2 + [ x"$a" = x"$b" ] && exit 1 + echo "$l" > $f + echo "$a" >> $f + exit 0 +fi +exit 2 Index: sys/kern/init_main.c =================================================================== RCS file: /cvs/src/sys/kern/init_main.c,v retrieving revision 1.130 diff -u -r1.130 init_main.c --- sys/kern/init_main.c 6 May 2006 23:02:36 -0000 1.130 +++ sys/kern/init_main.c 25 Sep 2006 16:30:30 -0000 @@ -347,6 +347,9 @@ /* Start real time and statistics clocks. */ initclocks(); +#ifdef GPROF + startprofclock(&proc0); +#endif /* Lock the kernel on behalf of proc0. */ KERNEL_PROC_LOCK(p); @@ -385,11 +388,6 @@ domaininit(); if_attachdomain(); splx(s); - -#ifdef GPROF - /* Initialize kernel profiling. */ - kmstartup(); -#endif #if !defined(NO_PROPOLICE) { Index: sys/kern/subr_prof.c =================================================================== RCS file: /cvs/src/sys/kern/subr_prof.c,v retrieving revision 1.15 diff -u -r1.15 subr_prof.c --- sys/kern/subr_prof.c 9 Dec 2005 09:09:52 -0000 1.15 +++ sys/kern/subr_prof.c 25 Sep 2006 16:30:30 -0000 @@ -45,53 +45,40 @@ #ifdef GPROF #include <sys/malloc.h> #include <sys/gmon.h> -#include <uvm/uvm_extern.h> +#include "addr_etext.h" /* - * Froms is actually a bunch of unsigned shorts indexing tos + * Round lowpc and highpc to multiples of the density we're using + * so the rest of the scaling (here and in gprof) stays in ints. */ -struct gmonparam _gmonparam = { GMON_PROF_OFF }; - -extern char etext[]; - +#define LOWPC ROUNDDOWN((u_long)KERNBASE, HISTFRACTION * sizeof(HISTCOUNTER)) +#define HIGHPC ROUNDUP(ADDR_ETEXT, HISTFRACTION * sizeof(HISTCOUNTER)) +#define TEXTSIZE (HIGHPC - LOWPC) +#define KCOUNTSIZE (TEXTSIZE / HISTFRACTION) +#define FROMSSIZE (TEXTSIZE / HASHFRACTION) +#define TOLIM (TEXTSIZE * ARCDENSITY / 100) +#define TOLIMIT (TOLIM < MINARCS ? MINARCS : TOLIM > MAXARCS ? MAXARCS : TOLIM) +#define TOSSIZE (TOLIMIT * sizeof(struct tostruct)) -void -kmstartup(void) -{ - char *cp; - struct gmonparam *p = &_gmonparam; - int size; +static char buf[KCOUNTSIZE + FROMSSIZE + TOSSIZE]; - /* - * Round lowpc and highpc to multiples of the density we're using - * so the rest of the scaling (here and in gprof) stays in ints. - */ - p->lowpc = ROUNDDOWN(KERNBASE, HISTFRACTION * sizeof(HISTCOUNTER)); - p->highpc = ROUNDUP((u_long)etext, HISTFRACTION * sizeof(HISTCOUNTER)); - p->textsize = p->highpc - p->lowpc; - printf("Profiling kernel, textsize=%ld [%lx..%lx]\n", - p->textsize, p->lowpc, p->highpc); - p->kcountsize = p->textsize / HISTFRACTION; - p->hashfraction = HASHFRACTION; - p->fromssize = p->textsize / HASHFRACTION; - p->tolimit = p->textsize * ARCDENSITY / 100; - if (p->tolimit < MINARCS) - p->tolimit = MINARCS; - else if (p->tolimit > MAXARCS) - p->tolimit = MAXARCS; - p->tossize = p->tolimit * sizeof(struct tostruct); - size = p->kcountsize + p->fromssize + p->tossize; - cp = (char *)uvm_km_zalloc(kernel_map, round_page(size)); - if (cp == 0) { - printf("No memory for profiling.\n"); - return; - } - p->tos = (struct tostruct *)cp; - cp += p->tossize; - p->kcount = (u_short *)cp; - cp += p->kcountsize; - p->froms = (u_short *)cp; -} +/* + * Froms is actually a bunch of unsigned shorts indexing tos + */ +struct gmonparam _gmonparam = { + /* state = */ GMON_PROF_ON, + /* kcount = */ (u_short *)(buf + TOSSIZE), + KCOUNTSIZE, + /* froms = */ (u_short *)(buf + TOSSIZE + KCOUNTSIZE), + FROMSSIZE, + /* tos = */ (struct tostruct *)buf, + TOSSIZE, + TOLIMIT, + LOWPC, + HIGHPC, + TEXTSIZE, + HASHFRACTION +}; /* * Return kernel profiling information. Index: sys/sys/systm.h =================================================================== RCS file: /cvs/src/sys/sys/systm.h,v retrieving revision 1.69 diff -u -r1.69 systm.h --- sys/sys/systm.h 27 Apr 2006 02:17:21 -0000 1.69 +++ sys/sys/systm.h 25 Sep 2006 16:30:30 -0000 @@ -291,11 +291,6 @@ void cpu_configure(void); extern void (*md_diskconf)(void); - -#ifdef GPROF -void kmstartup(void); -#endif - int nfs_mountroot(void); int dk_mountroot(void); extern int (*mountroot)(void); Index: usr.sbin/config/config.h =================================================================== RCS file: /cvs/src/usr.sbin/config/config.h,v retrieving revision 1.22 diff -u -r1.22 config.h --- usr.sbin/config/config.h 27 Apr 2006 18:09:52 -0000 1.22 +++ usr.sbin/config/config.h 25 Sep 2006 16:30:32 -0000 @@ -299,6 +299,7 @@ struct devi *allpseudo; /* list of all pseudo-devices */ int ndevi; /* number of devi's (before packing) */ int npseudo; /* number of pseudo's */ +int need_addr_etext; /* whether to provide addr_etext.h */ struct files *allfiles; /* list of all kernel source files */ struct objects *allobjects; /* list of all kernel object and library files */ Index: usr.sbin/config/main.c =================================================================== RCS file: /cvs/src/usr.sbin/config/main.c,v retrieving revision 1.38 diff -u -r1.38 main.c --- usr.sbin/config/main.c 12 Nov 2005 15:40:09 -0000 1.38 +++ usr.sbin/config/main.c 25 Sep 2006 16:30:32 -0000 @@ -50,6 +50,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> +#include <sys/wait.h> #include <ctype.h> #include <errno.h> #include <stdio.h> @@ -79,6 +80,7 @@ static int hasparent(struct devi *); static int cfcrosscheck(struct config *, const char *, struct nvlist *); static void optiondelta(void); +static void gen_addr_etext(void); int madedir = 0; @@ -201,6 +203,7 @@ nextopt = &options; nextmkopt = &mkoptions; nextdefopt = &defoptions; + need_addr_etext = 0; /* * Handle profiling (must do this before we try to create any @@ -270,6 +273,8 @@ if (mksymlinks() || mkmakefile() || mkheaders() || mkswap() || mkioconf()) stop(); + if (need_addr_etext) + gen_addr_etext(); (void)printf("Don't forget to run \"make depend\"\n"); optiondelta(); exit(0); @@ -754,4 +759,32 @@ if (ret == 0 || madedir == 1) return; (void)printf("Kernel options have changed -- you must run \"make clean\"\n"); +} + +void +gen_addr_etext(void) +{ + pid_t pid; + int status; + size_t len; + char *buf; + + errno = 0; + if ((pid = fork()) == -1) + goto bad; + if (pid) { + if (waitpid(pid, &status, 0) == -1) + goto bad; + if (!WIFEXITED(status) || WEXITSTATUS(status)) + goto bad; + } else { + len = strlen(srcdir) + 30; + buf = emalloc(len); + snprintf(buf, len, "%s/conf/gen_addr_etext", srcdir); + execl("/bin/sh", "sh", "--", buf, 0); + goto bad; + } + return; +bad: + panic("gen_addr_etext: %s", strerror(errno)); } Index: usr.sbin/config/mkmakefile.c =================================================================== RCS file: /cvs/src/usr.sbin/config/mkmakefile.c,v retrieving revision 1.20 diff -u -r1.20 mkmakefile.c --- usr.sbin/config/mkmakefile.c 6 May 2006 11:31:46 -0000 1.20 +++ usr.sbin/config/mkmakefile.c 25 Sep 2006 16:30:32 -0000 @@ -177,6 +177,8 @@ return (1); sp = ""; for (nv = options; nv != NULL; nv = nv->nv_next) { + if (!strcmp(nv->nv_name, "GPROF")) + need_addr_etext = 1; if (ht_lookup(defopttab, nv->nv_name) != NULL) continue; if (fprintf(fp, "%s-D%s", sp, nv->nv_name) < 0) @@ -444,9 +446,15 @@ if (fprintf(fp, "\n" "\t${SYSTEM_LD_HEAD}\n" "\t${SYSTEM_LD} swap%s.o\n" - "\t${SYSTEM_LD_TAIL}\n" + "\t${SYSTEM_LD_TAIL}\n", swname) < 0) + return (1); + if (need_addr_etext && fputs( + "\tif sh $S/conf/gen_addr_etext $@; then make $@;" + " else [ $$? = 1 ]; fi\n", fp) < 0) + return (1); + if (fprintf(fp, "\n" - "swap%s.o: ", swname, swname) < 0) + "swap%s.o: ", swname) < 0) return (1); if (cf->cf_root != NULL) { if (fprintf(fp, "swap%s.c\n", nm) < 0)