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