This is all "#if defined(__i386__) && __GNUC__ >= 2":

Add support for GCC's --test-coverage --profile-arcs options.

Add code to call the functions listed in the .ctors section, these are
used to string the per .o file counter blocks into a linked list.

Add empty __bb_fork_func() to cope with GCC magic gandling of exec*()
named functions.

To add support for other platforms should be trivial, but involves
determining the exact data-types gcc uses on that platform.
This commit is contained in:
Poul-Henning Kamp 2003-01-06 07:40:49 +00:00
parent 12ebd46e4b
commit 578c478621
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=108779

View file

@ -157,6 +157,7 @@ kmstartup(dummy)
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 +532,49 @@ addupc_task(ke, pc, ticks)
}
stopprofclock(p);
}
#if defined(__i386__) && __GNUC__ >= 2
/*
* Support for "--test-coverage --profile-arcs" in GCC.
*
* We need to call all the functions in the .ctor section, in order
* to get all the counter-arrays strung into a list.
*
* XXX: the .ctors call __bb_init_func which is located in over in
* XXX: i386/i386/support.s for historical reasons. There is probably
* XXX: no reason for that to be assembler anymore, but doing it right
* XXX: in MI C code requires one to reverse-engineer the type-selection
* XXX: inside GCC. Have fun.
*
* XXX: Worrisome perspective: Calling the .ctors may make C++ in the
* XXX: kernel feasible. Don't.
*/
typedef void (*ctor_t)(void);
extern ctor_t _start_ctors, _stop_ctors;
static void
tcov_init(void *foo __unused)
{
ctor_t *p, q;
for (p = &_start_ctors; p < &_stop_ctors; p++) {
q = *p;
q();
}
}
SYSINIT(kmem, SI_SUB_KPROF, SI_ORDER_SECOND, tcov_init, NULL)
/*
* GCC contains magic to recognize calls to for instance execve() and
* puts in calls to this function to preserve the profile counters.
* XXX: Put zinging punchline here.
*/
void __bb_fork_func(void);
void
__bb_fork_func(void)
{
}
#endif