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