BSD 3 development
[unix-history] / usr / src / cmd / sdb / display.c
CommitLineData
d610219d
HK
1#include "head.h"
2#include <a.out.h>
3#include "cdefs.h"
4struct user u;
5BKPTR bkpthead;
6
7/* initialize frame pointers to top of call stack */
8struct proct *
9initframe() {
10 argp = *(ADDR *) (((ADDR) &u) + AP);
11 frame = *(ADDR *) (((ADDR) &u) + FP);
12 callpc = *(ADDR *) (((ADDR) &u) + PC);
13 if ((frame == 0) || (frame & 0xf0000000 != 0x70000000))
14 return(badproc);
15 return(adrtoproc(callpc++)); /* ++ because UNIX backs up instrs */
16}
17
18
19struct proct *
20nextframe() {
21 callpc = get(frame+16, DSP);
22 argp = get(frame+8, DSP);
23 frame = get(frame+12, DSP) & EVEN;
24 if (callpc > 0x70000000) { /* error handler kludge */
25 callpc = get(argp+12, DSP);
26 argp = get(frame+8, DSP);
27 frame = get(frame+12, DSP) & EVEN;
28 }
29 if ((frame == 0) || (frame & 0xf0000000 != 0x70000000))
30 return(badproc);
31 return(adrtoproc(callpc-1));
32}
33
34/* returns core image address for variable */
35ADDR
36formaddr(class, addr)
37register char class;
38ADDR addr; {
39if (debug) printf("formaddr(%o, %d)\n", class & 0377, addr);
40 switch(class & STABMASK) {
41 case N_RSYM:
42 return(stackreg(addr));
43 case N_GSYM:
44 case N_SSYM:
45 case N_STSYM:
46 case N_LCSYM:
47 return(addr);
48
49 case N_PSYM:
50 return(argp+addr);
51
52 case N_LSYM:
53 return(frame+addr);
54
55 default:
56 printf("Bad class in formaddr: 0%o",
57 class & 0377);
58 return(0);
59 }
60}
61
62char class;
63
64/*
65 * stackreg(reg):
66 * If the register for the current frame is somewhere on the stack
67 * then return the address of where it is, otherwise its still in
68 * the register so return the register number.
69 * We distinguish the two by noting that register numbers are less
70 * than 16 and that stack addresses are greater.
71 *
72 * MACHINE DEPENDENT
73 */
74ADDR
75stackreg(reg) {
76 register int curframe, regfl, mask, i;
77 struct proct *procp;
78 ADDR regaddr;
79
80 curframe = frame;
81 regaddr = reg;
82 regfl = 0x10000 << reg;
83 for (procp=initframe(); frame!=curframe; procp=nextframe()) {
84 if (procp == badproc) {
85 error("Stackreg error: frame");
86 return(-1);
87 }
88 mask = get(frame+4, DSP);
89 if (mask & regfl) {
90 regaddr = frame + 20;
91 for (i=0; i<reg; i++) {
92 if (mask & 0x10000)
93 regaddr += WORDSIZE;
94 mask = mask >> 1;
95 }
96 if (!(mask & 0x10000)) {
97 error("Stackreg error: contents");
98 return(-1);
99 }
100 }
101 }
102 return(regaddr);
103}
104
105/* returns address of proc:var. Sets externals class and subflag */
106ADDR
107varaddr(proc, var)
108char *proc, *var; {
109 return(findvar(proc, var, "", 0));
110}
111
112/*
113 * displays values of variables matching proc:var,
114 * returns its address
115 */
116ADDR
117dispvar(proc, var, fmt)
118char *proc, *var, *fmt; {
119 return(findvar(proc, var, fmt, 1));
120}
121
122/*
123 * Find and print values of all variables matching proc:var
124 * using specified format.
125 * Returns address of last matching variable.
126 *
127 * prvar==0 => no output,
128 * prvar==1 => output value,
129 * prvar==2 => output addr
130 */
131ADDR
132findvar(proc, var, fmt, prvar)
133char *proc, *var, *fmt; {
134 ADDR addr = -1, a = -1;
135 int metaflag = 0, match=0, nullflag=0, depthcnt = -1;
136 char *comblk;
137 register struct proct *procp;
138
139 if (var[0] == '\0') {
140 error("Unexpected null variable name");
141 return(-1);
142 }
143
144 metaflag = eqany('*', proc) || eqany('?', proc) ||
145 eqany('*', var) || eqany('?', var);
146
147 if (proc[0] == '\0') {
148 nullflag++;
149 proc = curproc()->pname;
150 }
151
152 comblk = colonflag ? "" : "*";
153
154 if (integ && !eqany(var[0], "->.[")) {
155 depthcnt = integ;
156 }
157 if (integ) {
158 if (eqany(var[0], "->.["))
159 match++;
160 else
161 depthcnt = integ;
162 }
163
164 procp = initframe();
165 if (!eqany(var[0], "->.[") && !(nullflag && colonflag)) {
166 do {
167 if (eqpat(proc, procp->pname)) {
168 match++;
169 if (--depthcnt==0 || integ==0) {
170 a = outvar(procp->pname, var, fmt,
171 metaflag, integ, N_GSYM,
172 0, prname, comblk, prvar);
173 if (a != -1)
174 addr = a;
175 if (depthcnt == 0)
176 break;
177 }
178 }
179 } while ((procp=nextframe()) != badproc);
180 }
181
182 if ((colonflag || metaflag || a == -1) &&
183 (nullflag || eqpat(proc, ""))) {
184 a = outvar("", var, fmt, metaflag, integ,
185 N_GSYM, 0, prname, comblk, prvar);
186 if (a != -1) {
187 addr = a;
188 match++;
189 }
190 }
191
192 if (match==0 && colonflag) {
193 procp = initframe();
194 do {
195 if (eqstr(curproc()->pname, procp->pname))
196 break;
197 } while ((procp=nextframe()) != badproc);
198 a = outvar(curproc()->pname, var, fmt, metaflag,
199 integ, N_GSYM, 0, prname,
200 nullflag ? "_BLNK_" : proc, prvar);
201 if (a != -1) {
202 addr = a;
203 match++;
204 }
205 }
206
207 if (match == 0) {
208 printf("%s not an active procedure\n", proc);
209 return(-1);
210 }
211 if (addr == -1) {
212 if (var[0] == '.')
213 var++;
214 if (proc[0])
215 printf("%.8s:%s not found\n", proc, var);
216 else
217 printf("%s not found\n", var);
218 return(-1);
219 }
220 return(addr);
221}
222
223char *
224typetodesc(type, subflag)
225short type; {
226 register int ptr, ftn, ary;
227 register char *desc;
228
229 static char *typedesc[] = {
230 "d", /* undef */
231 "d", /* farg */
232 "c", /* char */
233 "hd", /* short */
234 "d", /* int */
235 "ld", /* long */
236 "f", /* float */
237 "g", /* double */
238 "d", /* strty */
239 "d", /* unionty */
240 "d", /* enumty */
241 "d", /* moety */
242 "bu", /* uchar */
243 "hu", /* ushort */
244 "u", /* unsigned */
245 "lu", /* ulong */
246 "d" /* ? */
247 };
248
249 ptr = ftn = ary = 0;
250
251 desc = typedesc[type&BTMASK];
252 for (; type & TMASK; type = DECREF(type)) {
253 if (ISPTR(type)) ptr++;
254 else if (ISFTN(type)) ftn++;
255 else if (ISARY(type)) ary++;
256 }
257
258 if ((ptr-subflag == 1 || ary-subflag == 1) && desc[0] == 'c')
259 return("s");
260 if (debug)
261 printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc);
262 if (ptr + ary == subflag)
263 return(desc);
264 if (ptr) return("x");
265 if (ptr==1 && ftn==1) return("p");
266 return(desc);
267}
268
269typetosize(type, stsize)
270short type; {
271 register int ptr, ftn, ary;
272 register int size;
273
274 static char typesize[] = {
275 4, /* undef */
276 4, /* farg */
277 1, /* char */
278 2, /* short */
279 WORDSIZE, /* int */
280 4, /* long */
281 4, /* float */
282 8, /* double */
283 0, /* strty */
284 0, /* unionty */
285 4, /* enumty */
286 4, /* moety */
287 1, /* uchar */
288 2, /* ushort */
289 4, /* unsigned */
290 4, /* ulong */
291 4 /* ? */
292 };
293
294 ptr = ftn = ary = 0;
295
296 size = typesize[type&BTMASK];
297 for (; type & TMASK; type = DECREF(type)) {
298 if (ISPTR(type)) ptr++;
299 else if (ISFTN(type)) ftn++;
300 else if (ISARY(type)) ary++;
301 }
302
303 if (debug)
304 printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n",
305 ptr,ftn,ary,size,stsize);
306 if (ptr>1) return(4);
307 if (size == 0) return(stsize);
308 else return(size);
309}
310
311
312/* print breakpoints */
313prbkpt() {
314 register BKPTR bkptr;
315 register int cnt;
316 char *cmdp;
317
318 cnt = 0;
319
320 for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
321 if (bkptr->flag) {
322 cnt++;
323 printbkpt("", adrtoprocp(bkptr->loc)->pname,
324 adrtolineno(bkptr->loc));
325 cmdp = bkptr->comm;
326 if (*cmdp != '\n') {
327 printf(" <");
328 while (*cmdp != '\n')
329 printf("%c", *cmdp++);
330 printf(">\n");
331 }
332 else
333 printf("\n");
334 }
335 if (cnt == 0)
336 printf("No breakpoints set\n");
337}
338
339/* interactively delete breakpoints */
340
341idbkpt() {
342 register BKPTR bkptr;
343 register int yesflg, cnt;
344 register char c;
345
346 cnt = 0;
347
348 for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
349 if (bkptr->flag) {
350 printbkpt(" ? ", adrtoprocp(bkptr->loc)->pname,
351 adrtolineno(bkptr->loc));
352 yesflg = 0;
353 cnt++;
354 do {
355 c = getchar();
356 if (c == 'y' || c == 'd') yesflg++;
357 } while (c != '\n');
358 if (yesflg)
359 bkptr->flag = 0;
360 }
361 if (cnt == 0)
362 printf("No breakpoints set\n");
363}
364
365/* delete all breakpoints */
366
367dabkpt() {
368 register BKPTR bkptr;
369
370 for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
371 bkptr->flag = 0;
372}
373printbkpt(s, name, lineno)
374char *s, *name; {
375 if (name[0] == '_')
376 printf("%.7s:", name+1);
377 else
378 printf("%.8s:", name);
379
380 if (lineno != -1)
381 printf("%d%s", lineno, s);
382 else
383 printf("%s", s);
384}
385
386/* print call frame */
387prframe() {
388 prfrx(0);
389}
390
391/* set top to print just the top procedure */
392prfrx(top) {
393 int narg;
394 long offset;
395 register char class;
396 register int endflg;
397 char *p;
398 struct proct *procp;
399 struct nlist stentry;
400
401 if ((procp = initframe()) == badproc) return;
402 do {
403 if (get(frame+12, DSP) == 0) return;
404 p = procp->pname;
405 if (eqstr("__dbsubc", p)) return;
406 if (p[0] == '_') {
407 endflg = 1;
408 printf("%.7s(", p+1);
409 }
410 else {
411 printf("%.8s(", p);
412 endflg = 0;
413 }
414 if (endflg == 0) {
415 offset = procp->st_offset;
416 blseek(&sbuf, offset, 0);
417 do {
418 if (bread(&sbuf, &stentry, sizeof stentry) <
419 sizeof stentry) {
420 endflg++;
421 break;
422 }
423 class = stentry.n_type & STABMASK;
424 } while (class == N_FUN);
425 while (class != N_PSYM) {
426 if (bread(&sbuf, &stentry, sizeof stentry) <
427 sizeof stentry) {
428 endflg++;
429 break;
430 }
431 class = stentry.n_type & STABMASK;
432 if (class == N_FUN) {
433 endflg++;
434 break;
435 }
436 }
437 }
438
439 narg = get(argp, DSP);
440 if (narg & ~0xff) narg = 0;
441 argp += WORDSIZE;
442 while (narg) {
443 if (endflg) {
444 printf("%d", get(argp, DSP));
445 argp += 4;
446 } else {
447 int length;
448 printf("%.8s=", stentry.n_name);
449 dispx(argp, "", N_GSYM, stentry.n_desc, 0, 0);
450 length = typetosize(stentry.n_desc, 0);
451 if (length > WORDSIZE)
452 argp += length;
453 else
454 argp += WORDSIZE;
455 }
456 do {
457 if (endflg) break;
458 if (bread(&sbuf, &stentry, sizeof stentry) <
459 sizeof stentry) {
460 endflg++;
461 break;
462 }
463 class = stentry.n_type & STABMASK;
464 if (class == N_FUN) {
465 endflg++;
466 break;
467 }
468 } while (class != N_PSYM);
469 l1: if (--narg != 0) printf(",");
470 }
471 printf(")");
472 if (debug) printf(" @ 0x%x ", callpc);
473 if (procp->sfptr != badfile)
474 printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename,
475 adrtolineno(callpc-1));
476 printf("\n");
477 } while (((procp = nextframe()) != badproc) && !top);
478}
479
480STRING signals[] = {
481 "",
482 "hangup",
483 "interrupt",
484 "quit",
485 "illegal instruction",
486 "trace/BPT",
487 "IOT",
488 "EMT",
489 "floating exception",
490 "killed",
491 "bus error",
492 "memory fault",
493 "bad system call",
494 "broken pipe",
495 "alarm call",
496 "terminated",
497};
498INT signo;
499
500sigprint() {
501 printf("%s", signals[signo]);
502}
503