xref: /csrg-svn/old/adb/adb.tahoe/machdep.c (revision 47819)
1*47819Sbostic /*-
2*47819Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*47819Sbostic  * All rights reserved.
4*47819Sbostic  *
5*47819Sbostic  * %sccs.include.proprietary.c%
6*47819Sbostic  */
7*47819Sbostic 
836560Sbostic #ifndef lint
9*47819Sbostic static char sccsid[] = "@(#)machdep.c	5.5 (Berkeley) 04/04/91";
10*47819Sbostic #endif /* not lint */
1136560Sbostic 
1236560Sbostic /*
1336560Sbostic  * adb - miscellaneous machine dependent routines.
1436560Sbostic  */
1536560Sbostic 
1636560Sbostic #define	RLOCALS			/* enable alternate $C stack trace */
1736560Sbostic 
1836560Sbostic #include "defs.h"
1936560Sbostic #include "bkpt.h"
2036560Sbostic #include <machine/pte.h>
2136560Sbostic #include <machine/frame.h>
2236560Sbostic #include <machine/reg.h>
2336560Sbostic #include <machine/vmparam.h>
2436560Sbostic #include <sys/ptrace.h>
2536560Sbostic #include <sys/vmmac.h>
2636560Sbostic #include <stab.h>
2736560Sbostic 
2836560Sbostic struct	pte *sbr;
2936560Sbostic int	slr;
3036560Sbostic struct	pcb pcb;
3136560Sbostic int	masterpcbb;
3236560Sbostic 
3336560Sbostic /*
3436560Sbostic  * Activation records.
3536560Sbostic  */
3636560Sbostic 
3736560Sbostic /*
3836560Sbostic  * Set up a stack frame based on the registers in the core image
3936560Sbostic  * (or in the kernel core file ... not yet!).
4036560Sbostic  */
a_init(ap)4136560Sbostic a_init(ap)
4236560Sbostic 	register struct activation *ap;
4336560Sbostic {
4436560Sbostic 
4536560Sbostic 	ap->a_valid = 1;
4636560Sbostic 	if (kcore) {
4736560Sbostic 		ap->a_fp = pcb.pcb_fp;
4836560Sbostic 		ap->a_pc = pcb.pcb_pc;
4936560Sbostic 	} else {
5036560Sbostic 		ap->a_fp = u.u_ar0[FP];
5136560Sbostic 		ap->a_pc = u.u_ar0[PC];
5236560Sbostic 	}
5336560Sbostic }
5436560Sbostic 
5536560Sbostic /*
5636560Sbostic  * Back up one stack frame in the call stack.
5736560Sbostic  * ap points to the activation record from the previous frame.
5836560Sbostic  * Clear a_valid field if we ran out of frames.
5936560Sbostic  */
a_back(ap)6036560Sbostic a_back(ap)
6136560Sbostic 	register struct activation *ap;
6236560Sbostic {
6336560Sbostic 	struct frame fr;
6436560Sbostic 
6536560Sbostic 	if (adbread(SP_DATA, ap->a_fp - FRAMEOFF, &fr, sizeof fr) != sizeof fr)
6636560Sbostic 		ap->a_valid = 0;
6736560Sbostic 	else {
6836560Sbostic 		ap->a_fp = fr.fr_savfp;
6936560Sbostic 		ap->a_pc = fr.fr_savpc;
7036560Sbostic 		if (ap->a_fp == 0)
7136560Sbostic 			ap->a_valid = 0;
7236560Sbostic 	}
7336560Sbostic }
7436560Sbostic 
7536560Sbostic /*
7636560Sbostic  * Evaluate a local symbol (N_LSYM or N_PSYM) using the activation
7736560Sbostic  * record pointed to by ap.
7836560Sbostic  */
7936560Sbostic addr_t
eval_localsym(sp,ap)8036560Sbostic eval_localsym(sp, ap)
8136560Sbostic 	register struct nlist *sp;
8236560Sbostic 	struct activation *ap;
8336560Sbostic {
8436560Sbostic 
8536560Sbostic 	switch (sp->n_type) {
8636560Sbostic 
8736560Sbostic 	case N_LSYM:
8836560Sbostic 		return (ap->a_fp - sp->n_value);
8936560Sbostic 
9036560Sbostic 	case N_PSYM:
9136560Sbostic 		return (ap->a_fp + sp->n_value);
9236560Sbostic 	}
9336560Sbostic 	panic("eval_localsym");
9436560Sbostic 	/* NOTREACHED */
9536560Sbostic }
9636560Sbostic 
9736560Sbostic 
9836560Sbostic /* true iff address a is in instruction space */
9936560Sbostic #define	ispace(a) ((a) < txtmap.m1.e)
10036560Sbostic 
10136560Sbostic /*
10236560Sbostic  * Delete a (single) breakpoint.  Return 0 on success.
10336560Sbostic  */
10436560Sbostic int
clr_bpt(b)10536560Sbostic clr_bpt(b)
10636560Sbostic 	struct bkpt *b;
10736560Sbostic {
10836560Sbostic 	addr_t a = b->loc;
10936560Sbostic 
11036560Sbostic 	return (adbwrite(ispace(a) ? SP_INSTR : SP_DATA, a, &b->ins, 1) != 1);
11136560Sbostic }
11236560Sbostic 
11336560Sbostic /*
11436560Sbostic  * Set a (single) breakpoint.  Return 0 on success.
11536560Sbostic  */
11636560Sbostic set_bpt(b)
11736560Sbostic 	struct bkpt *b;
11836560Sbostic {
11936560Sbostic 	addr_t a = b->loc;
12036560Sbostic 	int space;
12136560Sbostic 	char bpt = 0x30;		/* breakpoint instruction */
12236560Sbostic 
12336560Sbostic 	space = ispace(a) ? SP_INSTR : SP_DATA;
12436560Sbostic 	return (adbread(space, a, &b->ins, 1) != 1 ||
12536560Sbostic 		adbwrite(space, a, &bpt, 1) != 1);
12636560Sbostic }
12736560Sbostic 
12836560Sbostic /*
12936560Sbostic  * Check a float for `correctness' (reserved patterns, etc).  Return
13036560Sbostic  * a pointer to a character string to be printed instead of the float,
13136560Sbostic  * or NULL to print the float as-is.
13236560Sbostic  *
13336560Sbostic  * The string returned, if any, should be no longer than 16 characters.
13436560Sbostic  *
13536560Sbostic  * On the Tahoe, we can simply check the second two bytes.  Byte two
13636560Sbostic  * contains one bit of the exponent, and byte 3 has the remaining 7
13736560Sbostic  * exponent bits and the sign bit.  If the sign bit is set and the
13836560Sbostic  * exponent is zero, the value is reserved.
13936560Sbostic  *
14036560Sbostic  * PLEASE CHECK THE ABOVE, IT IS PROBABLY WRONG
14136560Sbostic  */
14236560Sbostic /* ARGSUSED */
14336560Sbostic char *
checkfloat(fp,isdouble)14436560Sbostic checkfloat(fp, isdouble)
14536560Sbostic 	caddr_t fp;
14636560Sbostic 	int isdouble;
14736560Sbostic {
14836560Sbostic 
14936560Sbostic 	return ((((short *)fp)[1] & 0xff80) == 0x8000 ?
15036560Sbostic 		"(reserved oprnd)" : NULL);
15136560Sbostic }
15236560Sbostic 
15336560Sbostic /*
15436560Sbostic  * Convert a value in `expr_t' format to float or double.
15536560Sbostic  */
etofloat(e,fp,isdouble)15636560Sbostic etofloat(e, fp, isdouble)
15736560Sbostic 	expr_t e;
15836560Sbostic 	caddr_t fp;
15936560Sbostic 	int isdouble;
16036560Sbostic {
16136560Sbostic 
16236560Sbostic 	if (isdouble)
16336560Sbostic 		((int *)fp)[1] = 0;
16436560Sbostic 	*(int *)fp = e;
16536560Sbostic }
16636560Sbostic 
mch_init()16736560Sbostic mch_init()
16836560Sbostic {
16936560Sbostic 
17036560Sbostic 	mkioptab();
17136560Sbostic }
17236560Sbostic 
17336560Sbostic /* quietly read object obj from address addr */
17436560Sbostic #define	GET(obj, addr)	(void) adbread(SP_DATA, addr, &(obj), sizeof(obj))
17536560Sbostic 
17636560Sbostic /* set `current process' pcb */
setpcb(addr)17736560Sbostic setpcb(addr)
17836560Sbostic 	addr_t addr;
17936560Sbostic {
18036560Sbostic 	int pte;
18136560Sbostic 
18236560Sbostic 	GET(pte, addr);
18336560Sbostic 	masterpcbb = (pte & PG_PFNUM) * NBPG;
18436560Sbostic }
18536560Sbostic 
getpcb()18636560Sbostic getpcb()
18736560Sbostic {
18836560Sbostic 
18936560Sbostic 	/* maybe use adbread() here ... */
19036560Sbostic 	(void) readcore((off_t)masterpcbb & ~KERNBASE,
19136560Sbostic 		(char *)&pcb, sizeof(struct pcb));
19236560Sbostic 	adbprintf("p0br %R p0lr %R p2br %R p2lr %R\n",
19336560Sbostic 	    pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p2br, pcb.pcb_p2lr);
19436560Sbostic }
19536560Sbostic 
19636560Sbostic /*
19736560Sbostic  * Convert a kernel virtual address to a physical address,
19836560Sbostic  * a la the Tahoe hardware.  Set *err if the resulting address
19936560Sbostic  * is invalid.
20036560Sbostic  */
20136560Sbostic addr_t
vtophys(addr,err)20236560Sbostic vtophys(addr, err)
20336560Sbostic 	addr_t addr;
20436560Sbostic 	char **err;
20536560Sbostic {
20636560Sbostic 	register unsigned v = btop(addr & ~KERNBASE);
20736560Sbostic 	register addr_t pteaddr;
20836560Sbostic 	struct pte pte;
20936560Sbostic 
21036560Sbostic 	switch ((int)(addr >> 30)) {	/* select space */
21136560Sbostic 
21236560Sbostic 	case 3:
21336560Sbostic 		/* system space: get system pte */
21436560Sbostic 		if (v >= slr)
21536560Sbostic 			goto oor;
21636560Sbostic 		pteaddr = (addr_t)(sbr + v) & ~KERNBASE;
21736560Sbostic 		goto direct;
21836560Sbostic 
21936560Sbostic 	case 2:
22036560Sbostic 		/* P2 space: must not be in shadow region */
22136560Sbostic 		if (v < pcb.pcb_p2lr)
22236560Sbostic 			goto oor;
22336560Sbostic 		pteaddr = (addr_t)(pcb.pcb_p2br + v);
22436560Sbostic 		break;
22536560Sbostic 
22636560Sbostic 	case 1:
22736560Sbostic 		/* P1 space: verboten (for now) */
22836560Sbostic 		goto oor;
22936560Sbostic 
23036560Sbostic 	case 0:
23136560Sbostic 		/* P0 space: must not be off end of region */
23236560Sbostic 		if (v >= pcb.pcb_p0lr)
23336560Sbostic 			goto oor;
23436560Sbostic 		pteaddr = (addr_t)(pcb.pcb_p0br + v);
23536560Sbostic 		break;
23636560Sbostic 
23736560Sbostic oor:
23836560Sbostic 		*err = "address out of segment";
23936560Sbostic 		return (0);
24036560Sbostic 	}
24136560Sbostic 
24236560Sbostic 	/* in P0/P1/P2 space, pte should be in kernel virtual space */
24336560Sbostic 	if ((pteaddr & KERNBASE) != KERNBASE) {
24436560Sbostic 		*err = "bad p0br, p1br, or p2br in pcb";
24536560Sbostic 		return (0);
24636560Sbostic 	}
24736560Sbostic 	pteaddr = vtophys(pteaddr, err);
24836560Sbostic 	if (*err)
24936560Sbostic 		return (0);
25036560Sbostic 
25136560Sbostic direct:
25236560Sbostic 	/*
25336560Sbostic 	 * Read system pte.  If valid or reclaimable,
25436560Sbostic 	 * physical address is combination of its page number and
25536560Sbostic 	 * the page offset of the original address.
25636560Sbostic 	 */
25736560Sbostic 	if (readcore((off_t)pteaddr, (caddr_t)&pte, 4) != 4) {
25836560Sbostic 		*err = "page table botch";
25936560Sbostic 		return (0);
26036560Sbostic 	}
26136560Sbostic 	/* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
26236560Sbostic 	if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
26336560Sbostic 		*err = "page not valid/reclaimable";
26436560Sbostic 		return (0);
26536560Sbostic 	}
26636560Sbostic 	return ((addr_t)(ptob(pte.pg_pfnum) + (addr & PGOFSET)));
26736560Sbostic }
26836560Sbostic 
26936560Sbostic /*
27036560Sbostic  * Print a stack trace ($c, $C).  Trace backwards through nback
27136560Sbostic  * frames; if locals is set, print local variables.
27236560Sbostic  */
printstack(locals,nback)27336560Sbostic printstack(locals, nback)
27436560Sbostic 	int locals, nback;
27536560Sbostic {
27636560Sbostic 	register int i;
27736560Sbostic 	register addr_t a;
27836560Sbostic 	struct nlist *sym;
27936560Sbostic 	char *s;
28036560Sbostic 	addr_t callpc;		/* pc that called this frame */
28136560Sbostic 	int narg;		/* number of arguments to this frame */
28236560Sbostic 	struct activation cur;	/* this frame itself */
28336560Sbostic 	struct frame fr;	/* the frame above this frame */
28436560Sbostic 	addr_t dummy;		/* a variable to scribble on */
28536560Sbostic #define	UNKNOWN	-1
28636560Sbostic 
28736560Sbostic #ifdef RLOCALS
28836560Sbostic 	/* if locals variables are broken, use an alternate strategy */
28936560Sbostic 	register int r;
29036560Sbostic 	addr_t sp, prev_sp;
29136560Sbostic 	int regs[13];
29236560Sbostic 	static char unknown[] = "<unknown>";
29336560Sbostic #endif
29436560Sbostic 
29536560Sbostic #ifdef RLOCALS
29636560Sbostic 	/* grab registers */
29736560Sbostic 	bcopy((caddr_t)(kcore ? &pcb.pcb_r0 : &u.u_ar0[R0]), (caddr_t)regs,
29836560Sbostic 		sizeof(regs));
29936560Sbostic #endif
30036560Sbostic 
30136560Sbostic 	/* set up the current stack frame */
30236560Sbostic 	if (gavedot) {
30336560Sbostic 		cur.a_fp = dot;
30436560Sbostic 		cur.a_pc = UNKNOWN;
30536560Sbostic #ifdef RLOCALS
30636560Sbostic 		sp = UNKNOWN;
30736560Sbostic #endif
30836560Sbostic 	} else if (kcore) {
30936560Sbostic 		cur.a_fp = pcb.pcb_fp;
31036560Sbostic 		cur.a_pc = pcb.pcb_pc;
31136560Sbostic #ifdef RLOCALS
31236560Sbostic 		sp = pcb.pcb_ksp;
31336560Sbostic #endif
31436560Sbostic 	} else {
31536560Sbostic 		cur.a_fp = u.u_ar0[FP];
31636560Sbostic 		cur.a_pc = u.u_ar0[PC];
31736560Sbostic #ifdef RLOCALS
31836560Sbostic 		sp = u.u_ar0[SP];
31936560Sbostic #endif
32036560Sbostic 	}
32136560Sbostic 
32236560Sbostic 	/* now back up through the stack */
32336560Sbostic 	while (nback-- && cur.a_fp != 0) {
32436560Sbostic 		/* read this frame, but defer error check */
32536560Sbostic 		GET(fr, cur.a_fp - FRAMEOFF);
32636560Sbostic 
32736560Sbostic 		/* where are we? ... if u. area, signal trampoline code */
32836560Sbostic 		if (cur.a_pc >= USRSTACK && cur.a_pc < KERNBASE) {
32936560Sbostic 			narg = 0;
33036560Sbostic 			GET(callpc, cur.a_fp + 44);	/* XXX magic 44 */
33136560Sbostic 			s = "sigtramp";
33236560Sbostic 		} else {
33336560Sbostic 			narg = (fr.fr_removed >> 2) - 1;
33436560Sbostic 			callpc = fr.fr_savpc;
33536560Sbostic 			if (cur.a_pc != UNKNOWN &&
33636560Sbostic 			    (sym = findsym(cur.a_pc, SP_INSTR, &dummy)) != 0) {
33736560Sbostic 				s = sym->n_un.n_name;
33836560Sbostic 				if (eqstr(s, "start")) {
33936560Sbostic 					errflag = NULL;
34036560Sbostic 					break;
34136560Sbostic 				}
34236560Sbostic 			} else
34336560Sbostic 				s = "?";
34436560Sbostic 		}
34536560Sbostic 		/* safe at last to check for error reading frame */
34636560Sbostic 		checkerr();
34736560Sbostic 
34836560Sbostic 		/* arguments */
34936560Sbostic 		adbprintf("%s(", s);
35036560Sbostic 		a = cur.a_fp;
35139223Storek 		for (i = narg > 20 ? 20 : narg; i;) {
35236560Sbostic 			prfrom(a += 4, --i ? ',' : 0);
35336560Sbostic 			checkerr();
35436560Sbostic 		}
35536560Sbostic 		printc(')');
35636560Sbostic 		if (cur.a_pc != UNKNOWN) {
35736560Sbostic 			prints(" at ");
35836560Sbostic 			psymoff("%R", cur.a_pc, SP_INSTR, -(addr_t)1, "");
35936560Sbostic 		}
36036560Sbostic 		printc('\n');
36136560Sbostic 
36236560Sbostic 		/* local variables */
36336560Sbostic 		if (locals) {
36436560Sbostic #ifdef busted
36536560Sbostic 			if (cur.a_pc != UNKNOWN) {
36636560Sbostic 				sym = findsym(cur.a_pc, SP_INSTR, &dummy);
36736560Sbostic 				while ((sym = nextlocal(sym)) != NULL) {
36836560Sbostic 					adbprintf("%8t");
36936560Sbostic 					printlsym(sym->n_un.n_name);
37036560Sbostic 					adbprintf(":%12t");
37136560Sbostic 					prfrom(eval_localsym(sym, &cur), '\n');
37236560Sbostic 				}
37336560Sbostic 			}
37436560Sbostic #endif
37536560Sbostic #ifdef RLOCALS
37636560Sbostic 			adbprintf("\
37736574Storek fp: %R\%16tsp:  %?s%?R%32tpc:  %?s%?R%48tr0:  %R\n\
37836574Storek r1: %R\%16tr2:  %R\%32tr3:  %R\%48tr4:  %R\n\
37936574Storek r5: %R\%16tr6:  %R\%32tr7:  %R\%48tr8:  %R\n\
38036574Storek r9: %R\%16tr10: %R\%32tr11: %R\%48tr12: %R\n",
38136560Sbostic #define q(s) s == UNKNOWN, unknown, s != UNKNOWN, s
38236560Sbostic 			    cur.a_fp, q(sp), q(cur.a_pc), regs[0],
38336560Sbostic #undef q
38436560Sbostic 			    regs[1], regs[2], regs[3], regs[4],
38536560Sbostic 			    regs[5], regs[6], regs[7], regs[8],
38636560Sbostic 			    regs[9], regs[10], regs[11], regs[12]);
38736560Sbostic 
38836560Sbostic 			/* update registers, and find previous frame's sp */
38936560Sbostic 			a = cur.a_fp + 4;
39036560Sbostic 			for (r = 0, i = fr.fr_mask; i != 0; r++, i >>= 1)
39136560Sbostic 				if (i & 1)
39236560Sbostic 					GET(regs[r], a += 4);
39336560Sbostic 			a += narg * 4;
39436560Sbostic 			prev_sp = a;
39536560Sbostic 
39636560Sbostic 			/* now print automatics */
39736560Sbostic 			if (sp != UNKNOWN) {
39836560Sbostic #define	MAXPRINT 30		/* max # words to print */
39936560Sbostic 				/* XXX should be settable */
40036560Sbostic 				i = (cur.a_fp - sp) >> 2;
40136560Sbostic 				if (i > MAXPRINT)
40236560Sbostic 					i = MAXPRINT;
40336560Sbostic 				for (a = cur.a_fp; --i >= 0;) {
40436560Sbostic 					a -= 4;
40536560Sbostic 					adbprintf("%R: %V(fp):%24t",
40636560Sbostic 						a, a - cur.a_fp);
40736560Sbostic 					prfrom(a, '\n');
40836560Sbostic 				}
40936560Sbostic 				if (a > sp)
41036560Sbostic 					adbprintf("\
41136560Sbostic %R: %V(fp) .. %R: %V(fp) not displayed\n",
41236560Sbostic 						a, a - cur.a_fp,
41336560Sbostic 						sp, sp - cur.a_fp);
41436560Sbostic 			}
41536560Sbostic #endif /* RLOCALS */
41636560Sbostic 		}
41736560Sbostic 
41836560Sbostic 		errflag = NULL;		/* clobber any read errors */
41936560Sbostic 
42036560Sbostic 		/* back up one frame */
42136560Sbostic 		if (fr.fr_savfp == 0)
42236560Sbostic 			break;
42336560Sbostic 		cur.a_fp = fr.fr_savfp;
42436560Sbostic #ifdef RLOCALS
42536560Sbostic 		sp = prev_sp;
42636560Sbostic #endif
42736560Sbostic 		cur.a_pc = callpc;
42836560Sbostic 
42936560Sbostic 		if (!gavedot && !INSTACK(cur.a_fp) && !kcore)
43036560Sbostic 			break;
43136560Sbostic 
43236560Sbostic 		/* make sure we returned somewhere... */
43336560Sbostic 		(void) adbread(kcore ? SP_DATA : SP_INSTR, cur.a_pc, &dummy, 1);
43436560Sbostic 		checkerr();
43536560Sbostic 	}
43636560Sbostic }
43736560Sbostic 
43836560Sbostic /*
43936560Sbostic  * Register offset to u. pointer, and register offset to ptrace value
44036560Sbostic  */
44136560Sbostic #define	otoua(o) \
44236560Sbostic 	((int *)(((o) < 0 ? (int)u.u_ar0 : (int)&u.u_pcb) + (o)))
44336560Sbostic #define	otopt(o) \
44436560Sbostic 	((int *)((o) < 0 ? (o) + ctob(UPAGES) : (o)))
44536560Sbostic 
44636560Sbostic /*
44736560Sbostic  * Return the value of some register.
44836560Sbostic  */
44936560Sbostic expr_t
getreg(reg)45036560Sbostic getreg(reg)
45136560Sbostic 	register struct reglist *reg;
45236560Sbostic {
45336560Sbostic 
45436560Sbostic 	return (kcore ? *reg->r_pcbaddr : *otoua(reg->r_offset));
45536560Sbostic }
45636560Sbostic 
45736560Sbostic 
45836560Sbostic /*
45936560Sbostic  * Set the value of some register.  Return 0 if all goes well.
46036560Sbostic  */
setreg(reg,val)46136560Sbostic setreg(reg, val)
46236560Sbostic 	register struct reglist *reg;
46336560Sbostic 	expr_t val;
46436560Sbostic {
46536560Sbostic 
46636560Sbostic 	if (kcore)
46736560Sbostic 		*reg->r_pcbaddr = val;
46836560Sbostic 	else {
46936560Sbostic 		*otoua(reg->r_offset) = val;
47036560Sbostic 		if (pid) {
47136560Sbostic 			errno = 0;
47236560Sbostic 			if (ptrace(PT_WRITE_U, pid, otopt(reg->r_offset),
47336560Sbostic 					(int)val) == -1 && errno)
47436560Sbostic 				return (-1);
47536560Sbostic 		}
47636560Sbostic 	}
47736560Sbostic 	return (0);
47836560Sbostic }
47936560Sbostic 
48036560Sbostic /*
48136560Sbostic  * Read registers from current process.
48236560Sbostic  */
readregs()48336560Sbostic readregs()
48436560Sbostic {
48536560Sbostic 	register struct reglist *reg;
48636560Sbostic 	extern struct reglist reglist[];
48736560Sbostic 
48836560Sbostic 	for (reg = reglist; reg->r_name != NULL; reg++)
48936560Sbostic 		*otoua(reg->r_offset) =
49036560Sbostic 			ptrace(PT_READ_U, pid, otopt(reg->r_offset), 0);
49136560Sbostic }
49236560Sbostic 
49336560Sbostic addr_t
getpc()49436560Sbostic getpc()
49536560Sbostic {
49636560Sbostic 
49736560Sbostic 	return (kcore ? pcb.pcb_pc : u.u_ar0[PC]);
49836560Sbostic }
49936560Sbostic 
setpc(where)50036560Sbostic setpc(where)
50136560Sbostic 	addr_t where;
50236560Sbostic {
50336560Sbostic 
50436560Sbostic 	if (kcore)
50536560Sbostic 		pcb.pcb_pc = where;
50636560Sbostic 	else
50736560Sbostic 		u.u_ar0[PC] = where;
50836560Sbostic }
50936560Sbostic 
51036560Sbostic /*
51136560Sbostic  * udot returns true if u.u_pcb appears correct.  More extensive
51236560Sbostic  * checking is possible....
51336560Sbostic  */
udot()51436560Sbostic udot()
51536560Sbostic {
51636560Sbostic 
51736560Sbostic 	/* user stack should be in stack segment */
51836560Sbostic 	if (!INSTACK(u.u_pcb.pcb_usp))
51936560Sbostic 		return (0);
52036560Sbostic 	/* kernel stack should be in u. area */
52136560Sbostic 	if (u.u_pcb.pcb_ksp < USRSTACK || u.u_pcb.pcb_ksp >= KERNBASE)
52236560Sbostic 		return (0);
52336560Sbostic 	/* looks good to us... */
52436560Sbostic 	return (1);
52536560Sbostic }
52636560Sbostic 
sigprint()52736560Sbostic sigprint()
52836560Sbostic {
52936560Sbostic 	extern char *sys_siglist[];
53036560Sbostic 	extern char *illinames[], *fpenames[];
53136560Sbostic 	extern int nillinames, nfpenames;
53236560Sbostic 
53336560Sbostic 	if ((u_int)signo - 1 < NSIG - 1)
53436560Sbostic 		prints(sys_siglist[signo]);
53536560Sbostic 	switch (signo) {
53636560Sbostic 
53736560Sbostic 	case SIGFPE:
53836560Sbostic 		if ((u_int)sigcode < nfpenames)
53936560Sbostic 			prints(fpenames[sigcode]);
54036560Sbostic 		break;
54136560Sbostic 
54236560Sbostic 	case SIGILL:
54336560Sbostic 		if ((u_int)sigcode < nillinames)
54436560Sbostic 			prints(illinames[sigcode]);
54536560Sbostic 		break;
54636560Sbostic 	}
54736560Sbostic }
548