* Copyright (c) 1991,1990 Carnegie Mellon University
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
* Carnegie Mellon requests users of this software to return to
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
* Revision 1.1 1992/03/25 21:45:37 pace
* Revision 2.5 91/02/05 17:07:27 mrt
* Changed to new Mach copyright
* [91/01/31 16:20:02 mrt]
* Revision 2.4 91/01/08 15:09:24 rpd
* Use db_map_equal, db_map_current, db_map_addr.
* Revision 2.3 90/11/05 14:26:39 rpd
* Initialize db_watchpoints_inserted to TRUE.
* Revision 2.2 90/10/25 14:44:16 rwd
* Made db_watchpoint_cmd parse a size argument.
* Generalized the watchpoint support.
* Author: Richard P. Draves, Carnegie Mellon University
#include <machine/db_machdep.h>
#include <ddb/db_watch.h>
#include <ddb/db_access.h>
#include <machine/db_machdep.h>
extern boolean_t
db_map_equal();
extern boolean_t
db_map_current();
extern vm_map_t
db_map_addr();
boolean_t db_watchpoints_inserted
= TRUE
;
struct db_watchpoint db_watch_table
[NWATCHPOINTS
];
db_watchpoint_t db_next_free_watchpoint
= &db_watch_table
[0];
db_watchpoint_t db_free_watchpoints
= 0;
db_watchpoint_t db_watchpoint_list
= 0;
register db_watchpoint_t watch
;
if ((watch
= db_free_watchpoints
) != 0) {
db_free_watchpoints
= watch
->link
;
if (db_next_free_watchpoint
== &db_watch_table
[NWATCHPOINTS
]) {
db_printf("All watchpoints used.\n");
watch
= db_next_free_watchpoint
;
db_next_free_watchpoint
++;
db_watchpoint_free(watch
)
register db_watchpoint_t watch
;
watch
->link
= db_free_watchpoints
;
db_free_watchpoints
= watch
;
db_set_watchpoint(map
, addr
, size
)
register db_watchpoint_t watch
;
* Should we do anything fancy with overlapping regions?
for (watch
= db_watchpoint_list
;
if (db_map_equal(watch
->map
, map
) &&
(watch
->loaddr
== addr
) &&
(watch
->hiaddr
== addr
+size
)) {
db_printf("Already set.\n");
watch
= db_watchpoint_alloc();
db_printf("Too many watchpoints.\n");
watch
->hiaddr
= addr
+size
;
watch
->link
= db_watchpoint_list
;
db_watchpoint_list
= watch
;
db_watchpoints_inserted
= FALSE
;
db_delete_watchpoint(map
, addr
)
register db_watchpoint_t watch
;
register db_watchpoint_t
*prev
;
for (prev
= &db_watchpoint_list
;
if (db_map_equal(watch
->map
, map
) &&
(watch
->loaddr
<= addr
) &&
(addr
< watch
->hiaddr
)) {
db_watchpoint_free(watch
);
register db_watchpoint_t watch
;
if (db_watchpoint_list
== 0) {
db_printf("No watchpoints set\n");
db_printf(" Map Address Size\n");
for (watch
= db_watchpoint_list
;
db_printf("%s%8x %8x %x\n",
db_map_current(watch
->map
) ? "*" : " ",
watch
->map
, watch
->loaddr
,
watch
->hiaddr
- watch
->loaddr
);
db_deletewatch_cmd(addr
, have_addr
, count
, modif
)
db_delete_watchpoint(db_map_addr(addr
), addr
);
db_watchpoint_cmd(addr
, have_addr
, count
, modif
)
if (db_expression(&value
))
size
= (vm_size_t
) value
;
db_set_watchpoint(db_map_addr(addr
), addr
, size
);
register db_watchpoint_t watch
;
if (!db_watchpoints_inserted
) {
for (watch
= db_watchpoint_list
;
pmap_protect(watch
->map
->pmap
,
trunc_page(watch
->loaddr
),
round_page(watch
->hiaddr
),
db_watchpoints_inserted
= TRUE
;
db_watchpoints_inserted
= FALSE
;
db_find_watchpoint(map
, addr
, regs
)
register db_watchpoint_t watch
;
db_watchpoint_t found
= 0;
for (watch
= db_watchpoint_list
;
if (db_map_equal(watch
->map
, map
)) {
if ((watch
->loaddr
<= addr
) &&
else if ((trunc_page(watch
->loaddr
) <= addr
) &&
(addr
< round_page(watch
->hiaddr
)))
* We didn't hit exactly on a watchpoint, but we are
* in a protected region. We want to single-step
db_watchpoints_inserted
= FALSE
;