new copyright; att/bsd/shared
[unix-history] / usr / src / usr.bin / pascal / pdx / breakpoint / bpact.c
CommitLineData
505bf312
KB
1/*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
d8be300a 6 */
d1a17f17 7
d8be300a 8#ifndef lint
505bf312
KB
9static char sccsid[] = "@(#)bpact.c 5.2 (Berkeley) %G%";
10#endif /* not lint */
11
d1a17f17
ML
12/*
13 * Routines for doing the right thing when a breakpoint is reached.
14 */
15
16#include "defs.h"
17#include "breakpoint.h"
18#include "sym.h"
19#include "tree.h"
20#include "source.h"
21#include "mappings.h"
22#include "runtime.h"
23#include "process.h"
24#include "machine.h"
25#include "main.h"
26#include "bp.rep"
27#include "tree/tree.rep"
28
29typedef enum { SAVE, NOSAVE } SAVEBP;
30
31LOCAL SAVEBP handlebp();
32
33/*
34 * A "delayed" breakpoint is one that has an action involving execution
35 * of code, e.g. at a CALL we want to step from the beginning of the
36 * procedure to the first line before printing parameters.
37 */
38
39LOCAL short delayed;
40
41#define NONE 0
42#define DELAY_CALL 1
43#define DELAY_STOP 2
44
45/*
46 * Take action at a breakpoint; if it's not a breakpoint return FALSE.
47 *
48 * As we go through the list of breakpoints, we have to remember
49 * the previous one so that "handlebp" can delete breakpoints on
50 * the fly if necessary.
51 *
52 * If the breakpoint is a STOP_BP, handlebp will set "isstopped". After
53 * going through the loop, bpact checks if "isstopped" is set and calls
54 * printstatus if it is. This is so multiple breakpoints at the same
55 * address, one of which is a STOP_BP, still work.
56 */
57
58#define isswitch(bptype) ( \
59 bptype == ALL_ON || bptype == ALL_OFF || \
60 bptype == TERM_ON || bptype == TERM_OFF || \
61 bptype == BLOCK_ON || bptype == BLOCK_OFF || \
62 bptype == STOP_ON || bptype == STOP_OFF \
63)
64
65BOOLEAN bpact()
66{
67 register BPINFO *p;
68 BPINFO *prev, *next;
69 BOOLEAN found;
70 ADDRESS oldpc;
71
72 delayed = NONE;
73 found = FALSE;
74 prev = NIL;
75 for (p = bphead; p != NIL; p = next) {
76 next = p->bpnext;
77 if (p->bpaddr == pc) {
78 prbpfound(p);
79 found = TRUE;
80 if (p->bpcond == NIL || isswitch(p->bptype) || cond(p->bpcond)) {
81 prbphandled();
82 if (handlebp(p) == NOSAVE) {
83 prbpnosave();
84 if (prev == NIL) {
85 bphead = next;
86 } else {
87 prev->bpnext = next;
88 }
89 dispose(p);
90 } else {
91 prbpsave();
92 prev = p;
93 }
94 } else {
95 prev = p;
96 }
97 } else {
98 prev = p;
99 }
100 }
101 if (delayed != NONE) {
102 oldpc = pc;
103 runtofirst();
104 if ((delayed&DELAY_CALL) == DELAY_CALL) {
105 SYM *s, *t;
106
107 s = curfunc;
108 t = whatblock(return_addr());
109 if (t == NIL) {
110 panic("can't find block for caller addr %d", caller_addr());
111 }
112 printcall(s, t);
113 addbp(return_addr(), RETURN, s, NIL, NIL, 0);
114 }
115 if (pc != oldpc) {
116 bpact();
117 }
118 if (isstopped) {
119 printstatus();
120 }
121 } else {
122 if (isstopped) {
123 printstatus();
124 }
125 }
126 fflush(stdout);
127 return(found);
128}
129
130/*
131 * Handle an expected breakpoint appropriately, return whether
132 * or not to save the breakpoint.
133 */
134
135LOCAL SAVEBP handlebp(p)
136BPINFO *p;
137{
138 register SYM *s, *t;
139 SAVEBP r;
140
141 r = SAVE;
142 switch(p->bptype) {
143 case ALL_ON:
144 curfunc = p->bpblock;
145 addcond(TRPRINT, p->bpcond);
146 if (p->bpline >= 0) {
147 tracing++;
148 } else {
149 inst_tracing++;
150 }
151 addbp(return_addr(), ALL_OFF, curfunc, p->bpcond, NIL, 0);
152 break;
153
154 case ALL_OFF:
155 r = NOSAVE;
156 if (p->bpline >= 0) {
157 tracing--;
158 } else {
159 inst_tracing--;
160 }
161 delcond(TRPRINT, p->bpcond);
162 curfunc = p->bpblock;
163 break;
164
165 case STOP_ON:
166 var_tracing++;
167 curfunc = p->bpblock;
168 if (p->bpnode != NIL) {
169 addvar(TRSTOP, p->bpnode, p->bpcond);
170 } else if (p->bpcond != NIL) {
171 addcond(TRSTOP, p->bpcond);
172 }
173 addbp(return_addr(), STOP_OFF, curfunc, p->bpcond, p->bpnode, 0);
174 break;
175
176 case STOP_OFF:
177 r = NOSAVE;
178 delcond(TRSTOP, p->bpcond);
179 var_tracing--;
180 curfunc = p->bpblock;
181 break;
182
183 case INST:
184 curline = p->bpline;
185 if (curline > 0) {
186 printf("trace: ");
187 printlines(curline, curline);
188 } else {
189 printf("inst trace: ");
190 printinst(pc, pc);
191 }
192 break;
193
194 case STOP_BP:
195 if (p->bpblock != NIL) {
196 delayed |= DELAY_STOP;
197 curfunc = p->bpblock;
198 }
199 curline = p->bpline;
200 isstopped = TRUE;
201 break;
202
203 case BLOCK_ON: {
204 BPINFO *nbp;
205
206 s = p->bpblock;
207 t = p->bpnode->nameval;
208 nbp = newbp(codeloc(t), CALL, t, p->bpcond, NIL, 0);
209 addbp(return_addr(), BLOCK_OFF, (SYM *) nbp, NIL, NIL, 0);
210 break;
211 }
212
213 case BLOCK_OFF: {
214 BPINFO *oldbp;
215
216 r = NOSAVE;
217 oldbp = (BPINFO *) p->bpblock;
218 delbp(oldbp->bpid);
219 break;
220 }
221
222 case CALL:
223 delayed |= DELAY_CALL;
224 curfunc = p->bpblock;
225 break;
226
227 case RETURN:
228 r = NOSAVE;
229 s = p->bpblock;
230 printrtn(s);
231 break;
232
233 case TERM_ON: {
234 ADDRESS addr;
235
236 curfunc = p->bpblock;
237 addvar(TRPRINT, p->bpnode, p->bpcond);
238 addr = return_addr();
239 addbp(addr, TERM_OFF, curfunc, p->bpcond, p->bpnode, 0);
240 var_tracing++;
241 break;
242 }
243
244 case TERM_OFF:
245 r = NOSAVE;
246 var_tracing--;
247 delvar(TRPRINT, p->bpnode, p->bpcond);
248 curfunc = p->bpblock;
249 break;
250
251 case AT_BP:
252 printf("at line %d: ", p->bpline);
253 eval(p->bpnode);
254 prtree(p->bpnode);
255 printf(" = ");
256 printval(p->bpnode->nodetype);
257 putchar('\n');
258 break;
259
260 /*
261 * Returning from a called procedure.
262 * Further breakpoint processing is not done, since if
263 * there were any it wouldn't be associated with the call.
264 */
265 case CALLPROC:
266 procreturn(p->bpblock);
267 delbp(p->bpid);
268 erecover();
269 /* NOTREACHED */
270
271 case END_BP:
272 r = NOSAVE;
273 endprogram();
274
275 default:
276 panic("unknown bptype %d in cont", p->bptype);
277 /* NOTREACHED */
278 }
279 return(r);
280}
281
282/*
283 * Internal trace routines.
284 */
285
286LOCAL char *prbptype[] ={
287 "ALL_ON", "ALL_OFF", "INST", "CALL", "RETURN", "BLOCK_ON", "BLOCK_OFF",
288 "TERM_ON", "TERM_OFF", "AT_BP", "STOP_BP", "CALLPROC", "END_BP",
289 "STOP_ON", "STOP_OFF",
290};
291
292LOCAL prbpfound(p)
293BPINFO *p;
294{
295 if (option('b')) {
296 printf("%s breakpoint found at pc %d, line %d -- ",
297 prbptype[(int) p->bptype], p->bpaddr, p->bpline);
298 }
299}
300
301LOCAL prbphandled()
302{
303 if (option('b')) {
304 printf("handled, ");
305 }
306}
307
308LOCAL prbpnosave()
309{
310 if (option('b')) {
311 printf("not saved\n");
312 fflush(stdout);
313 }
314}
315
316LOCAL prbpsave()
317{
318 if (option('b')) {
319 printf("saved\n");
320 fflush(stdout);
321 }
322}