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