1*9758Ssam /* subr_prof.c 4.3 82/12/17 */ 27332Ssam 37332Ssam #ifdef GPROF 47332Ssam #include "../h/crt0.h" 57332Ssam #include "../h/param.h" 67332Ssam #include "../h/systm.h" 77332Ssam 87332Ssam /* 97332Ssam * Froms is actually a bunch of unsigned shorts indexing tos 107332Ssam */ 117332Ssam int profiling = 3; 127332Ssam u_short *froms = 0; 137332Ssam struct tostruct *tos = 0; 147332Ssam u_short tolimit = 0; 15*9758Ssam #ifdef vax 167332Ssam char *s_lowpc = (char *)0x80000000; 17*9758Ssam #endif 18*9758Ssam #ifdef sun 19*9758Ssam char *s_lowpc = (char *)0x4000; 20*9758Ssam #endif 217332Ssam extern char etext; 227332Ssam char *s_highpc = &etext; 237332Ssam u_long s_textsize = 0; 247332Ssam int ssiz; 257332Ssam u_short *sbuf; 267332Ssam u_short *kcount; 277332Ssam 287332Ssam kmstartup() 297332Ssam { 307332Ssam u_long limit; 317332Ssam 327332Ssam s_textsize = s_highpc - s_lowpc; 337332Ssam ssiz = s_textsize + sizeof(struct phdr); 347332Ssam printf("Profiling kernel, s_textsize=%d [%x..%x]\n", 357332Ssam s_textsize, s_lowpc, s_highpc); 369161Ssam sbuf = (u_short *)wmemall(memall, ssiz); 377332Ssam if (sbuf == 0) { 387332Ssam printf("No space for monitor buffer(s)\n"); 397332Ssam return; 407332Ssam } 417332Ssam blkclr((caddr_t)sbuf, ssiz); 429161Ssam froms = (u_short *)wmemall(memall, s_textsize); 437332Ssam if (froms == 0) { 447332Ssam printf("No space for monitor buffer(s)\n"); 457332Ssam wmemfree(sbuf, ssiz); 467332Ssam sbuf = 0; 477332Ssam return; 487332Ssam } 497332Ssam blkclr((caddr_t)froms, s_textsize); 509161Ssam tos = (struct tostruct *)wmemall(memall, s_textsize); 517332Ssam if (tos == 0) { 527332Ssam printf("No space for monitor buffer(s)\n"); 537332Ssam wmemfree(sbuf, ssiz); 547332Ssam sbuf = 0; 557332Ssam wmemfree(froms, s_textsize); 567332Ssam froms = 0; 577332Ssam return; 587332Ssam } 597332Ssam blkclr((caddr_t)tos, s_textsize); 607332Ssam tos[0].link = 0; 617332Ssam limit = s_textsize / sizeof(struct tostruct); 627332Ssam /* 637332Ssam * Tolimit is what mcount checks to see if 647332Ssam * all the data structures are ready!!! 657332Ssam * Make sure it won't overflow. 667332Ssam */ 677332Ssam tolimit = limit > 65534 ? 65534 : limit; 687332Ssam ((struct phdr *)sbuf)->lpc = s_lowpc; 697332Ssam ((struct phdr *)sbuf)->hpc = s_highpc; 707332Ssam ((struct phdr *)sbuf)->ncnt = ssiz; 717332Ssam kcount = (u_short *)(((int)sbuf) + sizeof(struct phdr)); 727332Ssam #ifdef notdef 737332Ssam profiling = 0; /* patch by hand when you're ready */ 747332Ssam #endif 757332Ssam } 767332Ssam 77*9758Ssam #ifdef vax 787332Ssam /* 797332Ssam * This routine is massaged so that it may be jsb'ed to 807332Ssam */ 817332Ssam asm("#define _mcount mcount"); 827332Ssam mcount() 837332Ssam { 847332Ssam register char *selfpc; /* r11 */ 857332Ssam register u_short *frompcindex; /* r10 */ 867332Ssam register struct tostruct *top; /* r9 */ 877332Ssam 887332Ssam asm(" forgot to run ex script on gcrt0.s"); 897332Ssam asm("#define r11 r5"); 907332Ssam asm("#define r10 r4"); 917332Ssam asm("#define r9 r3"); 927332Ssam #ifdef lint 937332Ssam selfpc = (char *) 0; 947332Ssam frompcindex = 0; 957332Ssam #else not lint 967332Ssam /* 977332Ssam * Find the return address for mcount, 987332Ssam * and the return address for mcount's caller. 997332Ssam */ 1007332Ssam asm(" movl (sp), r11"); /* selfpc = ... (jsb frame) */ 1017332Ssam asm(" movl 16(fp), r10"); /* frompcindex = (calls frame) */ 1027332Ssam #endif not lint 1037332Ssam /* 1047332Ssam * Check that we are profiling 1057332Ssam * and that we aren't recursively invoked. 1067332Ssam */ 1077332Ssam if (tolimit == 0) 1087332Ssam goto out; 1097332Ssam if (profiling) 1107332Ssam goto out; 1117332Ssam profiling++; 1127332Ssam /* 1137332Ssam * Check that frompcindex is a reasonable pc value. 1147332Ssam * For example: signal catchers get called from the stack, 1157332Ssam * not from text space. too bad. 1167332Ssam */ 1177332Ssam frompcindex = (u_short *)((long)frompcindex - (long)s_lowpc); 1187332Ssam if ((u_long)frompcindex > s_textsize) 1197332Ssam goto done; 1207332Ssam frompcindex = &froms[((long)frompcindex) >> 1]; 1217332Ssam if (*frompcindex != 0) 1227332Ssam top = &tos[*frompcindex]; 1237332Ssam else { 1247332Ssam *frompcindex = ++tos[0].link; 1257332Ssam if (*frompcindex >= tolimit) 1267332Ssam goto overflow; 1277332Ssam top = &tos[*frompcindex]; 1287332Ssam top->selfpc = selfpc; 1297332Ssam top->count = 0; 1307332Ssam top->link = 0; 1317332Ssam } 1327332Ssam for (; /* break */; top = &tos[top->link]) { 1337332Ssam if (top->selfpc == selfpc) { 1347332Ssam top->count++; 1357332Ssam break; 1367332Ssam } 1377332Ssam if (top->link != 0) 1387332Ssam continue; 1397332Ssam top->link = ++tos[0].link; 1407332Ssam if (top->link >= tolimit) 1417332Ssam goto overflow; 1427332Ssam top = &tos[top->link]; 1437332Ssam top->selfpc = selfpc; 1447332Ssam top->count = 1; 1457332Ssam top->link = 0; 1467332Ssam break; 1477332Ssam } 1487332Ssam done: 1497332Ssam profiling--; 1507332Ssam /* and fall through */ 1517332Ssam out: 1527332Ssam asm(" rsb"); 1537332Ssam asm("#undef r11"); 1547332Ssam asm("#undef r10"); 1557332Ssam asm("#undef r9"); 1567332Ssam asm("#undef _mcount"); 1577332Ssam 1587332Ssam overflow: 1597332Ssam tolimit = 0; 1607332Ssam printf("mcount: tos overflow\n"); 1617332Ssam goto out; 1627332Ssam } 163*9758Ssam #endif 1647332Ssam #endif GPROF 165