This source file includes following definitions.
- db_breakpoint_alloc
- db_breakpoint_free
- db_set_breakpoint
- db_delete_breakpoint
- db_find_breakpoint
- db_find_breakpoint_here
- db_set_breakpoints
- db_clear_breakpoints
- db_set_temp_breakpoint
- db_delete_temp_breakpoint
- db_list_breakpoints
- db_delete_cmd
- db_breakpoint_cmd
- db_listbreak_cmd
- db_map_equal
- db_map_current
- db_map_addr
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
34
35
36 #include <sys/param.h>
37 #include <sys/proc.h>
38
39 #include <uvm/uvm_extern.h>
40
41 #include <machine/db_machdep.h>
42
43 #include <ddb/db_lex.h>
44 #include <ddb/db_access.h>
45 #include <ddb/db_sym.h>
46 #include <ddb/db_break.h>
47 #include <ddb/db_output.h>
48
49 #define NBREAKPOINTS 100
50 struct db_breakpoint db_break_table[NBREAKPOINTS];
51 db_breakpoint_t db_next_free_breakpoint = &db_break_table[0];
52 db_breakpoint_t db_free_breakpoints = 0;
53 db_breakpoint_t db_breakpoint_list = 0;
54
55 db_breakpoint_t
56 db_breakpoint_alloc(void)
57 {
58 db_breakpoint_t bkpt;
59
60 if ((bkpt = db_free_breakpoints) != 0) {
61 db_free_breakpoints = bkpt->link;
62 return (bkpt);
63 }
64 if (db_next_free_breakpoint == &db_break_table[NBREAKPOINTS]) {
65 db_printf("All breakpoints used.\n");
66 return (0);
67 }
68 bkpt = db_next_free_breakpoint;
69 db_next_free_breakpoint++;
70
71 return (bkpt);
72 }
73
74 void
75 db_breakpoint_free(db_breakpoint_t bkpt)
76 {
77 bkpt->link = db_free_breakpoints;
78 db_free_breakpoints = bkpt;
79 }
80
81 void
82 db_set_breakpoint(struct vm_map *map, db_addr_t addr, int count)
83 {
84 db_breakpoint_t bkpt;
85
86 if (db_find_breakpoint(map, addr)) {
87 db_printf("Already set.\n");
88 return;
89 }
90
91 #ifdef DB_VALID_BREAKPOINT
92 if (!DB_VALID_BREAKPOINT(addr)) {
93 db_printf("Not a valid address for a breakpoint.\n");
94 return;
95 }
96 #endif
97
98 bkpt = db_breakpoint_alloc();
99 if (bkpt == 0) {
100 db_printf("Too many breakpoints.\n");
101 return;
102 }
103
104 bkpt->map = map;
105 bkpt->address = addr;
106 bkpt->flags = 0;
107 bkpt->init_count = count;
108 bkpt->count = count;
109
110 bkpt->link = db_breakpoint_list;
111 db_breakpoint_list = bkpt;
112 }
113
114 void
115 db_delete_breakpoint(struct vm_map *map, db_addr_t addr)
116 {
117 db_breakpoint_t bkpt;
118 db_breakpoint_t *prev;
119
120 for (prev = &db_breakpoint_list;
121 (bkpt = *prev) != 0;
122 prev = &bkpt->link) {
123 if (db_map_equal(bkpt->map, map) &&
124 (bkpt->address == addr)) {
125 *prev = bkpt->link;
126 break;
127 }
128 }
129 if (bkpt == 0) {
130 db_printf("Not set.\n");
131 return;
132 }
133
134 db_breakpoint_free(bkpt);
135 }
136
137 db_breakpoint_t
138 db_find_breakpoint(struct vm_map *map, db_addr_t addr)
139 {
140 db_breakpoint_t bkpt;
141
142 for (bkpt = db_breakpoint_list;
143 bkpt != 0;
144 bkpt = bkpt->link)
145 {
146 if (db_map_equal(bkpt->map, map) &&
147 (bkpt->address == addr))
148 return (bkpt);
149 }
150 return (0);
151 }
152
153 db_breakpoint_t
154 db_find_breakpoint_here(db_addr_t addr)
155 {
156 return db_find_breakpoint(db_map_addr(addr), addr);
157 }
158
159 boolean_t db_breakpoints_inserted = TRUE;
160
161 void
162 db_set_breakpoints(void)
163 {
164 db_breakpoint_t bkpt;
165
166 if (!db_breakpoints_inserted) {
167
168 for (bkpt = db_breakpoint_list;
169 bkpt != 0;
170 bkpt = bkpt->link)
171 if (db_map_current(bkpt->map)) {
172 bkpt->bkpt_inst = db_get_value(bkpt->address, BKPT_SIZE,
173 FALSE);
174 db_put_value(bkpt->address, BKPT_SIZE,
175 BKPT_SET(bkpt->bkpt_inst));
176 }
177 db_breakpoints_inserted = TRUE;
178 }
179 }
180
181 void
182 db_clear_breakpoints(void)
183 {
184 db_breakpoint_t bkpt;
185
186 if (db_breakpoints_inserted) {
187
188 for (bkpt = db_breakpoint_list;
189 bkpt != 0;
190 bkpt = bkpt->link)
191 if (db_map_current(bkpt->map)) {
192 db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
193 }
194 db_breakpoints_inserted = FALSE;
195 }
196 }
197
198
199
200
201
202
203 db_breakpoint_t
204 db_set_temp_breakpoint(db_addr_t addr)
205 {
206 db_breakpoint_t bkpt;
207
208 #ifdef DB_VALID_BREAKPOINT
209 if (!DB_VALID_BREAKPOINT(addr)) {
210 db_printf("Not a valid address for a breakpoint.\n");
211 return (0);
212 }
213 #endif
214
215 bkpt = db_breakpoint_alloc();
216 if (bkpt == 0) {
217 db_printf("Too many breakpoints.\n");
218 return (0);
219 }
220
221 bkpt->map = NULL;
222 bkpt->address = addr;
223 bkpt->flags = BKPT_TEMP;
224 bkpt->init_count = 1;
225 bkpt->count = 1;
226
227 bkpt->bkpt_inst = db_get_value(bkpt->address, BKPT_SIZE, FALSE);
228 db_put_value(bkpt->address, BKPT_SIZE, BKPT_SET(bkpt->bkpt_inst));
229 return bkpt;
230 }
231
232 void
233 db_delete_temp_breakpoint(db_breakpoint_t bkpt)
234 {
235 db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
236 db_breakpoint_free(bkpt);
237 }
238
239
240
241
242 void
243 db_list_breakpoints(void)
244 {
245 db_breakpoint_t bkpt;
246
247 if (db_breakpoint_list == 0) {
248 db_printf("No breakpoints set\n");
249 return;
250 }
251
252 db_printf(" Map Count Address\n");
253 for (bkpt = db_breakpoint_list;
254 bkpt != 0;
255 bkpt = bkpt->link)
256 {
257 db_printf("%s%p %5d ",
258 db_map_current(bkpt->map) ? "*" : " ",
259 bkpt->map, bkpt->init_count);
260 db_printsym(bkpt->address, DB_STGY_PROC, db_printf);
261 db_printf("\n");
262 }
263 }
264
265
266
267 void
268 db_delete_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
269 {
270 db_delete_breakpoint(db_map_addr(addr), (db_addr_t)addr);
271 }
272
273
274
275 void
276 db_breakpoint_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
277 {
278 if (count == -1)
279 count = 1;
280
281 db_set_breakpoint(db_map_addr(addr), (db_addr_t)addr, count);
282 }
283
284
285
286 void
287 db_listbreak_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
288 {
289 db_list_breakpoints();
290 }
291
292
293
294
295
296
297
298 boolean_t
299 db_map_equal(struct vm_map *map1, struct vm_map *map2)
300 {
301 return ((map1 == map2) ||
302 ((map1 == NULL) && (map2 == kernel_map)) ||
303 ((map1 == kernel_map) && (map2 == NULL)));
304 }
305
306 boolean_t
307 db_map_current(struct vm_map *map)
308 {
309 #if 0
310 thread_t thread;
311
312 return ((map == NULL) ||
313 (map == kernel_map) ||
314 (((thread = current_thread()) != NULL) &&
315 (map == thread->proc->map)));
316 #else
317 return (1);
318 #endif
319 }
320
321 struct vm_map *
322 db_map_addr(vaddr_t addr)
323 {
324 #if 0
325 thread_t thread;
326
327
328
329
330
331
332
333 if ((VM_MIN_ADDRESS <= addr) &&
334 (addr < VM_MAX_ADDRESS) &&
335 ((thread = current_thread()) != NULL))
336 return thread->proc->map;
337 else
338 #endif
339 return kernel_map;
340 }