1 /* subr_prof.c 4.1 82/06/28 */ 2 3 #ifdef GPROF 4 #include "../h/crt0.h" 5 #include "../h/param.h" 6 #include "../h/systm.h" 7 8 /* 9 * Froms is actually a bunch of unsigned shorts indexing tos 10 */ 11 int profiling = 3; 12 u_short *froms = 0; 13 struct tostruct *tos = 0; 14 u_short tolimit = 0; 15 char *s_lowpc = (char *)0x80000000; 16 extern char etext; 17 char *s_highpc = &etext; 18 u_long s_textsize = 0; 19 int ssiz; 20 u_short *sbuf; 21 u_short *kcount; 22 23 kmstartup() 24 { 25 u_long limit; 26 27 s_textsize = s_highpc - s_lowpc; 28 ssiz = s_textsize + sizeof(struct phdr); 29 printf("Profiling kernel, s_textsize=%d [%x..%x]\n", 30 s_textsize, s_lowpc, s_highpc); 31 sbuf = (u_short *)wmemall(vmemall, ssiz); 32 if (sbuf == 0) { 33 printf("No space for monitor buffer(s)\n"); 34 return; 35 } 36 blkclr((caddr_t)sbuf, ssiz); 37 froms = (u_short *)wmemall(vmemall, s_textsize); 38 if (froms == 0) { 39 printf("No space for monitor buffer(s)\n"); 40 wmemfree(sbuf, ssiz); 41 sbuf = 0; 42 return; 43 } 44 blkclr((caddr_t)froms, s_textsize); 45 tos = (struct tostruct *)wmemall(vmemall, s_textsize); 46 if (tos == 0) { 47 printf("No space for monitor buffer(s)\n"); 48 wmemfree(sbuf, ssiz); 49 sbuf = 0; 50 wmemfree(froms, s_textsize); 51 froms = 0; 52 return; 53 } 54 blkclr((caddr_t)tos, s_textsize); 55 tos[0].link = 0; 56 limit = s_textsize / sizeof(struct tostruct); 57 /* 58 * Tolimit is what mcount checks to see if 59 * all the data structures are ready!!! 60 * Make sure it won't overflow. 61 */ 62 tolimit = limit > 65534 ? 65534 : limit; 63 ((struct phdr *)sbuf)->lpc = s_lowpc; 64 ((struct phdr *)sbuf)->hpc = s_highpc; 65 ((struct phdr *)sbuf)->ncnt = ssiz; 66 kcount = (u_short *)(((int)sbuf) + sizeof(struct phdr)); 67 #ifdef notdef 68 profiling = 0; /* patch by hand when you're ready */ 69 #endif 70 } 71 72 /* 73 * This routine is massaged so that it may be jsb'ed to 74 */ 75 asm("#define _mcount mcount"); 76 mcount() 77 { 78 register char *selfpc; /* r11 */ 79 register u_short *frompcindex; /* r10 */ 80 register struct tostruct *top; /* r9 */ 81 82 asm(" forgot to run ex script on gcrt0.s"); 83 asm("#define r11 r5"); 84 asm("#define r10 r4"); 85 asm("#define r9 r3"); 86 #ifdef lint 87 selfpc = (char *) 0; 88 frompcindex = 0; 89 #else not lint 90 /* 91 * Find the return address for mcount, 92 * and the return address for mcount's caller. 93 */ 94 asm(" movl (sp), r11"); /* selfpc = ... (jsb frame) */ 95 asm(" movl 16(fp), r10"); /* frompcindex = (calls frame) */ 96 #endif not lint 97 /* 98 * Check that we are profiling 99 * and that we aren't recursively invoked. 100 */ 101 if (tolimit == 0) 102 goto out; 103 if (profiling) 104 goto out; 105 profiling++; 106 /* 107 * Check that frompcindex is a reasonable pc value. 108 * For example: signal catchers get called from the stack, 109 * not from text space. too bad. 110 */ 111 frompcindex = (u_short *)((long)frompcindex - (long)s_lowpc); 112 if ((u_long)frompcindex > s_textsize) 113 goto done; 114 frompcindex = &froms[((long)frompcindex) >> 1]; 115 if (*frompcindex != 0) 116 top = &tos[*frompcindex]; 117 else { 118 *frompcindex = ++tos[0].link; 119 if (*frompcindex >= tolimit) 120 goto overflow; 121 top = &tos[*frompcindex]; 122 top->selfpc = selfpc; 123 top->count = 0; 124 top->link = 0; 125 } 126 for (; /* break */; top = &tos[top->link]) { 127 if (top->selfpc == selfpc) { 128 top->count++; 129 break; 130 } 131 if (top->link != 0) 132 continue; 133 top->link = ++tos[0].link; 134 if (top->link >= tolimit) 135 goto overflow; 136 top = &tos[top->link]; 137 top->selfpc = selfpc; 138 top->count = 1; 139 top->link = 0; 140 break; 141 } 142 done: 143 profiling--; 144 /* and fall through */ 145 out: 146 asm(" rsb"); 147 asm("#undef r11"); 148 asm("#undef r10"); 149 asm("#undef r9"); 150 asm("#undef _mcount"); 151 152 overflow: 153 tolimit = 0; 154 printf("mcount: tos overflow\n"); 155 goto out; 156 } 157 #endif GPROF 158