1 /* Mips simulator watchpoint support.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "sim-options.h"
24 #include "sim-assert.h"
40 static DECLARE_OPTION_HANDLER (watch_option_handler
);
43 OPTION_WATCH_DELETE
= OPTION_START
,
56 delete_watchpoint (SIM_DESC sd
, watchpoint_type type
)
58 sim_watch_point
*point
= &STATE_WATCHPOINTS (sd
)->points
[type
];
59 if (point
->event
!= NULL
)
60 sim_events_deschedule (sd
, point
->event
);
61 point
->action
= invalid_watchpoint_action
;
66 static sim_event_handler handle_watchpoint
;
69 schedule_watchpoint (SIM_DESC sd
,
75 sim_watchpoints
*watch
= STATE_WATCHPOINTS (sd
);
76 sim_watch_point
*point
= &watch
->points
[type
];
77 if (point
->event
!= NULL
)
78 sim_events_deschedule (sd
, point
->event
);
80 point
->is_within
= is_within
;
81 if (point
->action
== invalid_watchpoint_action
)
82 point
->action
= break_watchpoint_action
;
87 point
->event
= sim_events_watch_sim (sd
, watch
->pc
, watch
->sizeof_pc
,
90 point
->arg
, point
->arg
, /* PC == arg? */
94 case clock_watchpoint
:
95 point
->event
= sim_events_watch_clock (sd
,
96 point
->arg
, /* ms time */
100 case cycles_watchpoint
:
101 point
->event
= sim_events_schedule (sd
, point
->arg
, /* time */
106 sim_engine_abort (sd
, NULL
, NULL_CIA
,
107 "handle_watchpoint - internal error - bad switch");
115 handle_watchpoint (SIM_DESC sd
, void *data
)
117 sim_watchpoints
*watch
= STATE_WATCHPOINTS (sd
);
118 sim_watch_point
*point
= data
;
119 watchpoint_type type
= point
- watch
->points
;
121 switch (point
->action
)
124 case break_watchpoint_action
:
125 point
->event
= NULL
; /* gone */
126 sim_engine_halt (sd
, NULL
, NULL
, NULL_CIA
, sim_stopped
, SIGINT
);
129 case n_interrupt_watchpoint_action
:
130 /* First reschedule this event */
131 schedule_watchpoint (sd
, type
, point
->arg
, point
->is_within
, 1/*is-command*/);
134 case interrupt_watchpoint_action
:
135 watch
->interrupt_handler (sd
, NULL
);
139 sim_engine_abort (sd
, NULL
, NULL_CIA
,
140 "handle_watchpoint - internal error - bad switch");
147 action_watchpoint (SIM_DESC sd
, watchpoint_type type
, const char *arg
)
149 sim_watchpoints
*watch
= STATE_WATCHPOINTS (sd
);
150 sim_watch_point
*point
= &watch
->points
[type
];
151 if (strcmp (arg
, "break") == 0)
153 point
->action
= break_watchpoint_action
;
155 else if (strcmp (arg
, "int") == 0)
157 if (watch
->interrupt_handler
== NULL
)
159 sim_io_eprintf (sd
, "This simulator does not support int watchpoints\n");
162 point
->action
= interrupt_watchpoint_action
;
164 else if (strcmp (arg
, "+int") == 0)
166 if (watch
->interrupt_handler
== NULL
)
168 sim_io_eprintf (sd
, "This simulator does not support int watchpoints\n");
171 point
->action
= n_interrupt_watchpoint_action
;
175 sim_io_eprintf (sd
, "Interrupts other than `int' currently unsuported\n");
182 static const OPTION watch_options
[] =
184 { {"watch-delete", required_argument
, NULL
, OPTION_WATCH_DELETE
},
185 '\0', "all|pc|cycles|clock", "Delete a watchpoint",
186 watch_option_handler
},
187 { {"delete-watch", required_argument
, NULL
, OPTION_WATCH_DELETE
},
188 '\0', "all|pc|cycles|clock", NULL
,
189 watch_option_handler
},
191 { {"watch-pc", required_argument
, NULL
, OPTION_WATCH_PC
},
192 '\0', "[!] VALUE", "Watch the PC (break)",
193 watch_option_handler
},
194 { {"watch-clock", required_argument
, NULL
, OPTION_WATCH_CLOCK
},
195 '\0', "TIME-IN-MS", "Watch the clock (break)",
196 watch_option_handler
},
197 { {"watch-cycles", required_argument
, NULL
, OPTION_WATCH_CYCLES
},
198 '\0', "CYCLES", "Watch the cycles (break)",
199 watch_option_handler
},
201 { {"action-pc", required_argument
, NULL
, OPTION_ACTION_PC
},
202 '\0', "break|int|+int", "Action taken by PC watchpoint",
203 watch_option_handler
},
204 { {"action-clock", required_argument
, NULL
, OPTION_ACTION_CLOCK
},
205 '\0', "break|int|+int", "Action taken by CLOCK watchpoint",
206 watch_option_handler
},
207 { {"action-cycles", required_argument
, NULL
, OPTION_ACTION_CYCLES
},
208 '\0', "break|int|+int", "Action taken by CYCLES watchpoint",
209 watch_option_handler
},
211 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
216 watch_option_handler (sd
, opt
, arg
, is_command
)
225 case OPTION_WATCH_DELETE
:
226 if (strcmp (arg
, "all") == 0
227 || strcmp (arg
, "pc") == 0)
229 delete_watchpoint (sd
, pc_watchpoint
);
232 if (strcmp (arg
, "all") == 0
233 || strcmp (arg
, "clock") == 0)
235 delete_watchpoint (sd
, clock_watchpoint
);
238 if (strcmp (arg
, "all") == 0
239 || strcmp (arg
, "cycles") == 0)
241 delete_watchpoint (sd
, cycles_watchpoint
);
244 sim_io_eprintf (sd
, "Unknown watchpoint type `%s'\n", arg
);
247 case OPTION_WATCH_PC
:
248 if (STATE_WATCHPOINTS (sd
)->pc
== NULL
)
250 sim_io_eprintf (sd
, "PC watchpoints are not supported for this simulator\n");
254 return schedule_watchpoint (sd
, pc_watchpoint
, strtoul (arg
+ 1, NULL
, 0),
255 0 /* !is_within */, is_command
);
257 return schedule_watchpoint (sd
, pc_watchpoint
, strtoul (arg
, NULL
, 0),
258 1 /* is_within */, is_command
);
260 case OPTION_WATCH_CLOCK
:
261 return schedule_watchpoint (sd
, clock_watchpoint
, strtoul (arg
, NULL
, 0), 0, is_command
);
263 case OPTION_WATCH_CYCLES
:
264 return schedule_watchpoint (sd
, cycles_watchpoint
, strtoul (arg
, NULL
, 0), 0, is_command
);
266 case OPTION_ACTION_PC
:
267 return action_watchpoint (sd
, pc_watchpoint
, arg
);
269 case OPTION_ACTION_CLOCK
:
270 return action_watchpoint (sd
, clock_watchpoint
, arg
);
272 case OPTION_ACTION_CYCLES
:
273 return action_watchpoint (sd
, cycles_watchpoint
, arg
);
277 sim_io_eprintf (sd
, "Unknown watch option %d\n", opt
);
285 sim_watchpoint_init (SIM_DESC sd
)
287 /* schedule any watchpoints enabled by command line options */
288 sim_watchpoints
*watch
= STATE_WATCHPOINTS (sd
);
289 watchpoint_type type
;
290 for (type
= 0; type
< nr_watchpoint_types
; type
++)
292 if (watch
->points
[type
].action
!= invalid_watchpoint_action
)
293 schedule_watchpoint (sd
, type
,
294 watch
->points
[type
].arg
,
295 watch
->points
[type
].is_within
,
303 sim_watchpoint_install (SIM_DESC sd
)
305 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
306 sim_add_option_table (sd
, watch_options
);
307 sim_module_add_init_fn (sd
, sim_watchpoint_init
);