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