6 typedef struct Data Data;
8 typedef struct Acc Acc;
46 void graph(int, ulong, Pc*);
53 main(int argc, char *argv[])
57 s = getenv("tabstop");
58 if(s!=nil && strtol(s,0,0)>0)
59 tabstop = strtol(s,0,0);
71 fprint(2, "usage: prof [-dr] [8.out] [prof.out]\n");
74 Binit(&bout, 1, OWRITE);
85 graph(0, data[0].down, 0);
95 dp->down = beswab(dp->down);
96 dp->right = beswab(dp->right);
97 dp->pc = beswal(dp->pc);
98 dp->count = beswal(dp->count);
99 dp->time = beswal(dp->time);
103 acmp(void *va, void *vb)
126 if((fd = open(cout, 0)) < 0){
130 if (!crackhdr(fd, &f)) {
131 fprint(2, "can't read text file header\n");
134 if (f.type == FNONE) {
135 fprint(2, "text file not an a.out\n");
138 if (syminit(fd, &f) < 0) {
139 fprint(2, "syminit: %r\n");
152 if((fd = open(dout, 0)) < 0){
161 ndata = d->length/sizeof(data[0]);
162 data = malloc(ndata*sizeof(Data));
164 fprint(2, "prof: can't malloc data\n");
165 exits("data malloc");
167 if(read(fd, data, d->length) != d->length){
168 fprint(2, "prof: can't read data file\n");
173 for (i = 0; i < ndata; i++)
183 if (findsym(pc, CTEXT, &s))
185 snprint(buf, sizeof(buf), "#%lux", pc);
190 graph(int ind, ulong i, Pc *pc)
192 long time, count, prgm;
196 fprint(2, "prof: index out of range %ld [max %ld]\n", i, ndata);
199 count = data[i].count;
203 time += data[0].time;
204 if(data[i].right != 0xFFFF)
205 graph(ind, data[i].right, pc);
208 Bprint(&bout, "%s:%lud\n", name(prgm), time);
210 Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);
211 if(data[i].down == 0xFFFF)
219 Bprint(&bout, "...\n");
225 graph(ind+1, data[i].down, &lpc);
228 * assume acc is ordered by increasing text address.
237 for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
238 if (pc < acc[mid].pc)
241 if (mid != nsym-1 && pc >= acc[mid+1].pc)
257 fprint(2, "prof: index out of range %ld [max %ld]\n", i, ndata);
260 j = symind(data[i].pc);
263 time += data[0].time;
265 for(k = 0; k < indent; k++)
267 print("%lud: %ld/%lud", i, data[i].time, data[i].count);
269 print(" %s\n", acc[j].name);
271 print(" 0x%lux\n", data[i].pc);
274 if(data[i].down != 0xFFFF){
276 dtime = sum(data[i].down);
279 j = symind(data[i].pc);
281 acc[j].ms += time - dtime;
283 acc[j].calls += data[i].count;
285 if(data[i].right == 0xFFFF)
287 return time + sum(data[i].right);
295 for (nsym = 0; textsym(&s, nsym); nsym++) {
296 acc = realloc(acc, (nsym+1)*sizeof(Acc));
298 fprint(2, "prof: malloc fail\n");
301 acc[nsym].name = s.name;
302 acc[nsym].pc = s.value;
303 acc[nsym].calls = acc[nsym].ms = 0;
306 qsort(acc, nsym, sizeof(Acc), acmp);
307 Bprint(&bout, " %% Time Calls Name\n");
310 while (--nsym >= 0) {
312 Bprint(&bout, "%4.1f %8.3f %8lud\t%s\n",
313 (100.0*acc[nsym].ms)/ms,
327 Bwrite(&bout, ".\t", 2);
331 Bwrite(&bout, ". ", j);
354 p = getenv("objtype");
356 for(i=0; trans[i]; i+=2)
357 if(strcmp(p, trans[i]) == 0)