This source file includes following definitions.
- db_watchpoint_alloc
- db_watchpoint_free
- db_set_watchpoint
- db_delete_watchpoint
- db_list_watchpoints
- db_deletewatch_cmd
- db_watchpoint_cmd
- db_listwatch_cmd
- db_set_watchpoints
- db_clear_watchpoints
- db_find_watchpoint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <sys/param.h>
34 #include <sys/proc.h>
35
36 #include <machine/db_machdep.h>
37
38 #include <ddb/db_break.h>
39 #include <ddb/db_watch.h>
40 #include <ddb/db_lex.h>
41 #include <ddb/db_access.h>
42 #include <ddb/db_run.h>
43 #include <ddb/db_sym.h>
44 #include <ddb/db_output.h>
45 #include <ddb/db_command.h>
46 #include <ddb/db_extern.h>
47
48
49
50
51
52 boolean_t db_watchpoints_inserted = TRUE;
53
54 #define NWATCHPOINTS 100
55 struct db_watchpoint db_watch_table[NWATCHPOINTS];
56 db_watchpoint_t db_next_free_watchpoint = &db_watch_table[0];
57 db_watchpoint_t db_free_watchpoints = 0;
58 db_watchpoint_t db_watchpoint_list = 0;
59
60 db_watchpoint_t
61 db_watchpoint_alloc(void)
62 {
63 db_watchpoint_t watch;
64
65 if ((watch = db_free_watchpoints) != 0) {
66 db_free_watchpoints = watch->link;
67 return (watch);
68 }
69 if (db_next_free_watchpoint == &db_watch_table[NWATCHPOINTS]) {
70 db_printf("All watchpoints used.\n");
71 return (0);
72 }
73 watch = db_next_free_watchpoint;
74 db_next_free_watchpoint++;
75
76 return (watch);
77 }
78
79 void
80 db_watchpoint_free(db_watchpoint_t watch)
81 {
82 watch->link = db_free_watchpoints;
83 db_free_watchpoints = watch;
84 }
85
86 void
87 db_set_watchpoint(struct vm_map *map, db_addr_t addr, vsize_t size)
88 {
89 db_watchpoint_t watch;
90
91 if (map == NULL) {
92 db_printf("No map.\n");
93 return;
94 }
95
96
97
98
99
100 for (watch = db_watchpoint_list;
101 watch != 0;
102 watch = watch->link)
103 if (db_map_equal(watch->map, map) &&
104 (watch->loaddr == addr) &&
105 (watch->hiaddr == addr+size)) {
106 db_printf("Already set.\n");
107 return;
108 }
109
110 watch = db_watchpoint_alloc();
111 if (watch == 0) {
112 db_printf("Too many watchpoints.\n");
113 return;
114 }
115
116 watch->map = map;
117 watch->loaddr = addr;
118 watch->hiaddr = addr+size;
119
120 watch->link = db_watchpoint_list;
121 db_watchpoint_list = watch;
122
123 db_watchpoints_inserted = FALSE;
124 }
125
126 void
127 db_delete_watchpoint(struct vm_map *map, db_addr_t addr)
128 {
129 db_watchpoint_t watch;
130 db_watchpoint_t *prev;
131
132 for (prev = &db_watchpoint_list;
133 (watch = *prev) != 0;
134 prev = &watch->link)
135 if (db_map_equal(watch->map, map) &&
136 (watch->loaddr <= addr) &&
137 (addr < watch->hiaddr)) {
138 *prev = watch->link;
139 db_watchpoint_free(watch);
140 return;
141 }
142
143 db_printf("Not set.\n");
144 }
145
146 void
147 db_list_watchpoints(void)
148 {
149 db_watchpoint_t watch;
150
151 if (db_watchpoint_list == 0) {
152 db_printf("No watchpoints set\n");
153 return;
154 }
155
156 db_printf(" Map Address Size\n");
157 for (watch = db_watchpoint_list;
158 watch != 0;
159 watch = watch->link)
160 db_printf("%s%p %8lx %lx\n",
161 db_map_current(watch->map) ? "*" : " ",
162 watch->map, watch->loaddr,
163 watch->hiaddr - watch->loaddr);
164 }
165
166
167
168 void
169 db_deletewatch_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
170 {
171 db_delete_watchpoint(db_map_addr(addr), addr);
172 }
173
174
175
176 void
177 db_watchpoint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
178 {
179 vsize_t size;
180 db_expr_t value;
181
182 if (db_expression(&value))
183 size = (vsize_t) value;
184 else
185 size = 4;
186 db_skip_to_eol();
187
188 db_set_watchpoint(db_map_addr(addr), addr, size);
189 }
190
191
192
193 void
194 db_listwatch_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
195 {
196 db_list_watchpoints();
197 }
198
199 void
200 db_set_watchpoints(void)
201 {
202 db_watchpoint_t watch;
203
204 if (!db_watchpoints_inserted && db_watchpoint_list != NULL) {
205 for (watch = db_watchpoint_list;
206 watch != 0;
207 watch = watch->link)
208 pmap_protect(watch->map->pmap,
209 trunc_page(watch->loaddr),
210 round_page(watch->hiaddr),
211 VM_PROT_READ);
212 pmap_update(watch->map->pmap);
213 db_watchpoints_inserted = TRUE;
214 }
215 }
216
217 void
218 db_clear_watchpoints(void)
219 {
220 db_watchpoints_inserted = FALSE;
221 }
222
223 boolean_t
224 db_find_watchpoint(struct vm_map *map, db_addr_t addr, db_regs_t *regs)
225 {
226 db_watchpoint_t watch;
227 db_watchpoint_t found = 0;
228
229 for (watch = db_watchpoint_list;
230 watch != 0;
231 watch = watch->link)
232 if (db_map_equal(watch->map, map)) {
233 if ((watch->loaddr <= addr) &&
234 (addr < watch->hiaddr))
235 return (TRUE);
236 else if ((trunc_page(watch->loaddr) <= addr) &&
237 (addr < round_page(watch->hiaddr)))
238 found = watch;
239 }
240
241
242
243
244
245
246
247 if (found) {
248 db_watchpoints_inserted = FALSE;
249 db_single_step(regs);
250 }
251
252 return (FALSE);
253 }