(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)

Reply via email to