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