]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/db/print.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / db / print.c
1 /*
2  *
3  *      debugger
4  *
5  */
6 #include "defs.h"
7 #include "fns.h"
8
9 extern  int     infile;
10 extern  int     outfile;
11 extern  int     maxpos;
12
13 /* general printing routines ($) */
14
15 char    *Ipath = INCDIR;
16 static  int     tracetype;
17 static void     printfp(Map*, int);
18
19 /*
20  *      callback on stack trace
21  */
22 static void
23 ptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
24 {
25         char buf[512];
26
27         USED(map);
28         dprint("%s(", sym->name);
29         printparams(sym, sp);
30         dprint(") ");
31         printsource(sym->value);
32         dprint(" called from ");
33         symoff(buf, 512, pc, CTEXT);
34         dprint("%s ", buf);
35         printsource(pc);
36         dprint("\n");
37         if(tracetype == 'C')
38                 printlocals(sym, sp);
39 }
40
41 void
42 printtrace(int modif)
43 {
44         int i;
45         uvlong pc, sp, link;
46         ulong w;
47         BKPT *bk;
48         Symbol s;
49         int stack;
50         char *fname;
51         char buf[512];
52
53         if (cntflg==0)
54                 cntval = -1;
55         switch (modif) {
56
57         case '<':
58                 if (cntval == 0) {
59                         while (readchar() != EOR)
60                                 ;
61                         reread();
62                         break;
63                 }
64                 if (rdc() == '<')
65                         stack = 1;
66                 else {
67                         stack = 0;
68                         reread();
69                 }
70                 fname = getfname();
71                 redirin(stack, fname);
72                 break;
73
74         case '>':
75                 fname = getfname();
76                 redirout(fname);
77                 break;
78
79         case 'a':
80                 attachprocess();
81                 break;
82
83         case 'k':
84                 kmsys();
85                 break;
86
87         case 'q':
88         case 'Q':
89                 done();
90
91         case 'w':
92                 maxpos=(adrflg?adrval:MAXPOS);
93                 break;
94
95         case 'S':
96                 printsym();
97                 break;
98
99         case 's':
100                 maxoff=(adrflg?adrval:MAXOFF);
101                 break;
102
103         case 'm':
104                 printmap("? map", symmap);
105                 printmap("/ map", cormap);
106                 break;
107
108         case 0:
109         case '?':
110                 if (pid)
111                         dprint("pid = %d\n",pid);
112                 else
113                         prints("no process\n");
114                 flushbuf();
115
116         case 'r':
117         case 'R':
118                 printregs(modif);
119                 return;
120
121         case 'f':
122         case 'F':
123                 printfp(cormap, modif);
124                 return;
125
126         case 'c':
127         case 'C':
128                 tracetype = modif;
129                 if (machdata->ctrace) {
130                         if (adrflg) {
131                                 /*
132                                  * trace from jmpbuf for multi-threaded code.
133                                  * assume sp and pc are in adjacent locations
134                                  * and mach->szaddr in size.
135                                  */
136                                 if (geta(cormap, adrval, &sp) < 0 ||
137                                         geta(cormap, adrval+mach->szaddr, &pc) < 0)
138                                                 error("%r");
139                         } else {
140                                 sp = rget(cormap, mach->sp);
141                                 pc = rget(cormap, mach->pc);
142                         }
143                         if(mach->link)
144                                 link = rget(cormap, mach->link);
145                         else
146                                 link = 0;
147                         if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0)
148                                 error("no stack frame");
149                 }
150                 break;
151
152                 /*print externals*/
153         case 'e':
154                 for (i = 0; globalsym(&s, i); i++) {
155                         if (get4(cormap, s.value, &w) > 0)
156                                 dprint("%s/%12t%#lux\n", s.name, w);
157                 }
158                 break;
159
160                 /*print breakpoints*/
161         case 'b':
162         case 'B':
163                 for (bk=bkpthead; bk; bk=bk->nxtbkpt)
164                         if (bk->flag) {
165                                 symoff(buf, 512, (WORD)bk->loc, CTEXT);
166                                 dprint(buf);
167                                 if (bk->count != 1)
168                                         dprint(",%d", bk->count);
169                                 dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
170                         }
171                 break;
172
173         case 'M':
174                 fname = getfname();
175                 if (machbyname(fname) == 0)
176                         dprint("unknown name\n");;
177                 break;
178         default:
179                 error("bad `$' command");
180         }
181
182 }
183
184 char *
185 getfname(void)
186 {
187         static char fname[ARB];
188         char *p;
189
190         if (rdc() == EOR) {
191                 reread();
192                 return (0);
193         }
194         p = fname;
195         do {
196                 *p++ = lastc;
197                 if (p >= &fname[ARB-1])
198                         error("filename too long");
199         } while (rdc() != EOR);
200         *p = 0;
201         reread();
202         return (fname);
203 }
204
205 static void
206 printfp(Map *map, int modif)
207 {
208         Reglist *rp;
209         int i;
210         int ret;
211         char buf[512];
212
213         for (i = 0, rp = mach->reglist; rp->rname; rp += ret) {
214                 ret = 1;
215                 if (!(rp->rflags&RFLT))
216                         continue;
217                 ret = fpformat(map, rp, buf, sizeof(buf), modif);
218                 if (ret < 0) {
219                         werrstr("Register %s: %r", rp->rname);
220                         error("%r");
221                 }
222                         /* double column print */
223                 if (i&0x01)
224                         dprint("%40t%-8s%-12s\n", rp->rname, buf);
225                 else
226                         dprint("\t%-8s%-12s", rp->rname, buf);
227                 i++;
228         }
229 }
230
231 void
232 redirin(int stack, char *file)
233 {
234         char *pfile;
235
236         if (file == 0) {
237                 iclose(-1, 0);
238                 return;
239         }
240         iclose(stack, 0);
241         if ((infile = open(file, 0)) < 0) {
242                 pfile = smprint("%s/%s", Ipath, file);
243                 infile = open(pfile, 0);
244                 free(pfile);
245                 if(infile < 0) {
246                         infile = STDIN;
247                         error("cannot open");
248                 }
249         }
250 }
251
252 void
253 printmap(char *s, Map *map)
254 {
255         int i;
256
257         if (!map)
258                 return;
259         if (map == symmap)
260                 dprint("%s%12t`%s'\n", s, fsym < 0 ? "-" : symfil);
261         else if (map == cormap)
262                 dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil);
263         else
264                 dprint("%s\n", s);
265         for (i = 0; i < map->nsegs; i++) {
266                 if (map->seg[i].inuse)
267                         dprint("%s%8t%-16#llux %-16#llux %-16#llux\n",
268                                 map->seg[i].name, map->seg[i].b,
269                                 map->seg[i].e, map->seg[i].f);
270         }
271 }
272
273 /*
274  *      dump the raw symbol table
275  */
276 void
277 printsym(void)
278 {
279         int i;
280         Sym *sp;
281
282         for (i = 0; sp = getsym(i); i++) {
283                 switch(sp->type) {
284                 case 't':
285                 case 'l':
286                         dprint("%16#llux t %s\n", sp->value, sp->name);
287                         break;
288                 case 'T':
289                 case 'L':
290                         dprint("%16#llux T %s\n", sp->value, sp->name);
291                         break;
292                 case 'D':
293                 case 'd':
294                 case 'B':
295                 case 'b':
296                 case 'a':
297                 case 'p':
298                 case 'm':
299                         dprint("%16#llux %c %s\n", sp->value, sp->type, sp->name);
300                         break;
301                 default:
302                         break;
303                 }
304         }
305 }
306
307 #define STRINGSZ        128
308
309 /*
310  *      print the value of dot as file:line
311  */
312 void
313 printsource(ADDR dot)
314 {
315         char str[STRINGSZ];
316
317         if (fileline(str, STRINGSZ, dot))
318                 dprint("%s", str);
319 }
320
321 void
322 printpc(void)
323 {
324         char buf[512];
325
326         dot = rget(cormap, mach->pc);
327         if(dot){
328                 printsource((long)dot);
329                 printc(' ');
330                 symoff(buf, sizeof(buf), (long)dot, CTEXT);
331                 dprint("%s/", buf);
332                 if (machdata->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
333                         error("%r");
334                 dprint("%16t%s\n", buf);
335         }
336 }
337
338 void
339 printlocals(Symbol *fn, ADDR fp)
340 {
341         int i;
342         ulong w;
343         Symbol s;
344
345         s = *fn;
346         for (i = 0; localsym(&s, i); i++) {
347                 if (s.class != CAUTO)
348                         continue;
349                 if (get4(cormap, fp-s.value, &w) > 0)
350                         dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, w);
351                 else
352                         dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
353         }
354 }
355
356 void
357 printparams(Symbol *fn, ADDR fp)
358 {
359         int i;
360         Symbol s;
361         ulong w;
362         int first = 0;
363
364         fp += mach->szaddr;                     /* skip saved pc */
365         s = *fn;
366         for (i = 0; localsym(&s, i); i++) {
367                 if (s.class != CPARAM)
368                         continue;
369                 if (first++)
370                         dprint(", ");
371                 if (get4(cormap, fp+s.value, &w) > 0)
372                         dprint("%s=%#lux", s.name, w);
373         }
374 }