|
|
1.1 root 1: /*
2: * machine-dependent code for
3: * looking in stack frames
4: * sequent/32032 version
5: */
6:
7: #include "defs.h"
8: #include "space.h"
9: #include <sys/param.h>
10: #include "regs.h"
11: #include <a.out.h>
12: #include "sym.h"
13: #include <signal.h>
14:
15: int maxargs = 20;
16:
17: /*
18: * stuff in the stack frame
19: */
20:
21: #define F_HACKPC 48 /* signal handler hack */
22: #define F_ARG1 8 /* first argument */
23: #define F_PC 4
24: #define F_FP 0
25:
26: /*
27: * how to find out the number of arguments to a procedure call:
28: * look at the instruction after the call (cxp)
29: * it should be an adjspb with an immediate operand
30: * the operand (the following byte) is the (negative) number of
31: * bytes to be popped off the stack after the call;
32: * i.e. the amount of space taken by parameters
33: */
34:
35: #define adjspbi(x) (((x) & 0xffff) == 0xa57c)
36: #define adjoff(x) ((((x) & 0xff0000) >> 16) | 0xffffff00)
37:
38: /*
39: * return an address for a local variable
40: * no register vars, unfortunately, as we can't provide an address
41: * gn is the procedure; ln the local name
42: */
43:
44: extern WORD expv;
45: extern int expsp;
46:
47: localaddr(gn, ln)
48: char *gn, *ln;
49: {
50: WORD fp;
51: ADDR laddr();
52:
53: if (gn) {
54: if (findrtn(gn) == 0)
55: error("function not found");
56: }
57: else {
58: findsym((WORD)atow(rget(PC)), INSTSP);
59: if (cursym == NULL)
60: error("function not found");
61: }
62: if (findframe(&fp) == 0)
63: error("function not found");
64: if (ln == NULL) {
65: expsp = 0;
66: expv = fp;
67: return;
68: }
69: while (localsym()) {
70: if (strcmp(ln, cursym->y_name) != 0)
71: continue;
72: expv = laddr(cursym, fp, fp + F_ARG1);
73: if (cursym->y_ltype == S_RSYM)
74: expsp = REGSP;
75: else
76: expsp = NOSP;
77: return;
78: }
79: error("local var not found");
80: /* NOTREACHED */
81: }
82:
83: /*
84: * print a stack traceback
85: * give locals if possible
86: */
87:
88: ctrace(modif)
89: char modif;
90: {
91: register ADDR fp, ap, callpc;
92: register int narg;
93: ADDR ofp;
94: ADDR newpc;
95: WORD w;
96:
97: if (adrflg) {
98: fp = adrval;
99: callpc = atow(aget(fp + F_PC, CORF|DATASP));
100: } else {
101: fp = (ADDR)rtow(rget(FP));
102: callpc = (ADDR)rtow(rget(PC));
103: }
104: clrraddr();
105: ofp = fp;
106: while (cntval--) {
107: chkerr();
108: findsym(callpc, INSTSP);
109: if (cursym == NULL)
110: printf("?(");
111: else if (strcmp("start", cursym->y_name) == 0)
112: break;
113: else
114: printf("%s(", cursym->y_name);
115: if (strcmp("sigcode", cursym->y_name) == 0) {
116: printf(") from %R\n", callpc);
117: callpc = ltow(lget(ofp + F_HACKPC, CORF|DATASP));
118: /* ignore saved r0 r1 r2 for now */
119: continue;
120: }
121: newpc = atow(aget(fp + F_PC, CORF|DATASP));
122: w = ltow(lget(newpc, SYMF|INSTSP));
123: if (!adjspbi(w))
124: narg = 0;
125: else
126: narg = -adjoff(w)/4;
127: for (ap = fp + F_ARG1; --narg >= 0; ap += SZREG) {
128: printf("%R", ltow(lget(ap, CORF|DATASP)));
129: if (narg != 0)
130: printc(',');
131: }
132: printf(") from %R\n", callpc);
133: if (modif == 'C')
134: locals(fp, fp + F_ARG1);
135: setraddr(callpc, fp);
136: callpc = newpc;
137: ofp = fp;
138: fp = atow(aget(fp + F_FP, CORF|DATASP));
139: if (fp == 0)
140: break;
141: }
142: clrraddr();
143: }
144:
145: static
146: locals(fp, ap)
147: ADDR fp, ap;
148: {
149: WORD val;
150: register int sp;
151: ADDR laddr();
152:
153: while (localsym()) {
154: sp = CORF | DATASP;
155: if (cursym->y_ltype == S_RSYM)
156: sp = CORF | REGSP;
157: val = ltow(lget(laddr(cursym, fp, ap), sp));
158: if (errflg == 0)
159: printf("%8t%s/%10t%R\n", cursym->y_name, val);
160: else {
161: printf("%8t%s/%10t?\n", cursym->y_name);
162: errflg = 0;
163: }
164: }
165: }
166:
167: ADDR
168: laddr(sp, fp, ap)
169: struct sym *sp;
170: ADDR fp, ap;
171: {
172:
173: switch (sp->y_ltype) {
174: case S_STSYM:
175: return (sp->y_value);
176:
177: case S_LSYM:
178: return (fp - sp->y_value);
179:
180: case S_PSYM:
181: return (ap + sp->y_value);
182:
183: case S_RSYM:
184: return (sp->y_value * SZREG);
185: }
186: error("bad local symbol");
187: /* NOTREACHED */
188: }
189:
190: int
191: findframe(fpp)
192: ADDR *fpp;
193: {
194: register ADDR fp, pc;
195: struct sym *svcur;
196:
197: svcur = cursym;
198: fp = rtow(rget(FP));
199: pc = rtow(rget(PC));
200: if (errflg)
201: return (0);
202: clrraddr();
203: for (;;) {
204: findsym(pc, INSTSP);
205: if (cursym == svcur)
206: break;
207: if (cursym && strcmp(cursym->y_name, "start") == 0) {
208: clrraddr();
209: return (0);
210: }
211: setraddr(cursym->y_value, fp);
212: pc = atow(aget(fp + F_PC, CORF|DATASP));
213: fp = atow(aget(fp + F_FP, CORF|DATASP));
214: /* sigtramp? */
215: if (errflg) {
216: clrraddr();
217: return (0);
218: }
219: }
220: *fpp = fp;
221: return (1);
222: }
223:
224: /*
225: * set addresses for saved registers for this frame
226: * the mask is that from an `enter' instruction
227: */
228:
229: extern ADDR raddr[];
230:
231: setraddr(pc, fp)
232: ADDR pc;
233: register ADDR fp;
234: {
235: register int r;
236: register int i;
237: int roff;
238: register int mask;
239:
240: if ((mask = regmask(pc, &roff)) == 0)
241: return;
242: fp += roff;
243: for (r = 7, i = 0; mask; r--)
244: if (mask & (1 << r)) {
245: if (MINREG <= r && r <= MAXREG)
246: raddr[r - MINREG] = fp + i * SZREG;
247: i++;
248: mask &=~ (1 << r);
249: }
250: }
251:
252: clrraddr()
253: {
254: register int i;
255:
256: for (i = 0; i <= MAXREG - MINREG; i++)
257: raddr[i] = 0;
258: }
259:
260: /*
261: * find the mask of saved registers for this routine
262: *
263: * pc is the entry point.
264: * if the code was run through c2, the first instruction will be `enter';
265: * grab the mask.
266: * set *rp to the number of bytes of local storage on the stack
267: * (the registers are pushed AFTER local storage)
268: * if it wasn't put through c2, the first instruction will be a branch.
269: * the instruction branched to will be the `enter.'
270: *
271: * awful but how else to do it?
272: */
273:
274: #define enter(w) (((w)&0xff) == 0x82)
275: #define entmsk(w) (((w)>>8) & 0xff)
276: #define br(w) (((w)&0xff) == 0xea)
277:
278: int
279: regmask(pc, rp)
280: ADDR pc;
281: int *rp;
282: {
283: register WORD w;
284: long disp();
285:
286: *rp = 0;
287: w = ltow(lget(pc, SYMF|INSTSP));
288: if (enter(w)) {
289: *rp = disp(pc + 2);
290: return (entmsk(w));
291: }
292: if (!br(w))
293: return (0);
294: w = ltow(lget(pc + disp(pc + 1), SYMF|INSTSP));
295: if (enter(w))
296: return (entmsk(w));
297: return (0);
298: }
299:
300: static
301: disp(pc)
302: ADDR pc;
303: {
304: register WORD w;
305:
306: w = ltow(lget(pc, SYMF|INSTSP));
307: if ((w & 0x80) == 0) {
308: w &= 0x7f;
309: if (w & 0x40)
310: w |= 0xffffffc0;
311: }
312: else if ((w & 0x40) == 0) {
313: w = ((w << 8) & 0x3f00) | ((w >> 8) & 0xff);
314: if (w & 0x2000)
315: w |= 0xffffc000;
316: }
317: else {
318: w = ((w << 24) & 0x3f000000)
319: | ((w << 8) & 0xff0000)
320: | ((w >> 8) & 0xff00)
321: | ((w >> 24) & 0xff);
322: if (w & 0x20000000)
323: w |= 0xc0000000;
324: }
325: return (w);
326: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.