/* subr_prof.c 6.1 83/07/29 */
/* last integrated from: gmon.c 4.10 (Berkeley) 1/14/83 */
* Froms is actually a bunch of unsigned shorts indexing tos
struct tostruct
*tos
= 0;
char *s_lowpc
= (char *)0x80000000;
u_long 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.
ROUNDDOWN((unsigned)s_lowpc
, HISTFRACTION
*sizeof(HISTCOUNTER
));
ROUNDUP((unsigned)s_highpc
, HISTFRACTION
*sizeof(HISTCOUNTER
));
s_textsize
= s_highpc
- s_lowpc
;
printf("Profiling kernel, s_textsize=%d [%x..%x]\n",
s_textsize
, s_lowpc
, s_highpc
);
ssiz
= (s_textsize
/ HISTFRACTION
) + sizeof(struct phdr
);
sbuf
= (u_short
*)wmemall(memall
, ssiz
);
printf("No space for monitor buffer(s)\n");
blkclr((caddr_t
)sbuf
, ssiz
);
fromssize
= s_textsize
/ HASHFRACTION
;
froms
= (u_short
*)wmemall(memall
, fromssize
);
printf("No space for monitor buffer(s)\n");
blkclr((caddr_t
)froms
, fromssize
);
tolimit
= s_textsize
* ARCDENSITY
/ 100;
} else if (tolimit
> 65534) {
tossize
= tolimit
* sizeof(struct tostruct
);
tos
= (struct tostruct
*)wmemall(memall
, tossize
);
printf("No space for monitor buffer(s)\n");
wmemfree(froms
, fromssize
);
blkclr((caddr_t
)tos
, tossize
);
((struct phdr
*)sbuf
)->lpc
= s_lowpc
;
((struct phdr
*)sbuf
)->hpc
= s_highpc
;
((struct phdr
*)sbuf
)->ncnt
= ssiz
;
kcount
= (u_short
*)(((int)sbuf
) + sizeof(struct phdr
));
* profiling is what mcount checks to see if
* all the data structures are ready!!!
profiling
= 0; /* patch by hand when you're ready */
* This routine is massaged so that it may be jsb'ed to
asm("#the beginning of mcount()");
register char *selfpc
; /* r11 => r5 */
register unsigned short *frompcindex
; /* r10 => r4 */
register struct tostruct
*top
; /* r9 => r3 */
register struct tostruct
*prevtop
; /* r8 => r2 */
register long toindex
; /* r7 => r1 */
* find the return address for mcount,
* and the return address for mcount's caller.
asm(" .text"); /* make sure we're in text space */
asm(" movl (sp), r11"); /* selfpc = ... (jsb frame) */
asm(" movl 16(fp), r10"); /* frompcindex = (calls frame) */
* check that we are profiling
* and that we aren't recursively invoked.
* check that frompcindex is a reasonable pc value.
* for example: signal catchers get called from the stack,
* not from text space. too bad.
frompcindex
= (unsigned short *)((long)frompcindex
- (long)s_lowpc
);
if ((unsigned long)frompcindex
> s_textsize
) {
&froms
[((long)frompcindex
) / (HASHFRACTION
* sizeof(*froms
))];
* first time traversing this arc
if (toindex
>= tolimit
) {
if (top
->selfpc
== selfpc
) {
* arc at front of chain; usual case.
* have to go looking down chain for it.
* top points to what we are looking at,
* prevtop points to previous top.
* we know it is not at the head of the chain.
for (; /* goto done */; ) {
* top is end of the chain and none of the chain
* had top->selfpc == selfpc.
* so we allocate a new tostruct
* and link it to the head of the chain.
if (toindex
>= tolimit
) {
top
->link
= *frompcindex
;
* otherwise, check the next arc on the chain.
if (top
->selfpc
== selfpc
) {
* move it to the head of the chain.
prevtop
->link
= top
->link
;
top
->link
= *frompcindex
;
printf("mcount: tos overflow\n");
asm("#the end of mcount()");