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