|
|
1.1 root 1: static char sccsid[] = "@(#)display.c 4.3 8/17/82";
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: u_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:
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:
292: typetosize(type, stsize)
293: short 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 */
336: prbkpt() {
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:
363: idbkpt() {
364: register BKPTR bkptr;
365: register int yesflg, cnt;
366: char c;
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:
388: dabkpt() {
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: */
398: printbkpt(s, procp, dot)
399: char *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 */
410: prframe() {
411: prfrx(0);
412: }
413:
414: /* set top to print just the top procedure */
415: prfrx(top) {
416: int narg;
417: long offset;
418: u_char class;
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: }
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.