Blob


1 /*
2 *
3 * debugger
4 *
5 */
6 #include "defs.h"
7 #include "fns.h"
9 #define ptrace dbptrace
11 extern int infile;
12 extern int outfile;
13 extern int maxpos;
15 /* general printing routines ($) */
17 char *Ipath = INCDIR;
18 static int tracetype;
19 static void printfp(Map*, int);
21 /*
22 * callback on stack trace
23 */
24 static int
25 ptrace(Map *map, Regs *regs, u64int pc, u64int nextpc, Symbol *sym, int depth)
26 {
27 char buf[512];
29 USED(map);
30 if(sym){
31 dprint("%s(", sym->name);
32 printparams(sym, regs);
33 dprint(") ");
34 }else
35 dprint("%#lux ", pc);
36 printsource(pc);
38 dprint(" called from ");
39 symoff(buf, 512, nextpc, CTEXT);
40 dprint("%s ", buf);
41 /* printsource(nextpc); */
42 dprint("\n");
43 if(tracetype == 'C' && sym)
44 printlocals(sym, regs);
45 return depth<40;
46 }
48 static ulong *adrregvals;
50 static int
51 adrrw(Regs *regs, char *name, u64int *val, int isr)
52 {
53 int i;
55 if((i = windindex(name)) == -1)
56 return correg->rw(correg, name, val, isr);
57 if(isr){
58 *val = adrregvals[i];
59 return 0;
60 }
61 werrstr("saved registers are immutable");
62 return -1;
63 }
65 Regs*
66 adrregs(void)
67 {
68 int i;
69 static Regs r;
70 static u32int x;
72 if(adrregvals== nil){
73 adrregvals = malloc(mach->nwindreg*sizeof(adrregvals[0]));
74 if(adrregvals == nil)
75 error("%r");
76 }
77 for(i=0; i<mach->nwindreg; i++){
78 if(get4(cormap, adrval+4*i, &x) < 0)
79 error("%r");
80 adrregvals[i] = x;
81 }
82 r.rw = adrrw;
83 return &r;
84 }
86 void
87 printdollar(int modif)
88 {
89 int i;
90 u32int u4;
91 BKPT *bk;
92 Symbol s;
93 int stack;
94 char *fname;
95 char buf[512];
96 Regs *r;
98 if (cntflg==0)
99 cntval = -1;
100 switch (modif) {
102 case '<':
103 if (cntval == 0) {
104 while (readchar() != EOR)
106 reread();
107 break;
109 if (rdc() == '<')
110 stack = 1;
111 else {
112 stack = 0;
113 reread();
115 fname = getfname();
116 redirin(stack, fname);
117 break;
119 case '>':
120 fname = getfname();
121 redirout(fname);
122 break;
124 case 'a':
125 attachprocess();
126 break;
128 /* maybe use this for lwpids?
129 case 'A':
130 attachpthread();
131 break;
132 */
133 case 'k':
134 kmsys();
135 break;
137 case 'q':
138 case 'Q':
139 done();
141 case 'w':
142 maxpos=(adrflg?adrval:MAXPOS);
143 break;
145 case 'S':
146 printsym();
147 break;
149 case 's':
150 maxoff=(adrflg?adrval:MAXOFF);
151 break;
153 case 'm':
154 printmap("? map", symmap);
155 printmap("/ map", cormap);
156 break;
158 case 0:
159 case '?':
160 if (pid)
161 dprint("pid = %d\n",pid);
162 else
163 prints("no process\n");
164 flushbuf();
166 case 'r':
167 case 'R':
168 printregs(modif);
169 return;
171 case 'f':
172 case 'F':
173 printfp(cormap, modif);
174 return;
176 case 'c':
177 case 'C':
178 tracetype = modif;
179 if (adrflg)
180 r = adrregs();
181 else
182 r = correg;
183 if(stacktrace(cormap, correg, ptrace) <= 0)
184 error("no stack frame");
185 break;
187 /*print externals*/
188 case 'e':
189 for (i = 0; indexsym(i, &s)>=0; i++) {
190 if (s.class==CDATA)
191 if (s.loc.type==LADDR)
192 if (get4(cormap, s.loc.addr, &u4) > 0)
193 dprint("%s/%12t%#lux\n", s.name, (ulong)u4);
195 break;
197 /*print breakpoints*/
198 case 'b':
199 case 'B':
200 for (bk=bkpthead; bk; bk=bk->nxtbkpt)
201 if (bk->flag) {
202 symoff(buf, 512, (WORD)bk->loc, CTEXT);
203 dprint(buf);
204 if (bk->count != 1)
205 dprint(",%d", bk->count);
206 dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
208 break;
210 case 'M':
211 fname = getfname();
212 if (machbyname(fname) == 0)
213 dprint("unknown name\n");;
214 break;
215 default:
216 error("bad `$' command");
218 USED(r);
222 char *
223 getfname(void)
225 static char fname[ARB];
226 char *p;
228 if (rdc() == EOR) {
229 reread();
230 return (0);
232 p = fname;
233 do {
234 *p++ = lastc;
235 if (p >= &fname[ARB-1])
236 error("filename too long");
237 } while (rdc() != EOR);
238 *p = 0;
239 reread();
240 return (fname);
243 static void
244 printfp(Map *map, int modif)
246 Regdesc *rp;
247 int i;
248 int ret;
249 char buf[512];
251 for (i = 0, rp = mach->reglist; rp->name; rp += ret) {
252 ret = 1;
253 if (!(rp->flags&RFLT))
254 continue;
255 ret = fpformat(map, rp, buf, sizeof(buf), modif);
256 if (ret < 0) {
257 werrstr("Register %s: %r", rp->name);
258 error("%r");
260 /* double column print */
261 if (i&0x01)
262 dprint("%40t%-8s%-12s\n", rp->name, buf);
263 else
264 dprint("\t%-8s%-12s", rp->name, buf);
265 i++;
269 void
270 redirin(int stack, char *file)
272 char pfile[ARB];
274 if (file == 0) {
275 iclose(-1, 0);
276 return;
278 iclose(stack, 0);
279 if ((infile = open(file, 0)) < 0) {
280 strcpy(pfile, Ipath);
281 strcat(pfile, "/");
282 strcat(pfile, file);
283 if ((infile = open(pfile, 0)) < 0) {
284 infile = STDIN;
285 error("cannot open");
290 void
291 printmap(char *s, Map *map)
293 int i;
295 if (!map)
296 return;
297 if (map == symmap)
298 dprint("%s%12t`%s'\n", s, symfil==nil ? "-" : symfil);
299 else if (map == cormap)
300 dprint("%s%12t`%s'\n", s, corfil==nil ? "-" : corfil);
301 else
302 dprint("%s\n", s);
303 for (i = 0; i < map->nseg; i++) {
304 dprint("%s%8t%-16#lux %-16#lux %-16#lux %s\n", map->seg[i].name,
305 map->seg[i].base, map->seg[i].base+map->seg[i].size, map->seg[i].offset,
306 map->seg[i].file ? map->seg[i].file : "");
310 /*
311 * dump the raw symbol table
312 */
313 void
314 printsym(void)
316 int i;
317 Symbol *sp, s;
319 for (i=0; indexsym(i, &s)>=0; i++){
320 sp = &s;
321 switch(sp->type) {
322 case 't':
323 case 'l':
324 dprint("%8#lux t %s\n", sp->loc.addr, sp->name);
325 break;
326 case 'T':
327 case 'L':
328 dprint("%8#lux T %s\n", sp->loc.addr, sp->name);
329 break;
330 case 'D':
331 case 'd':
332 case 'B':
333 case 'b':
334 case 'a':
335 case 'p':
336 case 'm':
337 dprint("%8#lux %c %s\n", sp->loc.addr, sp->type, sp->name);
338 break;
339 default:
340 break;
345 #define STRINGSZ 128
347 /*
348 * print the value of dot as file:line
349 */
350 void
351 printsource(long dot)
353 char str[STRINGSZ];
355 if (fileline(dot, str, STRINGSZ) >= 0)
356 dprint("%s", str);
359 void
360 printpc(void)
362 char buf[512];
363 u64int u;
365 if(rget(correg, mach->pc, &u) < 0)
366 error("%r");
367 dot = u;
368 if(dot){
369 printsource((long)dot);
370 printc(' ');
371 symoff(buf, sizeof(buf), (long)dot, CTEXT);
372 dprint("%s/", buf);
373 if (mach->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
374 error("%r");
375 dprint("%16t%s\n", buf);
379 void
380 printlocals(Symbol *fn, Regs *regs)
382 int i;
383 u32int v;
384 Symbol s;
386 for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
387 if (s.class != CAUTO)
388 continue;
389 if(lget4(cormap, regs, s.loc, &v) >= 0)
390 dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, v);
391 else
392 dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
396 void
397 printparams(Symbol *fn, Regs *regs)
399 int i;
400 Symbol s;
401 u32int v;
402 int first = 0;
404 for (i = 0; indexlsym(fn, i, &s)>=0; i++) {
405 if (s.class != CPARAM)
406 continue;
407 if (first++)
408 dprint(", ");
409 if(lget4(cormap, regs, s.loc, &v) >= 0)
410 dprint("%s=%#lux", s.name, v);
411 else
412 dprint("%s=?", s.name);