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
kdbrunpcs(runmode,execsig)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 */
kdbnextpcs(tracetrap)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
kdbexecbkpt(bkptr)107 kdbexecbkpt(bkptr)
108 BKPTR bkptr;
109 {
110
111 kdbdelbp();
112 bkptr->flag = BKPTSET;
113 kdbexecbkptf++;
114 reset(SINGLE);
115 }
116
117 BKPTR
kdbscanbkpt(addr)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
kdbdelbp()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
kdbsetbp()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