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