fix up header file dependencies
[unix-history] / usr / src / sys / kern / subr_prof.c
CommitLineData
3a3e0b91
SL
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 */
11int profiling = 3;
12u_short *froms = 0;
13struct tostruct *tos = 0;
14u_short tolimit = 0;
15char *s_lowpc = (char *)0x80000000;
16extern char etext;
17char *s_highpc = &etext;
18u_long s_textsize = 0;
19int ssiz;
20u_short *sbuf;
21u_short *kcount;
22
23kmstartup()
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 */
75asm("#define _mcount mcount");
76mcount()
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 }
142done:
143 profiling--;
144 /* and fall through */
145out:
146 asm(" rsb");
147 asm("#undef r11");
148 asm("#undef r10");
149 asm("#undef r9");
150 asm("#undef _mcount");
151
152overflow:
153 tolimit = 0;
154 printf("mcount: tos overflow\n");
155 goto out;
156}
157#endif GPROF