130296Ssam /*
230296Ssam  * Copyright (c) 1986 Regents of the University of California.
330296Ssam  * All rights reserved.  The Berkeley software License Agreement
430296Ssam  * specifies the terms and conditions for redistribution.
530296Ssam  *
6*41340Ssklower  *	@(#)kdb_runpcs.c	7.4 (Berkeley) 05/03/90
730296Ssam  */
830112Ssam 
930112Ssam #include "../kdb/defs.h"
1030112Ssam 
11*41340Ssklower char	*kdblp;
1230112Ssam 
1330112Ssam /* breakpoints */
14*41340Ssklower BKPTR	kdbbkpthead;
1530112Ssam 
16*41340Ssklower char	kdblastc;
1730112Ssam 
18*41340Ssklower long	kdbdot;
19*41340Ssklower int	kdbadrflg;
20*41340Ssklower long	kdbloopcnt;
21*41340Ssklower ADDR	kdbuserpc = 1;
2230112Ssam 
kdbrunpcs(runmode,execsig)23*41340Ssklower kdbrunpcs(runmode, execsig)
2430112Ssam {
2530112Ssam 	register BKPTR bkpt;
2630112Ssam 
27*41340Ssklower 	if (kdbadrflg)
28*41340Ssklower 		kdbuserpc = kdbdot;
2930112Ssam 	if (execsig == 0)
30*41340Ssklower 		kdbprintf("kdb: running\n");
3130112Ssam 	if (runmode==SINGLE) {
3230112Ssam 		/*
3330112Ssam 		 * To single step, delete the
3430112Ssam 		 * breakpoints and invoke the
3530112Ssam 		 * hardware single step in the
3630112Ssam 		 * main loop.
3730112Ssam 		 */
38*41340Ssklower 		kdbdelbp();
3930112Ssam 		reset(SINGLE);
4030112Ssam 	}
4130112Ssam 	/*
4230112Ssam 	 * If we're currently at a breakpoint,
4330112Ssam 	 * restore the instruction and single
4430112Ssam 	 * step before continuing.  Otherwise,
4530112Ssam 	 * we can just set our breakpoints and
4630112Ssam 	 * continue.
4730112Ssam 	 */
48*41340Ssklower 	if (bkpt = kdbscanbkpt(kdbuserpc)) {
49*41340Ssklower 		kdbexecbkpt(bkpt);
5030112Ssam 		/*NOTREACHED*/
5130112Ssam 	}
52*41340Ssklower 	kdbsetbp();
5330112Ssam 	reset(CONTIN);
5430112Ssam }
5530112Ssam 
56*41340Ssklower static	int kdbexecbkptf;
5730112Ssam 
5830112Ssam /*
5930112Ssam  * Continue execution after a trap.
6030112Ssam  *
6130112Ssam  * If tracetrap is nonzero, we've entered here because of a
6230112Ssam  * trace trap.  If we're skipping a breakpoint (execbkptf),
6330112Ssam  * or this is the next iteration of a breakpoint, continue.
6430112Ssam  * If this is the next iteration of a single step, do the
6530112Ssam  * next step.  Otherwise return 1 if we stopped because
6630112Ssam  * of a breakpoint,
6730112Ssam  */
kdbnextpcs(tracetrap)68*41340Ssklower kdbnextpcs(tracetrap)
6930296Ssam 	int tracetrap;
7030112Ssam {
7130112Ssam 	register BKPTR bkpt;
7230112Ssam 	short rc;
7330112Ssam 
7430136Ssam 	clrsstep();			/* clear hardware single step */
75*41340Ssklower 	kdbdelbp();
76*41340Ssklower 	if (kdbexecbkptf) {
77*41340Ssklower 		kdbexecbkptf = 0;
78*41340Ssklower 		kdbrunpcs(CONTIN, 1);
7930112Ssam 		/*NOTREACHED*/
8030112Ssam 	}
81*41340Ssklower 	if (!tracetrap && (bkpt = kdbscanbkpt(kdbuserpc))) {
8230112Ssam 		/*
8330112Ssam 		 * Stopped at a breakpoint,
8430112Ssam 		 * execute any command.
8530112Ssam 		 */
86*41340Ssklower 		kdbdot = bkpt->loc;
8730112Ssam 		if (bkpt->flag == BKPTEXEC ||
8830112Ssam 		    ((bkpt->flag = BKPTEXEC) && bkpt->comm[0] != EOR &&
89*41340Ssklower 		    kdbcommand(bkpt->comm, ':') && --bkpt->count)) {
90*41340Ssklower 			kdbloopcnt++;
91*41340Ssklower 			kdbexecbkpt(bkpt);
9230112Ssam 		} else {
9330112Ssam 			bkpt->count = bkpt->initcnt;
9430112Ssam 			rc = 1;
9530112Ssam 		}
9630296Ssam 	} else
9730112Ssam 		rc = 0;
98*41340Ssklower 	if (--kdbloopcnt > 0)
99*41340Ssklower 		kdbrunpcs(rc ? CONTIN : SINGLE, 1);
10030112Ssam 	return (rc);
10130112Ssam }
10230112Ssam 
10330112Ssam #define BPOUT 0
10430112Ssam #define BPIN 1
105*41340Ssklower static	int kdbbpstate = BPOUT;
10630112Ssam 
kdbexecbkpt(bkptr)107*41340Ssklower kdbexecbkpt(bkptr)
10830112Ssam 	BKPTR	bkptr;
10930112Ssam {
11030112Ssam 
111*41340Ssklower 	kdbdelbp();
11230136Ssam 	bkptr->flag = BKPTSET;
113*41340Ssklower 	kdbexecbkptf++;
11430112Ssam 	reset(SINGLE);
11530112Ssam }
11630112Ssam 
11730112Ssam BKPTR
kdbscanbkpt(addr)118*41340Ssklower kdbscanbkpt(addr)
11930112Ssam 	ADDR addr;
12030112Ssam {
12130112Ssam 	register BKPTR	bkptr;
12230112Ssam 
123*41340Ssklower 	for (bkptr = kdbbkpthead; bkptr; bkptr = bkptr->nxtbkpt)
12430136Ssam 		if (bkptr->flag && bkptr->loc == addr)
12530112Ssam 			break;
12630112Ssam 	return (bkptr);
12730112Ssam }
12830112Ssam 
kdbdelbp()129*41340Ssklower kdbdelbp()
13030112Ssam {
13130296Ssam 	register off_t a;
13230112Ssam 	register BKPTR bkptr;
13330112Ssam 
134*41340Ssklower 	if (kdbbpstate == BPOUT)
13530112Ssam 		return;
136*41340Ssklower 	for (bkptr = kdbbkpthead; bkptr; bkptr = bkptr->nxtbkpt)
13730112Ssam 		if (bkptr->flag) {
13830136Ssam 			a = bkptr->loc;
139*41340Ssklower 			kdbput((off_t)a, ISP, (long)bkptr->ins);
14030112Ssam 		}
141*41340Ssklower 	kdbbpstate = BPOUT;
14230112Ssam }
14330112Ssam 
kdbsetbp()144*41340Ssklower kdbsetbp()
14530112Ssam {
14630296Ssam 	register off_t a;
14730112Ssam 	register BKPTR bkptr;
14830112Ssam 
149*41340Ssklower 	if (kdbbpstate == BPIN)
15030112Ssam 		return;
151*41340Ssklower 	for (bkptr = kdbbkpthead; bkptr; bkptr = bkptr->nxtbkpt)
15230112Ssam 		if (bkptr->flag) {
15330112Ssam 			a = bkptr->loc;
154*41340Ssklower 			bkptr->ins = kdbget(a, ISP);
155*41340Ssklower 			kdbput(a, ISP, (long)SETBP(bkptr->ins));
15630112Ssam 		}
157*41340Ssklower 	kdbbpstate = BPIN;
15830112Ssam }
159