1 /*
2  * Copyright (c) 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)kdb_runpcs.c	7.4 (Berkeley) 05/03/90
7  */
8 
9 #include "../kdb/defs.h"
10 
11 char	*kdblp;
12 
13 /* breakpoints */
14 BKPTR	kdbbkpthead;
15 
16 char	kdblastc;
17 
18 long	kdbdot;
19 int	kdbadrflg;
20 long	kdbloopcnt;
21 ADDR	kdbuserpc = 1;
22 
23 kdbrunpcs(runmode, execsig)
24 {
25 	register BKPTR bkpt;
26 
27 	if (kdbadrflg)
28 		kdbuserpc = kdbdot;
29 	if (execsig == 0)
30 		kdbprintf("kdb: running\n");
31 	if (runmode==SINGLE) {
32 		/*
33 		 * To single step, delete the
34 		 * breakpoints and invoke the
35 		 * hardware single step in the
36 		 * main loop.
37 		 */
38 		kdbdelbp();
39 		reset(SINGLE);
40 	}
41 	/*
42 	 * If we're currently at a breakpoint,
43 	 * restore the instruction and single
44 	 * step before continuing.  Otherwise,
45 	 * we can just set our breakpoints and
46 	 * continue.
47 	 */
48 	if (bkpt = kdbscanbkpt(kdbuserpc)) {
49 		kdbexecbkpt(bkpt);
50 		/*NOTREACHED*/
51 	}
52 	kdbsetbp();
53 	reset(CONTIN);
54 }
55 
56 static	int kdbexecbkptf;
57 
58 /*
59  * Continue execution after a trap.
60  *
61  * If tracetrap is nonzero, we've entered here because of a
62  * trace trap.  If we're skipping a breakpoint (execbkptf),
63  * or this is the next iteration of a breakpoint, continue.
64  * If this is the next iteration of a single step, do the
65  * next step.  Otherwise return 1 if we stopped because
66  * of a breakpoint,
67  */
68 kdbnextpcs(tracetrap)
69 	int tracetrap;
70 {
71 	register BKPTR bkpt;
72 	short rc;
73 
74 	clrsstep();			/* clear hardware single step */
75 	kdbdelbp();
76 	if (kdbexecbkptf) {
77 		kdbexecbkptf = 0;
78 		kdbrunpcs(CONTIN, 1);
79 		/*NOTREACHED*/
80 	}
81 	if (!tracetrap && (bkpt = kdbscanbkpt(kdbuserpc))) {
82 		/*
83 		 * Stopped at a breakpoint,
84 		 * execute any command.
85 		 */
86 		kdbdot = bkpt->loc;
87 		if (bkpt->flag == BKPTEXEC ||
88 		    ((bkpt->flag = BKPTEXEC) && bkpt->comm[0] != EOR &&
89 		    kdbcommand(bkpt->comm, ':') && --bkpt->count)) {
90 			kdbloopcnt++;
91 			kdbexecbkpt(bkpt);
92 		} else {
93 			bkpt->count = bkpt->initcnt;
94 			rc = 1;
95 		}
96 	} else
97 		rc = 0;
98 	if (--kdbloopcnt > 0)
99 		kdbrunpcs(rc ? CONTIN : SINGLE, 1);
100 	return (rc);
101 }
102 
103 #define BPOUT 0
104 #define BPIN 1
105 static	int kdbbpstate = BPOUT;
106 
107 kdbexecbkpt(bkptr)
108 	BKPTR	bkptr;
109 {
110 
111 	kdbdelbp();
112 	bkptr->flag = BKPTSET;
113 	kdbexecbkptf++;
114 	reset(SINGLE);
115 }
116 
117 BKPTR
118 kdbscanbkpt(addr)
119 	ADDR addr;
120 {
121 	register BKPTR	bkptr;
122 
123 	for (bkptr = kdbbkpthead; bkptr; bkptr = bkptr->nxtbkpt)
124 		if (bkptr->flag && bkptr->loc == addr)
125 			break;
126 	return (bkptr);
127 }
128 
129 kdbdelbp()
130 {
131 	register off_t a;
132 	register BKPTR bkptr;
133 
134 	if (kdbbpstate == BPOUT)
135 		return;
136 	for (bkptr = kdbbkpthead; bkptr; bkptr = bkptr->nxtbkpt)
137 		if (bkptr->flag) {
138 			a = bkptr->loc;
139 			kdbput((off_t)a, ISP, (long)bkptr->ins);
140 		}
141 	kdbbpstate = BPOUT;
142 }
143 
144 kdbsetbp()
145 {
146 	register off_t a;
147 	register BKPTR bkptr;
148 
149 	if (kdbbpstate == BPIN)
150 		return;
151 	for (bkptr = kdbbkpthead; bkptr; bkptr = bkptr->nxtbkpt)
152 		if (bkptr->flag) {
153 			a = bkptr->loc;
154 			bkptr->ins = kdbget(a, ISP);
155 			kdbput(a, ISP, (long)SETBP(bkptr->ins));
156 		}
157 	kdbbpstate = BPIN;
158 }
159