#include typedef struct { long low; long high; long nbytes; } header; typedef struct { unsigned long from; unsigned long to; unsigned long count; } MTABE; typedef struct MTAB { MTABE calls[341]; struct MTAB *prev; } MTAB; static header h; short *histogram asm("mcount_histogram"); short mcount_skip asm("mcount_skip"); static int histlen; static MTAB *mtab=0; void mcount(_to) { MTAB *m; int i; int to; int ebp; int from; int mtabi; MTABE **cache; mcount_skip = 1; asm("movl %%edx,%0" : "=g" (cache)); to = *((&_to)-1) - 13; ebp = *((&_to)-2); from = ((int *)ebp)[1]; if (*cache && ((*cache)->from == from) && ((*cache)->to == to)) { (*cache)->count++; mcount_skip = 0; return; } mtabi = -1; for (m=mtab; m; m=m->prev) { for (i=0; i<341; i++) { if (m->calls[i].from == 0) { mtabi = i; break; } if ((m->calls[i].from == from) && (m->calls[i].to == to)) { m->calls[i].count ++; *cache = m->calls + i; mcount_skip = 0; return; } } } if (mtabi != -1) { mtab->calls[mtabi].from = from; mtab->calls[mtabi].to = to; mtab->calls[mtabi].count = 1; *cache = mtab->calls + mtabi; mcount_skip = 0; return; } m = (MTAB *)sbrk(sizeof(MTAB)); m->prev = mtab; mtab = m; memset(m, 0, sizeof(MTAB)); m->calls[0].from = from; m->calls[0].to = to; m->calls[0].count = 1; *cache = m->calls; mcount_skip = 0; } extern int etext; extern void mcount_isr_init() asm("mcount_isr_init"); extern void mcount_init() asm("mcount_init"); void mcount_init() { int hs; h.low = 0x1020; h.high = (int)&etext; histlen = (h.high-h.low)/4*sizeof(short); h.nbytes = sizeof(header) + histlen; histogram = (short *)sbrk(histlen); memset(histogram, 0, histlen); mcount_isr_init(); } extern void mcount_write() asm("mcount_write"); void mcount_write() { MTAB *m; int i, f; f = open("gmon.out", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); write(f, &h, sizeof(header)); write(f, histogram, histlen); for (m=mtab; m; m=m->prev) { for (i=0; i<341; i++) if (m->calls[i].from == 0) break; write(f, m->calls, i*12); } close(f); }