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