|
|
1.1 root 1: static char sccsid[] = "@(#)display.c 4.1 10/9/80";
2: #include "head.h"
3: #include <a.out.h>
4: #include <stab.h>
5: #include "cdefs.h"
6: struct user u;
7: BKPTR 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 */
16: struct proct *
17: initframe() {
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:
27: struct proct *
28: nextframe() {
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 */
44: ADDR
45: formaddr(class, addr)
46: register char class;
47: ADDR addr; {
48: if (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:
71: char 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: */
83: ADDR
84: stackreg(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 */
115: ADDR
116: varaddr(proc, var)
117: char *proc, *var; {
118: return(findvar(proc, var, "", 0));
119: }
120:
121: /*
122: * displays values of variables matching proc:var,
123: * returns its address
124: */
125: ADDR
126: dispvar(proc, var, fmt)
127: char *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: */
140: ADDR
141: findvar(proc, var, fmt, prvar)
142: char *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:
245: char *
246: typetodesc(type, subflag)
247: short 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:
291: typetosize(type, stsize)
292: short 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 */
335: prbkpt() {
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:
362: idbkpt() {
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:
387: dabkpt() {
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: */
397: printbkpt(s, procp, dot)
398: char *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 */
409: prframe() {
410: prfrx(0);
411: }
412:
413: /* set top to print just the top procedure */
414: prfrx(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:
515: INT signo;
516: STRING signals[];
517: extern nsig;
518: sigprint()
519: {
520:
521: if (signo < nsig)
522: printf("%s", signals[signo]);
523: else
524: printf("signal %d???", signals[signo]);
525: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.