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