|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie the
24: * rights to redistribute these changes.
25: */
26: /*
1.1.1.3 ! root 27: * db_break.c,v 1.2 1993/05/20 03:39:08 cgd Exp
! 28: *
1.1 root 29: * HISTORY
1.1.1.3 ! root 30: * db_break.c,v
! 31: * Revision 1.2 1993/05/20 03:39:08 cgd
! 32: * add explicit rcs id
! 33: *
! 34: * Revision 1.1.1.1 1993/03/21 09:46:26 cgd
1.1.1.2 root 35: * initial import of 386bsd-0.1 sources
36: *
1.1 root 37: * Revision 1.1 1992/03/25 21:44:57 pace
38: * Initial revision
39: *
40: * Revision 2.7 91/02/05 17:06:00 mrt
41: * Changed to new Mach copyright
42: * [91/01/31 16:17:01 mrt]
43: *
44: * Revision 2.6 91/01/08 15:09:03 rpd
45: * Added db_map_equal, db_map_current, db_map_addr.
46: * [90/11/10 rpd]
47: *
48: * Revision 2.5 90/11/05 14:26:32 rpd
49: * Initialize db_breakpoints_inserted to TRUE.
50: * [90/11/04 rpd]
51: *
52: * Revision 2.4 90/10/25 14:43:33 rwd
53: * Added map field to breakpoints.
54: * Added map argument to db_set_breakpoint, db_delete_breakpoint,
55: * db_find_breakpoint. Added db_find_breakpoint_here.
56: * [90/10/18 rpd]
57: *
58: * Revision 2.3 90/09/28 16:57:07 jsb
59: * Fixed db_breakpoint_free.
60: * [90/09/18 rpd]
61: *
62: * Revision 2.2 90/08/27 21:49:53 dbg
63: * Reflected changes in db_printsym()'s calling seq.
64: * [90/08/20 af]
65: * Clear breakpoints only if inserted.
66: * Reduce lint.
67: * [90/08/07 dbg]
68: * Created.
69: * [90/07/25 dbg]
70: *
71: */
72: /*
73: * Author: David B. Golub, Carnegie Mellon University
74: * Date: 7/90
75: */
76: /*
77: * Breakpoints.
78: */
79: #include "param.h"
80: #include "proc.h"
81: #include <machine/db_machdep.h> /* type definitions */
82:
83: #include <ddb/db_lex.h>
84: #include <ddb/db_break.h>
85: #include <ddb/db_access.h>
86: #include <ddb/db_sym.h>
87: #include <ddb/db_break.h>
88:
89: extern boolean_t db_map_equal();
90: extern boolean_t db_map_current();
91: extern vm_map_t db_map_addr();
92:
93: #define NBREAKPOINTS 100
94: struct db_breakpoint db_break_table[NBREAKPOINTS];
95: db_breakpoint_t db_next_free_breakpoint = &db_break_table[0];
96: db_breakpoint_t db_free_breakpoints = 0;
97: db_breakpoint_t db_breakpoint_list = 0;
98:
99: db_breakpoint_t
100: db_breakpoint_alloc()
101: {
102: register db_breakpoint_t bkpt;
103:
104: if ((bkpt = db_free_breakpoints) != 0) {
105: db_free_breakpoints = bkpt->link;
106: return (bkpt);
107: }
108: if (db_next_free_breakpoint == &db_break_table[NBREAKPOINTS]) {
109: db_printf("All breakpoints used.\n");
110: return (0);
111: }
112: bkpt = db_next_free_breakpoint;
113: db_next_free_breakpoint++;
114:
115: return (bkpt);
116: }
117:
118: void
119: db_breakpoint_free(bkpt)
120: register db_breakpoint_t bkpt;
121: {
122: bkpt->link = db_free_breakpoints;
123: db_free_breakpoints = bkpt;
124: }
125:
126: void
127: db_set_breakpoint(map, addr, count)
128: vm_map_t map;
129: db_addr_t addr;
130: int count;
131: {
132: register db_breakpoint_t bkpt;
133:
134: if (db_find_breakpoint(map, addr)) {
135: db_printf("Already set.\n");
136: return;
137: }
138:
139: bkpt = db_breakpoint_alloc();
140: if (bkpt == 0) {
141: db_printf("Too many breakpoints.\n");
142: return;
143: }
144:
145: bkpt->map = map;
146: bkpt->address = addr;
147: bkpt->flags = 0;
148: bkpt->init_count = count;
149: bkpt->count = count;
150:
151: bkpt->link = db_breakpoint_list;
152: db_breakpoint_list = bkpt;
153: }
154:
155: void
156: db_delete_breakpoint(map, addr)
157: vm_map_t map;
158: db_addr_t addr;
159: {
160: register db_breakpoint_t bkpt;
161: register db_breakpoint_t *prev;
162:
163: for (prev = &db_breakpoint_list;
164: (bkpt = *prev) != 0;
165: prev = &bkpt->link) {
166: if (db_map_equal(bkpt->map, map) &&
167: (bkpt->address == addr)) {
168: *prev = bkpt->link;
169: break;
170: }
171: }
172: if (bkpt == 0) {
173: db_printf("Not set.\n");
174: return;
175: }
176:
177: db_breakpoint_free(bkpt);
178: }
179:
180: db_breakpoint_t
181: db_find_breakpoint(map, addr)
182: vm_map_t map;
183: db_addr_t addr;
184: {
185: register db_breakpoint_t bkpt;
186:
187: for (bkpt = db_breakpoint_list;
188: bkpt != 0;
189: bkpt = bkpt->link)
190: {
191: if (db_map_equal(bkpt->map, map) &&
192: (bkpt->address == addr))
193: return (bkpt);
194: }
195: return (0);
196: }
197:
198: db_breakpoint_t
199: db_find_breakpoint_here(addr)
200: db_addr_t addr;
201: {
202: return db_find_breakpoint(db_map_addr(addr), addr);
203: }
204:
205: boolean_t db_breakpoints_inserted = TRUE;
206:
207: void
208: db_set_breakpoints()
209: {
210: register db_breakpoint_t bkpt;
211:
212: if (!db_breakpoints_inserted) {
213:
214: for (bkpt = db_breakpoint_list;
215: bkpt != 0;
216: bkpt = bkpt->link)
217: if (db_map_current(bkpt->map)) {
218: bkpt->bkpt_inst = db_get_value(bkpt->address,
219: BKPT_SIZE,
220: FALSE);
221: db_put_value(bkpt->address,
222: BKPT_SIZE,
223: BKPT_SET(bkpt->bkpt_inst));
224: }
225: db_breakpoints_inserted = TRUE;
226: }
227: }
228:
229: void
230: db_clear_breakpoints()
231: {
232: register db_breakpoint_t bkpt;
233:
234: if (db_breakpoints_inserted) {
235:
236: for (bkpt = db_breakpoint_list;
237: bkpt != 0;
238: bkpt = bkpt->link)
239: if (db_map_current(bkpt->map)) {
240: db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
241: }
242: db_breakpoints_inserted = FALSE;
243: }
244: }
245:
246: /*
247: * Set a temporary breakpoint.
248: * The instruction is changed immediately,
249: * so the breakpoint does not have to be on the breakpoint list.
250: */
251: db_breakpoint_t
252: db_set_temp_breakpoint(addr)
253: db_addr_t addr;
254: {
255: register db_breakpoint_t bkpt;
256:
257: bkpt = db_breakpoint_alloc();
258: if (bkpt == 0) {
259: db_printf("Too many breakpoints.\n");
260: return 0;
261: }
262:
263: bkpt->map = NULL;
264: bkpt->address = addr;
265: bkpt->flags = BKPT_TEMP;
266: bkpt->init_count = 1;
267: bkpt->count = 1;
268:
269: bkpt->bkpt_inst = db_get_value(bkpt->address, BKPT_SIZE, FALSE);
270: db_put_value(bkpt->address, BKPT_SIZE, BKPT_SET(bkpt->bkpt_inst));
271: return bkpt;
272: }
273:
274: void
275: db_delete_temp_breakpoint(bkpt)
276: db_breakpoint_t bkpt;
277: {
278: db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
279: db_breakpoint_free(bkpt);
280: }
281:
282: /*
283: * List breakpoints.
284: */
285: void
286: db_list_breakpoints()
287: {
288: register db_breakpoint_t bkpt;
289:
290: if (db_breakpoint_list == 0) {
291: db_printf("No breakpoints set\n");
292: return;
293: }
294:
295: db_printf(" Map Count Address\n");
296: for (bkpt = db_breakpoint_list;
297: bkpt != 0;
298: bkpt = bkpt->link)
299: {
300: db_printf("%s%8x %5d ",
301: db_map_current(bkpt->map) ? "*" : " ",
302: bkpt->map, bkpt->init_count);
303: db_printsym(bkpt->address, DB_STGY_PROC);
304: db_printf("\n");
305: }
306: }
307:
308: /* Delete breakpoint */
309: /*ARGSUSED*/
310: void
311: db_delete_cmd(addr, have_addr, count, modif)
312: db_expr_t addr;
313: int have_addr;
314: db_expr_t count;
315: char * modif;
316: {
317: db_delete_breakpoint(db_map_addr(addr), (db_addr_t)addr);
318: }
319:
320: /* Set breakpoint with skip count */
321: /*ARGSUSED*/
322: void
323: db_breakpoint_cmd(addr, have_addr, count, modif)
324: db_expr_t addr;
325: int have_addr;
326: db_expr_t count;
327: char * modif;
328: {
329: if (count == -1)
330: count = 1;
331:
332: db_set_breakpoint(db_map_addr(addr), (db_addr_t)addr, count);
333: }
334:
335: /* list breakpoints */
336: void
337: db_listbreak_cmd()
338: {
339: db_list_breakpoints();
340: }
341:
342: #include <vm/vm_kern.h>
343:
344: /*
345: * We want ddb to be usable before most of the kernel has been
346: * initialized. In particular, current_thread() or kernel_map
347: * (or both) may be null.
348: */
349:
350: boolean_t
351: db_map_equal(map1, map2)
352: vm_map_t map1, map2;
353: {
354: return ((map1 == map2) ||
355: ((map1 == NULL) && (map2 == kernel_map)) ||
356: ((map1 == kernel_map) && (map2 == NULL)));
357: }
358:
359: boolean_t
360: db_map_current(map)
361: vm_map_t map;
362: {
363: #if 0
364: thread_t thread;
365:
366: return ((map == NULL) ||
367: (map == kernel_map) ||
368: (((thread = current_thread()) != NULL) &&
369: (map == thread->task->map)));
370: #else
371: return (1);
372: #endif
373: }
374:
375: vm_map_t
376: db_map_addr(addr)
377: vm_offset_t addr;
378: {
379: #if 0
380: thread_t thread;
381:
382: /*
383: * We want to return kernel_map for all
384: * non-user addresses, even when debugging
385: * kernel tasks with their own maps.
386: */
387:
388: if ((VM_MIN_ADDRESS <= addr) &&
389: (addr < VM_MAX_ADDRESS) &&
390: ((thread = current_thread()) != NULL))
391: return thread->task->map;
392: else
393: #endif
394: return kernel_map;
395: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.