|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)machdep.c 5.3 (Berkeley) 9/26/89";
3: #endif
4:
5: /*
6: * adb - miscellaneous machine dependent routines.
7: */
8:
9: #define RLOCALS /* enable alternate $C stack trace */
10:
11: #include "defs.h"
12: #include "bkpt.h"
13: #include <machine/pte.h>
14: #include <machine/frame.h>
15: #include <machine/reg.h>
16: #include <machine/vmparam.h>
17: #include <sys/ptrace.h>
18: #include <sys/vmmac.h>
19: #include <stab.h>
20:
21: struct pte *sbr;
22: int slr;
23: struct pcb pcb;
24: int masterpcbb;
25:
26: /*
27: * Activation records.
28: */
29:
30: /*
31: * Set up a stack frame based on the registers in the core image
32: * (or in the kernel core file ... not yet!).
33: */
34: a_init(ap)
35: register struct activation *ap;
36: {
37:
38: ap->a_valid = 1;
39: if (kcore) {
40: ap->a_ap = pcb.pcb_ap;
41: ap->a_fp = pcb.pcb_fp;
42: ap->a_pc = pcb.pcb_pc;
43: } else {
44: ap->a_ap = u.u_ar0[AP];
45: ap->a_fp = u.u_ar0[FP];
46: ap->a_pc = u.u_ar0[PC];
47: }
48: }
49:
50: /*
51: * Back up one stack frame in the call stack.
52: * ap points to the activation record from the previous frame.
53: * Clear a_valid field if we ran out of frames.
54: */
55: a_back(ap)
56: register struct activation *ap;
57: {
58: struct frame fr;
59:
60: /*
61: * The magic constants below allow us to read just the part of
62: * the frame that we need.
63: */
64: if (adbread(SP_DATA, ap->a_fp + 8, &fr.fr_savap, 12) != 12)
65: ap->a_valid = 0;
66: else {
67: ap->a_ap = fr.fr_savap;
68: ap->a_fp = fr.fr_savfp;
69: ap->a_pc = fr.fr_savpc;
70: if (ap->a_fp == 0)
71: ap->a_valid = 0;
72: }
73: }
74:
75: /*
76: * Evaluate a local symbol (N_LSYM or N_PSYM) using the activation
77: * record pointed to by ap.
78: */
79: addr_t
80: eval_localsym(sp, ap)
81: register struct nlist *sp;
82: struct activation *ap;
83: {
84: switch (sp->n_type) {
85:
86: case N_LSYM:
87: return (ap->a_fp - sp->n_value); /* ??? */
88:
89: case N_PSYM:
90: return (ap->a_ap + sp->n_value); /* ??? */
91: }
92: panic("eval_localsym");
93: /* NOTREACHED */
94: }
95:
96:
97: /* true iff address a is in instruction space */
98: #define ispace(a) ((a) < txtmap.m1.e)
99:
100: /*
101: * Delete a (single) breakpoint. Return 0 on success.
102: */
103: int
104: clr_bpt(b)
105: struct bkpt *b;
106: {
107: addr_t a = b->loc;
108:
109: return (adbwrite(ispace(a) ? SP_INSTR : SP_DATA, a, &b->ins, 1) != 1);
110: }
111:
112: /*
113: * Set a (single) breakpoint. Return 0 on success.
114: */
115: set_bpt(b)
116: struct bkpt *b;
117: {
118: addr_t a = b->loc;
119: int space;
120: char bpt = 0x03; /* breakpoint instruction */
121:
122: space = ispace(a) ? SP_INSTR : SP_DATA;
123: return (adbread(space, a, &b->ins, 1) != 1 ||
124: adbwrite(space, a, &bpt, 1) != 1);
125: }
126:
127: /*
128: * Check a float for `correctness' (reserved patterns, etc). Return
129: * a pointer to a character string to be printed instead of the float,
130: * or NULL to print the float as-is.
131: *
132: * The string returned, if any, should be no longer than 16 characters.
133: *
134: * On the VAX, we can simply check the first two bytes. Byte zero
135: * contains one bit of the exponent, and byte 1 has the remaining 7
136: * exponent bits and the sign bit. If the sign bit is set and the
137: * exponent is zero, the value is reserved.
138: */
139: /* ARGSUSED */
140: char *
141: checkfloat(fp, isdouble)
142: caddr_t fp;
143: int isdouble;
144: {
145:
146: return ((*(short *)fp & 0xff80) == 0x8000 ? "(reserved oprnd)" : NULL);
147: }
148:
149: /*
150: * Convert a value in `expr_t' format to float or double.
151: */
152: etofloat(e, fp, isdouble)
153: expr_t e;
154: caddr_t fp;
155: int isdouble;
156: {
157:
158: if (isdouble)
159: ((int *)fp)[1] = 0;
160: *(int *)fp = e;
161: }
162:
163: mch_init()
164: {
165:
166: mkioptab();
167: }
168:
169: /* quietly read object obj from address addr */
170: #define GET(obj, addr) (void) adbread(SP_DATA, addr, &(obj), sizeof(obj))
171:
172: /* set `current process' pcb */
173: setpcb(addr)
174: addr_t addr;
175: {
176: int pte;
177:
178: GET(pte, addr);
179: masterpcbb = (pte & PG_PFNUM) * NBPG;
180: }
181:
182: getpcb()
183: {
184:
185: /* maybe use adbread() here ... */
186: (void) readcore((off_t)masterpcbb & ~KERNBASE,
187: (char *)&pcb, sizeof(struct pcb));
188: pcb.pcb_p0lr &= ~AST_CLR;
189: adbprintf("p0br %R p0lr %R p1br %R p1lr %R\n",
190: pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
191: }
192:
193: /*
194: * Convert a kernel virtual address to a physical address,
195: * a la the VAX hardware. Set *err if the resulting address
196: * is invalid.
197: */
198: addr_t
199: vtophys(addr, err)
200: addr_t addr;
201: char **err;
202: {
203: register unsigned v = btop(addr & ~0xc0000000);
204: register addr_t pteaddr;
205: struct pte pte;
206: #define issys(a) ((a) & 0x80000000)
207: #define isp1(a) ((a) & 0x40000000)
208:
209: if (issys(addr)) {
210: /* system space: get system pte */
211: if (isp1(addr) || v >= slr) {
212: oor:
213: *err = "address out of segment";
214: return (0);
215: }
216: pteaddr = (addr_t)(sbr + v) & ~0x80000000;
217: } else {
218: if (isp1(addr)) {
219: /* P1 space: must not be in shadow region */
220: if (v < pcb.pcb_p1lr)
221: goto oor;
222: pteaddr = (addr_t)(pcb.pcb_p1br + v);
223: } else {
224: /* P0 space: must not be off end of region */
225: if (v >= pcb.pcb_p0lr)
226: goto oor;
227: pteaddr = (addr_t)(pcb.pcb_p0br + v);
228: }
229: if (!issys(pteaddr) || isp1(pteaddr)) {
230: *err = "bad p0br or p1br in pcb";
231: return (0);
232: }
233: /* in either case, find system pte by recursing */
234: pteaddr = vtophys(pteaddr, err);
235: if (*err)
236: return (0);
237: }
238:
239: /*
240: * Read system pte. If valid or reclaimable,
241: * physical address is combination of its page number and
242: * the page offset of the original address.
243: */
244: if (readcore((off_t)pteaddr, (caddr_t)&pte, 4) != 4) {
245: *err = "page table botch";
246: return (0);
247: }
248: /* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
249: if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
250: *err = "page not valid/reclaimable";
251: return (0);
252: }
253: return ((addr_t)(ptob(pte.pg_pfnum) + (addr & PGOFSET)));
254: }
255:
256: /*
257: * Print a stack trace ($c, $C). Trace backwards through nback
258: * frames; if locals is set, print local variables.
259: */
260: printstack(locals, nback)
261: int locals, nback;
262: {
263: register int i;
264: register addr_t a;
265: struct nlist *sym;
266: char *s;
267: /* addr_t callpc; /* pc that called this frame */
268: struct activation cur; /* this frame itself */
269: struct frame fr; /* the frame above this frame */
270: u_char narg; /* number of int-args to this frame */
271: addr_t dummy; /* a variable to scribble on */
272: #define UNKNOWN -1
273:
274: #ifdef RLOCALS
275: /* if locals variables are broken, use an alternate strategy */
276: register int r;
277: addr_t sp, prev_sp;
278: int regs[12];
279: static char unknown[] = "<unknown>";
280: #endif
281:
282: /* fr_savpc==UNKNOWN implies fr is invalid */
283: fr.fr_savpc = UNKNOWN;
284:
285: #ifdef RLOCALS
286: /* grab registers */
287: bcopy((caddr_t)(kcore ? &pcb.pcb_r0 : &u.u_ar0[R0]), (caddr_t)regs,
288: sizeof(regs));
289: #endif
290:
291: /* set up the current stack frame */
292: if (gavedot) {
293: GET(fr, cur.a_fp = dot);
294: checkerr();
295: if (fr.fr_s) { /* was a `calls'; can figure out ap */
296: cur.a_ap = cur.a_fp + sizeof(fr) + fr.fr_spa;
297: for (i = fr.fr_mask; i != 0; i >>= 1)
298: if (i & 1)
299: cur.a_ap += 4;
300: } else /* `callg': cannot find ap */
301: cur.a_ap = UNKNOWN;
302: cur.a_pc = UNKNOWN;
303: #ifdef RLOCALS
304: sp = UNKNOWN;
305: #endif
306: } else if (kcore) {
307: cur.a_ap = pcb.pcb_ap;
308: cur.a_fp = pcb.pcb_fp;
309: cur.a_pc = pcb.pcb_pc;
310: #ifdef RLOCALS
311: sp = pcb.pcb_ksp;
312: #endif
313: } else {
314: cur.a_ap = u.u_ar0[AP];
315: cur.a_fp = u.u_ar0[FP];
316: cur.a_pc = u.u_ar0[PC];
317: #ifdef RLOCALS
318: sp = u.u_ar0[SP];
319: #endif
320: }
321:
322: /* now back up through the stack */
323: while (nback--) {
324: if (fr.fr_savpc == UNKNOWN)
325: GET(fr, cur.a_fp);
326:
327: /* where are we? ... if u. area, signal trampoline code */
328: if ((int)cur.a_pc >= USRSTACK) {
329: /* GET(callpc, cur.a_fp + 92); /* XXX magic 92 */
330: s = "sigtramp";
331: } else {
332: /* callpc = fr.fr_savpc; */
333: if (cur.a_pc != UNKNOWN &&
334: (sym = findsym(cur.a_pc, SP_INSTR, &dummy)) != 0) {
335: s = sym->n_un.n_name;
336: if (eqstr(s, "start")) {
337: errflag = NULL;
338: break;
339: }
340: } else
341: s = "?";
342: }
343: adbprintf("%s(", s);
344: if ((a = cur.a_ap) != UNKNOWN) {
345: GET(narg, a);
346: for (i = narg > 20 ? 20 : narg; i;)
347: prfrom(a += 4, --i ? ',' : 0);
348: }
349: printc(')');
350: if (cur.a_pc != UNKNOWN) {
351: prints(" at ");
352: psymoff("%R", cur.a_pc, SP_INSTR, -(addr_t)1, "");
353: }
354: printc('\n');
355:
356: /* local variables */
357: if (locals) {
358: #ifdef busted
359: if (cur.a_pc != UNKNOWN) {
360: sym = findsym(cur.a_pc, SP_INSTR, &dummy);
361: while ((sym = nextlocal(sym)) != NULL) {
362: adbprintf("%8t");
363: printlsym(sym->n_un.n_name);
364: adbprintf(":%12t");
365: prfrom(eval_localsym(sym, &cur), '\n');
366: }
367: }
368: #endif
369: #ifdef RLOCALS
370: adbprintf("\
371: fp: %R\%16tap: %?s%?R%32tsp: %?s%?R%48tpc: %?s%?R\n\
372: r0: %R\%16tr1: %R\%32tr2: %R\%48tr3: %R\n\
373: r4: %R\%16tr5: %R\%32tr6: %R\%48tr7: %R\n\
374: r8: %R\%16tr9: %R\%32tr10: %R\%48tr11: %R\n",
375: #define q(s) s == UNKNOWN, unknown, s != UNKNOWN, s
376: cur.a_fp, q(cur.a_ap), q(sp), q(cur.a_pc),
377: #undef q
378: regs[0], regs[1], regs[2], regs[3],
379: regs[4], regs[5], regs[6], regs[7],
380: regs[8], regs[9], regs[10], regs[11]);
381:
382: /* update registers, and find previous frame's sp */
383: a = cur.a_fp + 16;
384: for (r = 0, i = fr.fr_mask; i != 0; r++, i >>= 1)
385: if (i & 1)
386: GET(regs[r], a += 4);
387: a += fr.fr_spa;
388: if (fr.fr_s)
389: a += narg * 4;
390: prev_sp = a;
391:
392: /* now print automatics */
393: if (sp != UNKNOWN) {
394: #define MAXPRINT 30 /* max # words to print */
395: /* XXX should be settable */
396: i = (cur.a_fp - sp) >> 2;
397: if (i > MAXPRINT)
398: i = MAXPRINT;
399: for (a = cur.a_fp; --i >= 0;) {
400: a -= 4;
401: adbprintf("%R: %V(fp):%24t",
402: a, a - cur.a_fp);
403: prfrom(a, '\n');
404: }
405: if (a > sp)
406: adbprintf("\
407: %R: %V(fp) .. %R: %V(fp) not displayed\n",
408: a, a - cur.a_fp,
409: sp, sp - cur.a_fp);
410: }
411: #endif /* RLOCALS */
412: }
413:
414: errflag = NULL; /* clobber any read errors */
415:
416: /* back up one frame */
417: if (fr.fr_savfp == 0)
418: break;
419: cur.a_ap = fr.fr_savap;
420: cur.a_fp = fr.fr_savfp;
421: #ifdef RLOCALS
422: sp = prev_sp;
423: #endif
424: cur.a_pc = fr.fr_savpc;
425: fr.fr_savpc = UNKNOWN; /* until we read it again */
426:
427: if (!gavedot && !INSTACK(cur.a_fp) && !kcore)
428: break;
429:
430: /* make sure we returned somewhere... */
431: (void) adbread(kcore ? SP_DATA : SP_INSTR, cur.a_pc, &dummy, 1);
432: checkerr();
433: }
434: }
435:
436: /*
437: * Register offset to u. pointer, and register offset to ptrace value
438: */
439: #define otoua(o) \
440: ((int *)(((o) < 0 ? (int)u.u_ar0 : (int)&u.u_pcb) + (o)))
441: #define otopt(o) \
442: ((int *)((o) < 0 ? (o) + ctob(UPAGES) : (o)))
443:
444: /*
445: * Return the value of some register.
446: */
447: expr_t
448: getreg(reg)
449: register struct reglist *reg;
450: {
451:
452: return (kcore ? *reg->r_pcbaddr : *otoua(reg->r_offset));
453: }
454:
455:
456: /*
457: * Set the value of some register. Return 0 if all goes well.
458: */
459: setreg(reg, val)
460: register struct reglist *reg;
461: expr_t val;
462: {
463:
464: if (kcore)
465: *reg->r_pcbaddr = val;
466: else {
467: *otoua(reg->r_offset) = val;
468: if (pid) {
469: errno = 0;
470: if (ptrace(PT_WRITE_U, pid, otopt(reg->r_offset),
471: (int)val) == -1 && errno)
472: return (-1);
473: }
474: }
475: return (0);
476: }
477:
478: /*
479: * Read registers from current process.
480: */
481: readregs()
482: {
483: register struct reglist *reg;
484: extern struct reglist reglist[];
485:
486: for (reg = reglist; reg->r_name != NULL; reg++)
487: *otoua(reg->r_offset) =
488: ptrace(PT_READ_U, pid, otopt(reg->r_offset), 0);
489: }
490:
491: addr_t
492: getpc()
493: {
494:
495: return (u.u_ar0[PC]);
496: }
497:
498: setpc(where)
499: addr_t where;
500: {
501:
502: u.u_ar0[PC] = where;
503: }
504:
505: /*
506: * udot returns true if u.u_pcb appears correct. More extensive
507: * checking is possible....
508: */
509: udot()
510: {
511:
512: /* user stack should be in stack segment */
513: if (!INSTACK(u.u_pcb.pcb_usp))
514: return (0);
515: /* kernel stack should be in u. area */
516: if (u.u_pcb.pcb_ksp < USRSTACK)
517: return (0);
518: /* looks good to us... */
519: return (1);
520: }
521:
522: sigprint()
523: {
524: extern char *sys_siglist[];
525: extern char *illinames[], *fpenames[];
526: extern int nillinames, nfpenames;
527:
528: if ((u_int)signo - 1 < NSIG - 1)
529: prints(sys_siglist[signo]);
530: switch (signo) {
531:
532: case SIGFPE:
533: if ((u_int)sigcode < nfpenames)
534: prints(fpenames[sigcode]);
535: break;
536:
537: case SIGILL:
538: if ((u_int)sigcode < nillinames)
539: prints(illinames[sigcode]);
540: break;
541: }
542: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.