|
|
1.1 root 1: /*
2: * machine-dependent code for
3: * looking in stack frames
4: * vax version
5: */
6:
7: #include "defs.h"
8: #include <sys/param.h>
9: #include "regs.h"
10: #include "sym.h"
11: #include "space.h"
12:
13: int maxargs = 20;
14:
15: /*
16: * VAX stack frame
17: */
18:
19: #define F_PSW 4
20: #define F_FLAGS 6
21: #define F_AP 8 /* saved ap */
22: #define F_FP 12 /* saved fp */
23: #define F_PC 16 /* return pc */
24: #define F_REGS 20 /* saved regs, if any */
25:
26: /*
27: * flags
28: */
29:
30: #define FFREGS 0x1fff /* saved register flags; 01 is r0 */
31: #define FFCALLS 0x2000 /* called by calls, not callg */
32: #define FFOFF 0xc000 /* offset added to align stack */
33: #define SALIGN(f) (((f)>>14) & 03)
34:
35: /*
36: * is the saved psw reasonable?
37: * really just a last resort to find the end of the stack
38: */
39:
40: #define BADPSW(p) (((p)&0xff00) != 0)
41:
42: /*
43: * is the pc probably in signal trampoline code?
44: * == it's in the user block
45: */
46:
47: #define sigtramp(pc) (0x80000000 > (pc) && (pc) > 0x80000000 - ctob(UPAGES))
48:
49: #define F_HACK 64 /* where to find the saved pc in a trampoline frame */
50: /*
51: * return an address for a local variable
52: * no register vars, unfortunately, as we can't provide an address
53: * gn is the procedure; ln the local name
54: *
55: * this is vax dependent because symbol tables vary
56: */
57:
58: localaddr(gn, ln)
59: char *gn, *ln;
60: {
61: WORD fp, ap;
62: extern WORD expv;
63: extern int expsp;
64: ADDR laddr();
65:
66: if (gn) {
67: if (findrtn(gn) == 0)
68: error("function not found");
69: }
70: else {
71: findsym((WORD)atow(rget(PC)), INSTSP);
72: if (cursym == NULL)
73: error("function not found");
74: }
75: if (findframe(&fp, &ap) == 0)
76: error("stack frame not found");
77: if (ln == NULL) {
78: expsp = 0;
79: expv = fp;
80: return;
81: }
82: while (localsym()) {
83: if (strcmp(ln, cursym->y_name) != 0)
84: continue;
85: expv = laddr(cursym, fp, ap);
86: if (cursym->y_ltype == S_RSYM)
87: expsp = REGSP;
88: else
89: expsp = NOSP;
90: return;
91: }
92: error("bad local variable");
93: /* NOTREACHED */
94: }
95:
96: /*
97: * print a stack traceback
98: * give locals if possible
99: */
100:
101: ctrace(modif)
102: char modif;
103: {
104: register ADDR fp, ap, callpc;
105: register int narg;
106: ADDR oap;
107: register int fl;
108: int tramp;
109:
110: if (adrflg) {
111: fp = adrval;
112: fl = stow(sget(fp + F_FLAGS, CORF|DATASP));
113: if ((fl & FFCALLS) == 0)
114: ap = fp; /* callg, can't figure out ap */
115: else {
116: ap = adrval + F_REGS + SALIGN(fl);
117: fl &= FFREGS;
118: while (fl) {
119: if (fl & 1)
120: ap += SZREG;
121: fl >>= 1;
122: }
123: }
124: callpc = atow(aget(fp + F_PC, CORF|DATASP));
125: } else {
126: ap = (ADDR)rtow(rget(AP));
127: fp = (ADDR)rtow(rget(FP));
128: callpc = (ADDR)rtow(rget(PC));
129: }
130: clrraddr();
131: while (cntval--) {
132: chkerr();
133: tramp = 0;
134: if (sigtramp(callpc)) {
135: printf("sigtramp(");
136: tramp++;
137: } else {
138: findsym(callpc, INSTSP);
139: if (cursym == NULL)
140: printf("?(");
141: else if (strcmp("start", cursym->y_name) == 0)
142: break;
143: else
144: printf("%s(", cursym->y_name);
145: }
146: fl = ctow(cget(ap, CORF|DATASP));
147: if ((narg = fl) > maxargs)
148: narg = maxargs;
149: oap = ap;
150: while (--fl, --narg >= 0) {
151: printf("%R", ltow(lget(ap += SZREG, CORF|DATASP)));
152: if (narg != 0)
153: printc(',');
154: }
155: if (fl >= 0)
156: printf(",...");
157: printf(") from %R\n", callpc);
158: if (modif == 'C')
159: locals(fp, oap);
160: if (tramp) /* hack */
161: callpc = atow(aget(fp + F_HACK, CORF|DATASP));
162: else
163: callpc = atow(aget(fp + F_PC, CORF|DATASP));
164: fl = stow(sget(fp + F_FLAGS, CORF|DATASP));
165: setraddr(fl, fp);
166: ap = atow(aget(fp + F_AP, CORF|DATASP));
167: fp = atow(aget(fp + F_FP + SALIGN(fl), CORF|DATASP));
168: if (fp == 0)
169: break;
170: fl = stow(sget(fp + F_PSW, CORF|DATASP));
171: if (BADPSW(fl))
172: break;
173: }
174: clrraddr();
175: }
176:
177: static
178: locals(fp, ap)
179: ADDR fp, ap;
180: {
181: WORD val;
182: register int sp;
183: ADDR laddr();
184:
185: while (localsym()) {
186: sp = CORF | DATASP;
187: if (cursym->y_ltype == S_RSYM)
188: sp = CORF | REGSP;
189: val = ltow(lget(laddr(cursym, fp, ap), sp));
190: if (errflg == 0)
191: printf("%8t%s/%10t%R\n", cursym->y_name, val);
192: else {
193: printf("%8t%s/%10t?\n", cursym->y_name);
194: errflg = 0;
195: }
196: }
197: }
198:
199: static ADDR
200: laddr(sp, fp, ap)
201: struct sym *sp;
202: ADDR fp, ap;
203: {
204:
205: switch (sp->y_ltype) {
206: case S_STSYM:
207: return (sp->y_value);
208:
209: case S_LSYM:
210: return (fp - sp->y_value);
211:
212: case S_PSYM:
213: return (ap + sp->y_value);
214:
215: case S_RSYM:
216: return (sp->y_value * SZREG);
217: }
218: error("bad local symbol");
219: /* NOTREACHED */
220: }
221:
222: static int
223: findframe(fpp, app)
224: ADDR *fpp, *app;
225: {
226: register ADDR fp, ap, pc;
227: register int fl;
228: struct sym *svcur;
229:
230: svcur = cursym;
231: fp = rtow(rget(FP));
232: ap = rtow(rget(AP));
233: pc = rtow(rget(PC));
234: if (errflg)
235: return (0);
236: clrraddr();
237: for (;;) {
238: findsym(pc, INSTSP);
239: if (cursym == svcur)
240: break;
241: if (cursym && strcmp(cursym->y_name, "start") == 0) {
242: clrraddr();
243: return (0);
244: }
245: fl = stow(sget((ADDR)fp + F_FLAGS, CORF|DATASP));
246: setraddr(fl, fp);
247: pc = atow(aget(fp + F_PC, CORF|DATASP));
248: ap = atow(aget(fp + F_AP, CORF|DATASP));
249: fp = atow(aget(fp + F_FP + SALIGN(fl), CORF|DATASP));
250: /* sigtramp? */
251: if (errflg) {
252: clrraddr();
253: return (0);
254: }
255: }
256: *fpp = fp;
257: *app = ap;
258: return (1);
259: }
260:
261: /*
262: * set addresses for saved registers for this frame
263: */
264:
265: static
266: setraddr(mask, fp)
267: register int mask;
268: register ADDR fp;
269: {
270: register int r;
271: register int i;
272: extern ADDR raddr[];
273:
274: mask &= FFREGS;
275: for (r = 0, i = 0; mask; r++)
276: if (mask & (1 << r)) {
277: if (MINREG <= r && r <= MAXREG)
278: raddr[r - MINREG] = fp + F_REGS +
279: i * SZREG;
280: i++;
281: mask &=~ (1 << r);
282: }
283: }
284:
285: static
286: clrraddr()
287: {
288: register int i;
289: extern ADDR raddr[];
290:
291: for (i = 0; i <= MAXREG - MINREG; i++)
292: raddr[i] = 0;
293: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.