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