|
|
1.1 root 1: static char sccsid[] = "@(#)display.c 4.2 2/28/81";
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) {
33: /* error handler kludge */
34: callpc = get(frame+64, DSP);
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 */
45: ADDR
46: formaddr(class, addr)
47: register char class;
48: ADDR addr; {
49: if (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:
72: char 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: */
84: ADDR
85: stackreg(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 */
116: ADDR
117: varaddr(proc, var)
118: char *proc, *var; {
119: return(findvar(proc, var, "", 0));
120: }
121:
122: /*
123: * displays values of variables matching proc:var,
124: * returns its address
125: */
126: ADDR
127: dispvar(proc, var, fmt)
128: char *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: */
141: ADDR
142: findvar(proc, var, fmt, prvar)
143: char *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:
246: char *
247: typetodesc(type, subflag)
248: short type; {
249: register int ptr, ftn, ary;
250: register char *desc;
251: register int base;
252:
253: static char *typedesc[MAXTYPE+1] = {
254: "d", /* undef */
255: "d", /* farg */
256: "c", /* char */
257: "hd", /* short */
258: "d", /* int */
259: "ld", /* long */
260: "f", /* float */
261: "g", /* double */
262: "d", /* strty */
263: "d", /* unionty */
264: "d", /* enumty */
265: "d", /* moety */
266: "bu", /* uchar */
267: "hu", /* ushort */
268: "u", /* unsigned */
269: "lu", /* ulong */
270: "d" /* void */
271: };
272:
273: ptr = ftn = ary = 0;
274: if ((base = type & BTMASK) > MAXTYPE)
275: base = 0;
276: desc = typedesc[base];
277: for (; type & TMASK; type = DECREF(type)) {
278: if (ISPTR(type)) ptr++;
279: else if (ISFTN(type)) ftn++;
280: else if (ISARY(type)) ary++;
281: }
282:
283: if ((ptr-subflag == 1 || ary-subflag == 1) && desc[0] == 'c')
284: return("s");
285: if (debug)
286: printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc);
287: if (ptr + ary == subflag)
288: return(desc);
289: if (ptr) return("x");
290: if (ptr==1 && ftn==1) return("p");
291: return(desc);
292: }
293:
294: typetosize(type, stsize)
295: short type; {
296: register int ptr, ftn, ary;
297: register int size;
298: register int base;
299:
300: static char typesize[MAXTYPE+1] = {
301: 4, /* undef */
302: 4, /* farg */
303: 1, /* char */
304: 2, /* short */
305: WORDSIZE, /* int */
306: 4, /* long */
307: 4, /* float */
308: 8, /* double */
309: 0, /* strty */
310: 0, /* unionty */
311: 4, /* enumty */
312: 4, /* moety */
313: 1, /* uchar */
314: 2, /* ushort */
315: 4, /* unsigned */
316: 4, /* ulong */
317: 4 /* void */
318: };
319:
320: ptr = ftn = ary = 0;
321: if ((base = type & BTMASK) > MAXTYPE)
322: base = 0;
323: size = typesize[base];
324: for (; type & TMASK; type = DECREF(type)) {
325: if (ISPTR(type)) ptr++;
326: else if (ISFTN(type)) ftn++;
327: else if (ISARY(type)) ary++;
328: }
329:
330: if (debug)
331: printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n",
332: ptr,ftn,ary,size,stsize);
333: if (ptr>1) return(4);
334: if (size == 0) return(stsize);
335: else return(size);
336: }
337:
338:
339: /* print breakpoints */
340: prbkpt() {
341: register BKPTR bkptr;
342: register int cnt;
343: char *cmdp;
344:
345: cnt = 0;
346:
347: for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
348: if (bkptr->flag) {
349: cnt++;
350: printbkpt("", adrtoprocp(bkptr->loc), bkptr->loc);
351: cmdp = bkptr->comm;
352: if (*cmdp != '\n') {
353: printf(" <");
354: while (*cmdp != '\n')
355: printf("%c", *cmdp++);
356: printf(">\n");
357: }
358: else
359: printf("\n");
360: }
361: if (cnt == 0)
362: printf("No breakpoints set\n");
363: }
364:
365: /* interactively delete breakpoints */
366:
367: idbkpt() {
368: register BKPTR bkptr;
369: register int yesflg, cnt;
370: register char c;
371:
372: cnt = 0;
373:
374: for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
375: if (bkptr->flag) {
376: printbkpt(" ? ", adrtoprocp(bkptr->loc), bkptr->loc);
377: yesflg = 0;
378: cnt++;
379: do {
380: c = getchar();
381: if (c == 'y' || c == 'd') yesflg++;
382: } while (c != '\n');
383: if (yesflg)
384: bkptr->flag = 0;
385: }
386: if (cnt == 0)
387: printf("No breakpoints set\n");
388: }
389:
390: /* delete all breakpoints */
391:
392: dabkpt() {
393: register BKPTR bkptr;
394:
395: for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt)
396: bkptr->flag = 0;
397: }
398:
399: /*
400: * Print name of breakpoint for a, b, d commands:
401: */
402: printbkpt(s, procp, dot)
403: char *s; struct proct *procp; ADDR dot; {
404: adrtolineno(dot);
405: if (dot != lnfaddr)
406: printf("0x%x (", dot);
407: prlnoff(procp, dot);
408: if (dot != lnfaddr)
409: printf(")");
410: printf("%s", s);
411: }
412:
413: /* print call frame */
414: prframe() {
415: prfrx(0);
416: }
417:
418: /* set top to print just the top procedure */
419: prfrx(top) {
420: int narg;
421: long offset;
422: register char class;
423: register int endflg;
424: char *p;
425: struct proct *procp;
426: struct nlist stentry;
427:
428: if ((procp = initframe()) == badproc) return;
429: do {
430: if (get(frame+12, DSP) == 0) return;
431: p = procp->pname;
432: if (eqstr("__dbsubc", p)) return;
433: if (p[0] == '_') {
434: endflg = 1;
435: #ifndef FLEXNAMES
436: printf("%.15s(", p+1);
437: #else
438: printf("%s(", p+1);
439: #endif
440: }
441: else {
442: #ifndef FLEXNAMES
443: printf("%.16s(", p);
444: #else
445: printf("%s(", p);
446: #endif
447: endflg = 0;
448: }
449: if (endflg == 0) {
450: offset = procp->st_offset;
451: blseek(&sbuf, offset, 0);
452: do {
453: if (bread(&sbuf, &stentry, sizeof stentry) <
454: sizeof stentry) {
455: endflg++;
456: break;
457: }
458: class = stentry.n_type & STABMASK;
459: } while (class == N_FUN);
460: while (class != N_PSYM) {
461: if (bread(&sbuf, &stentry, sizeof stentry) <
462: sizeof stentry) {
463: endflg++;
464: break;
465: }
466: class = stentry.n_type & STABMASK;
467: if (class == N_FUN) {
468: endflg++;
469: break;
470: }
471: }
472: }
473:
474: narg = get(argp, DSP);
475: if (narg & ~0xff) narg = 0;
476: argp += WORDSIZE;
477: while (narg) {
478: if (endflg) {
479: printf("%d", get(argp, DSP));
480: argp += 4;
481: } else {
482: int length;
483: #ifndef FLEXNAMES
484: printf("%.16s=", stentry.n_name);
485: #else
486: printf("%s=", stentry.n_un.n_name);
487: #endif
488: dispx(argp, "", N_GSYM, stentry.n_desc,
489: 0, 0, DSP);
490: length = typetosize(stentry.n_desc, 0);
491: if (length > WORDSIZE)
492: argp += length;
493: else
494: argp += WORDSIZE;
495: }
496: do {
497: if (endflg) break;
498: if (bread(&sbuf, &stentry, sizeof stentry) <
499: sizeof stentry) {
500: endflg++;
501: break;
502: }
503: class = stentry.n_type & STABMASK;
504: if (class == N_FUN) {
505: endflg++;
506: break;
507: }
508: } while (class != N_PSYM);
509: l1: if (--narg != 0) printf(",");
510: }
511: printf(")");
512: if (debug) printf(" @ 0x%x ", callpc);
513: if (procp->sfptr != badfile)
514: printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename,
515: adrtolineno(callpc-1));
516: printf("\n");
517: } while (((procp = nextframe()) != badproc) && !top);
518: }
519:
520: INT signo;
521: STRING signals[];
522: extern nsig;
523: sigprint()
524: {
525:
526: if (signo < nsig)
527: printf("%s", signals[signo]);
528: else
529: printf("signal %d???", signals[signo]);
530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.