1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)setbp.c 1.1 01/18/82";
4 
5 /*
6  * Breakpoint/machine interface.
7  */
8 
9 #include "defs.h"
10 #include <signal.h>
11 #include "machine.h"
12 #include "process.h"
13 #include "main.h"
14 #include "pxops.h"
15 #include "process/process.rep"
16 
17 #define BP_OP		O_BPT		/* breakpoint trap */
18 #define BP_ERRNO	SIGILL		/* signal received at a breakpoint */
19 
20 /*
21  * Setting a breakpoint at a location consists of saving
22  * the half-word at the location and poking a BP_OP there.
23  *
24  * We save the locations and half-words on a list for use in unsetting.
25  */
26 
27 typedef struct savelist SAVELIST;
28 
29 struct savelist {
30 	ADDRESS location;
31 	short save;
32 	short refcount;
33 	SAVELIST *link;
34 };
35 
36 LOCAL SAVELIST *savelist;
37 
38 /*
39  * Set a breakpoint at the given address.  Only save the half-word there
40  * if it's not already a breakpoint.
41  */
42 
43 setbp(addr)
44 ADDRESS addr;
45 {
46 	short w;
47 	short save;
48 	register SAVELIST *newsave, *s;
49 
50 	if (option('b')) {
51 		printf("setting breakpoint at %d\n", addr);
52 		fflush(stdout);
53 	}
54 	for (s = savelist; s != NIL; s = s->link) {
55 		if (s->location == addr) {
56 			s->refcount++;
57 			return;
58 		}
59 	}
60 	iread(&save, addr, sizeof(save));
61 	newsave = alloc(1, SAVELIST);
62 	newsave->location = addr;
63 	newsave->save = save;
64 	newsave->refcount = 1;
65 	newsave->link = savelist;
66 	savelist = newsave;
67 	w = BP_OP;
68 	iwrite(&w, addr, sizeof(w));
69 }
70 
71 /*
72  * Unset a breakpoint; unfortunately we have to search the SAVELIST
73  * to find the saved value.  The assumption is that the SAVELIST will
74  * usually be quite small.
75  */
76 
77 unsetbp(addr)
78 ADDRESS addr;
79 {
80 	register SAVELIST *s, *prev;
81 
82 	if (option('b')) {
83 		printf("unsetting breakpoint at %d\n", addr);
84 		fflush(stdout);
85 	}
86 	prev = NIL;
87 	for (s = savelist; s != NIL; s = s->link) {
88 		if (s->location == addr) {
89 			iwrite(&s->save, addr, sizeof(s->save));
90 			s->refcount--;
91 			if (s->refcount == 0) {
92 				if (prev == NIL) {
93 					savelist = s->link;
94 				} else {
95 					prev->link = s->link;
96 				}
97 				dispose(s);
98 			}
99 			return;
100 		}
101 		prev = s;
102 	}
103 	panic("unsetbp: couldn't find address %d", addr);
104 }
105 
106 /*
107  * Predicate to test if the reason the process stopped was because
108  * of a breakpoint.
109  */
110 
111 BOOLEAN isbperr()
112 {
113 	register PROCESS *p;
114 
115 	p = process;
116 	return(p->status==STOPPED && p->signo==BP_ERRNO);
117 }
118