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