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