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