Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 05 Jan 2003 17:24:58 +0100
From:      Poul-Henning Kamp <phk@freebsd.org>
To:        current@freebsd.org
Subject:   Calling gcc created constructors in the kernel...
Message-ID:  <7797.1041783898@critter.freebsd.dk>

next in thread | raw e-mail | index | archive | help

I want to get --test-coverage and --profile-arcs working for the
kernel in order to give us better statistical tools.

Unfortunately, GCC now uses construcorts to string the counters into
a list, and we don't call constructors in the kernel.

Would it be evil to do that ?

I've managed to get it working with the following patch, a modified
version of kernbb(8) and the standard GCC::gcov binary.

Any objections to me committing this ?

Is there a better way to get the start and end of the .ctors section ?

Poul-Henning


Index: conf/ldscript.i386
===================================================================
RCS file: /home/ncvs/src/sys/conf/ldscript.i386,v
retrieving revision 1.6
diff -u -r1.6 ldscript.i386
--- conf/ldscript.i386	11 Oct 2002 19:38:04 -0000	1.6
+++ conf/ldscript.i386	5 Jan 2003 13:50:12 -0000
@@ -65,10 +65,14 @@
     CONSTRUCTORS
   }
   .data1   : { *(.data1) }
+  _start_ctors = .;
+  PROVIDE (start_ctors = .);
   .ctors         :
   {
     *(.ctors)
   }
+  _stop_ctors = .;
+  PROVIDE (stop_ctors = .);
   .dtors         :
   {
     *(.dtors)
Index: kern/subr_prof.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_prof.c,v
retrieving revision 1.55
diff -u -r1.55 subr_prof.c
--- kern/subr_prof.c	1 Oct 2002 13:15:11 -0000	1.55
+++ kern/subr_prof.c	5 Jan 2003 13:53:38 -0000
@@ -78,6 +78,7 @@
 }
 #endif /* GUPROF */
 
+
 /*
  * Update the histograms to support extending the text region arbitrarily.
  * This is done slightly naively (no sparse regions), so will waste slight
@@ -157,6 +158,7 @@
 	uintfptr_t tmp_addr;
 #endif
 
+	tcov_init();
 	/*
 	 * 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.
@@ -531,3 +533,24 @@
 	}
 	stopprofclock(p);
 }
+
+#if 1
+typedef void (*ctor_t)(void);
+extern ctor_t _start_ctors, _stop_ctors;
+
+static void
+tcov_init(void *foo __unused)
+{
+	ctor_t *p, q;
+
+	printf("_start_ctors %p %p\n", _start_ctors, &_start_ctors);
+	printf("_stop_ctors %p %p\n", _stop_ctors, &_stop_ctors);
+	for (p = &_start_ctors; p < &_stop_ctors; p++) {
+		printf(" ctor %p %p\n", p, *p);
+		q = *p;
+		q();
+	}
+}
+
+SYSINIT(kmem, SI_SUB_KPROF, SI_ORDER_SECOND, tcov_init, NULL)
+#endif

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk@FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7797.1041783898>