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