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