1 #ifndef lint 2 static char sccsid[] = "@(#)machdep.c 5.3 (Berkeley) 09/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 } 543