|
|
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 <sys/dir.h>
10: #include <sys/user.h>
11: #include "regs.h"
12: #include "sym.h"
13: #include "space.h"
14:
15: int maxargs = 20;
16:
17: /*
18: * mc68000 stack frame
19: */
20:
21: #define F_FP 0 /* saved fp */
22: #define F_PC 4 /* return pc */
23: #define F_ARG 8 /* first argument */
24: #define FP AR6
25:
26: /*
27: * is the saved psw reasonable?
28: * really just a last resort to find the end of the stack
29: */
30:
31: #define BADPSW(p) (((p)&0xff00) != 0)
32:
33: /*
34: * return an address for a local variable
35: * no register vars, unfortunately, as we can't provide an address
36: * gn is the procedure; ln the local name
37: */
38:
39: localaddr(gn, ln)
40: char *gn, *ln;
41: {
42: WORD fp;
43: extern WORD expv;
44: extern int expsp;
45: ADDR laddr();
46:
47: if (gn) {
48: if (findrtn(gn) == 0)
49: error("function not found");
50: }
51: else {
52: findsym((WORD)atow(rget(PC)), INSTSP);
53: if (cursym == NULL)
54: error("function not found");
55: }
56: if (findframe(&fp) == 0)
57: error("stack frame not found");
58: if (ln == NULL) {
59: expsp = 0;
60: expv = fp;
61: return;
62: }
63: while (localsym()) {
64: if (strcmp(ln, cursym->y_name) != 0)
65: continue;
66: expv = laddr(cursym, fp);
67: if (cursym->y_ltype == S_RSYM)
68: expsp = REGSP;
69: else
70: expsp = NOSP;
71: return;
72: }
73: error("bad local variable");
74: /* NOTREACHED */
75: }
76:
77: /*
78: * print a stack traceback
79: * give locals if possible
80: */
81:
82: ctrace(modif)
83: char modif;
84: {
85: register ADDR fp, ap, callpc;
86: register int narg;
87: register int fl;
88:
89: if (adrflg) {
90: fp = adrval;
91: callpc = atow(aget(fp + F_PC, CORF|DATASP));
92: } else {
93: fp = (ADDR)rtow(rget(FP));
94: callpc = (ADDR)rtow(rget(PC));
95: }
96: clrraddr();
97: while (cntval--) {
98: chkerr();
99: findsym(callpc, INSTSP);
100: if (cursym == NULL)
101: printf("?(");
102: else if (strcmp("start", cursym->y_name) == 0)
103: break;
104: else
105: printf("%s(", cursym->y_name);
106: fl = getnargs(fp);
107: if ((narg = fl) > maxargs)
108: narg = maxargs;
109: ap = fp + F_ARG;
110: while (--fl, --narg >= 0) {
111: printf("%R", ltow(lget(ap, CORF|DATASP)));
112: ap += SZREG;
113: if (narg != 0)
114: printc(',');
115: }
116: if (fl >= 0)
117: printf(",...");
118: printf(") from %R\n", callpc);
119: if (modif == 'C')
120: locals(fp);
121: callpc = atow(aget(fp + F_PC, CORF|DATASP));
122: setraddr(fp);
123: fp = atow(aget(fp + F_FP, CORF|DATASP));
124: if (fp == 0)
125: break;
126: }
127: clrraddr();
128: }
129:
130: /*
131: * Given a frame pointer determine the number of arguments.
132: * Unlike the vax, there is no argument pointer so we look at
133: * the instruction in the return pc and try to determine how
134: * may arguments are there by the resetting of the stack pointer.
135: */
136: #define LEASPSP 0x4fef /* Lea sp@(xx),sp instruction */
137: #define ADDQWL 0x500f /* Addqw #xx,sp instruction */
138:
139: getnargs(fp)
140: ADDR fp;
141: {
142: ADDR callpc;
143: WORD instr, nargs;
144:
145: callpc = atow(aget(fp + F_PC, CORF|DATASP));
146: instr = stow(sget(callpc, SYMF|INSTSP));
147: if (instr == LEASPSP)
148: nargs = stow(sget(callpc + 2, SYMF|INSTSP));
149: else if ((instr & 0xf12f) == ADDQWL) {
150: nargs = (instr >> 9) & 7;
151: if (nargs == 0)
152: nargs = 8;
153: }
154: else
155: nargs = 0;
156: return (nargs / SZREG);
157: }
158:
159: static
160: locals(fp)
161: ADDR fp;
162: {
163: WORD val;
164: register int sp;
165: ADDR laddr();
166:
167: while (localsym()) {
168: sp = CORF | DATASP;
169: if (cursym->y_ltype == S_RSYM)
170: sp = CORF | REGSP;
171: val = ltow(lget(laddr(cursym, fp), sp));
172: if (errflg == 0)
173: printf("%8t%s/%10t%R\n", cursym->y_name, val);
174: else {
175: printf("%8t%s/%10t?\n", cursym->y_name);
176: errflg = 0;
177: }
178: }
179: }
180:
181: static ADDR
182: laddr(sp, fp)
183: struct sym *sp;
184: ADDR fp;
185: {
186:
187: switch (sp->y_ltype) {
188: case S_STSYM:
189: return (sp->y_value);
190:
191: case S_LSYM:
192: return (fp - sp->y_value);
193:
194: case S_PSYM:
195: return (fp + sp->y_value);
196:
197: case S_RSYM:
198: return (sp->y_value);
199: }
200: error("bad local symbol");
201: /* NOTREACHED */
202: }
203:
204: static int
205: findframe(fpp)
206: ADDR *fpp;
207: {
208: register ADDR fp, pc;
209: struct sym *svcur;
210:
211: svcur = cursym;
212: fp = rtow(rget(FP));
213: pc = rtow(rget(PC));
214: if (errflg)
215: return (0);
216: clrraddr();
217: for (;;) {
218: findsym(pc, INSTSP);
219: if (cursym == svcur)
220: break;
221: if (cursym && strcmp(cursym->y_name, "start") == 0) {
222: clrraddr();
223: return (0);
224: }
225: setraddr(fp);
226: pc = atow(aget(fp + F_PC, CORF|DATASP));
227: fp = atow(aget(fp + F_FP, CORF|DATASP));
228: if (errflg) {
229: clrraddr();
230: return (0);
231: }
232: }
233: *fpp = fp;
234: return (1);
235: }
236:
237: /*
238: * set addresses for saved registers for this frame
239: */
240:
241: static
242: setraddr(fp)
243: register ADDR fp;
244: {
245: register int r;
246: register int i;
247: extern ADDR raddr[];
248:
249: /* all wrong */
250: }
251:
252: static
253: clrraddr()
254: {
255: register int i;
256: extern ADDR raddr[];
257:
258: for (i = 0; i <= MAXREG - MINREG; i++)
259: raddr[i] = 0;
260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.