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,
74 sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
75 sim_watch_point *point = &watch->points[type];
76 if (point->event != NULL)
77 delete_watchpoint (sd, type);
79 if (point->action == invalid_watchpoint_action)
80 point->action = break_watchpoint_action;
85 point->event = sim_events_watch_sim (sd, watch->pc, watch->sizeof_pc,
87 point->arg, point->arg, /* PC == arg? */
91 case clock_watchpoint:
92 point->event = sim_events_watch_clock (sd,
93 point->arg, /* ms time */
97 case cycles_watchpoint:
98 point->event = sim_events_schedule (sd, point->arg, /* time */
103 sim_engine_abort (sd, NULL, NULL_CIA,
104 "handle_watchpoint - internal error - bad switch");
112 handle_watchpoint (SIM_DESC sd, void *data)
114 sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
115 sim_watch_point *point = data;
116 watchpoint_type type = point - watch->points;
118 switch (point->action)
121 case break_watchpoint_action:
122 point->event = NULL; /* gone */
123 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIGINT);
126 case n_interrupt_watchpoint_action:
127 /* First reschedule this event */
128 schedule_watchpoint (sd, type, point->arg, 1/*is-command*/);
131 case interrupt_watchpoint_action:
132 watch->interrupt_handler (sd, NULL);
136 sim_engine_abort (sd, NULL, NULL_CIA,
137 "handle_watchpoint - internal error - bad switch");
144 action_watchpoint (SIM_DESC sd, watchpoint_type type, const char *arg)
146 sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
147 sim_watch_point *point = &watch->points[type];
148 if (strcmp (arg, "break") == NULL)
150 point->action = break_watchpoint_action;
152 else if (strcmp (arg, "int") == NULL)
154 if (watch->interrupt_handler == NULL)
156 sim_io_eprintf (sd, "This simulator does not support int watchpoints\n");
159 point->action = interrupt_watchpoint_action;
161 else if (strcmp (arg, "+int") == 0)
163 if (watch->interrupt_handler == NULL)
165 sim_io_eprintf (sd, "This simulator does not support int watchpoints\n");
168 point->action = n_interrupt_watchpoint_action;
172 sim_io_eprintf (sd, "Interrupts other than `int' currently unsuported\n");
179 static const OPTION watch_options[] =
181 { {"watch-delete", required_argument, NULL, OPTION_WATCH_DELETE },
182 '\0', "all|pc|cycles|clock", "Delete a watchpoint",
183 watch_option_handler },
185 { {"watch-pc", required_argument, NULL, OPTION_WATCH_PC },
186 '\0', "VALUE", "Watch the PC (break)",
187 watch_option_handler },
188 { {"watch-clock", required_argument, NULL, OPTION_WATCH_CLOCK },
189 '\0', "TIME-IN-MS", "Watch the clock (break)",
190 watch_option_handler },
191 { {"watch-cycles", required_argument, NULL, OPTION_WATCH_CYCLES },
192 '\0', "CYCLES", "Watch the cycles (break)",
193 watch_option_handler },
195 { {"action-pc", required_argument, NULL, OPTION_ACTION_PC },
196 '\0', "break|int|+int", "Action taken by PC watchpoint",
197 watch_option_handler },
198 { {"action-clock", required_argument, NULL, OPTION_ACTION_CLOCK },
199 '\0', "break|int|+int", "Action taken by CLOCK watchpoint",
200 watch_option_handler },
201 { {"action-cycles", required_argument, NULL, OPTION_ACTION_CYCLES },
202 '\0', "break|int|+int", "Action taken by CYCLES watchpoint",
203 watch_option_handler },
205 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
210 watch_option_handler (sd, opt, arg, is_command)
219 case OPTION_WATCH_DELETE:
220 if (strcmp (arg, "all") == 0
221 || strcmp (arg, "pc") == 0)
223 delete_watchpoint (sd, pc_watchpoint);
226 if (strcmp (arg, "all") == 0
227 || strcmp (arg, "clock") == 0)
229 delete_watchpoint (sd, clock_watchpoint);
232 if (strcmp (arg, "all") == 0
233 || strcmp (arg, "cycles") == 0)
235 delete_watchpoint (sd, cycles_watchpoint);
238 sim_io_eprintf (sd, "Unknown watchpoint type `%s'\n", arg);
241 case OPTION_WATCH_PC:
242 if (STATE_WATCHPOINTS (sd)->pc == NULL)
244 sim_io_eprintf (sd, "PC watchpoints are not supported for this simulator\n");
247 return schedule_watchpoint (sd, pc_watchpoint, strtoul (arg, NULL, 0), is_command);
249 case OPTION_WATCH_CLOCK:
250 return schedule_watchpoint (sd, clock_watchpoint, strtoul (arg, NULL, 0), is_command);
252 case OPTION_WATCH_CYCLES:
253 return schedule_watchpoint (sd, cycles_watchpoint, strtoul (arg, NULL, 0), is_command);
255 case OPTION_ACTION_PC:
256 return action_watchpoint (sd, cycles_watchpoint, arg);
258 case OPTION_ACTION_CLOCK:
259 return action_watchpoint (sd, cycles_watchpoint, arg);
261 case OPTION_ACTION_CYCLES:
262 return action_watchpoint (sd, cycles_watchpoint, arg);
266 sim_io_eprintf (sd, "Unknown watch option %d\n", opt);
274 sim_watchpoint_init (SIM_DESC sd)
276 /* schedule any watchpoints enabled by command line options */
277 sim_watchpoints *watch = STATE_WATCHPOINTS (sd);
278 watchpoint_type type;
279 for (type = 0; type < nr_watchpoint_types; type++)
281 if (watch->points[type].action != invalid_watchpoint_action)
282 schedule_watchpoint (sd, type, watch->points[type].arg, 1/*is-command*/);
289 sim_watchpoint_install (SIM_DESC sd)
291 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
292 sim_add_option_table (sd, watch_options);
293 sim_module_add_init_fn (sd, sim_watchpoint_init);