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
ptrace(Map * map,uvlong pc,uvlong sp,Symbol * sym)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
printtrace(int modif)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 *
getfname(void)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
printfp(Map * map,int modif)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
redirin(int stack,char * file)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
printmap(char * s,Map * map)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
printsym(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
printsource(ADDR dot)313 printsource(ADDR dot)
314 {
315 char str[STRINGSZ];
316
317 if (fileline(str, STRINGSZ, dot))
318 dprint("%s", str);
319 }
320
321 void
printpc(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
printlocals(Symbol * fn,ADDR fp)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
printparams(Symbol * fn,ADDR fp)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 }
375