1 /* Simulator breakpoint 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. */
24 #include "sim-assert.h"
25 #include "sim-break.h"
27 #ifndef SIM_BREAKPOINT
28 #define SIM_BREAKPOINT {0x00}
29 #define SIM_BREAKPOINT_SIZE (1)
35 struct sim_breakpoint *next;
36 SIM_ADDR addr; /* Address of this breakpoint */
38 unsigned char loc_contents[SIM_BREAKPOINT_SIZE]; /* Contents of addr while
42 #define SIM_BREAK_INSERTED 0x1 /* Breakpoint has been inserted */
43 #define SIM_BREAK_DISABLED 0x2 /* Breakpoint is disabled */
45 static unsigned char sim_breakpoint [] = SIM_BREAKPOINT;
47 static void insert_breakpoint PARAMS ((SIM_DESC sd,
48 struct sim_breakpoint *bp));
49 static void remove_breakpoint PARAMS ((SIM_DESC sd,
50 struct sim_breakpoint *bp));
51 static SIM_RC resume_handler PARAMS ((SIM_DESC sd));
52 static SIM_RC suspend_handler PARAMS ((SIM_DESC sd));
55 /* Do the actual work of inserting a breakpoint into the instruction
59 insert_breakpoint (sd, bp)
61 struct sim_breakpoint *bp;
63 if (bp->flags & (SIM_BREAK_INSERTED | SIM_BREAK_DISABLED))
66 sim_core_read_buffer (sd, NULL, exec_map, bp->loc_contents,
67 bp->addr, SIM_BREAKPOINT_SIZE);
68 sim_core_write_buffer (sd, NULL, exec_map, sim_breakpoint,
69 bp->addr, SIM_BREAKPOINT_SIZE);
70 bp->flags |= SIM_BREAK_INSERTED;
73 /* Do the actual work of removing a breakpoint. */
76 remove_breakpoint (sd, bp)
78 struct sim_breakpoint *bp;
80 if (!(bp->flags & SIM_BREAK_INSERTED))
83 sim_core_write_buffer (sd, NULL, exec_map, bp->loc_contents,
84 bp->addr, SIM_BREAKPOINT_SIZE);
85 bp->flags &= ~SIM_BREAK_INSERTED;
88 /* Come here when a breakpoint insn is hit. If it's really a breakpoint, we
89 halt things, and never return. If it's a false hit, we return to let the
90 caller handle things. */
93 sim_handle_breakpoint (sd, cpu, cia)
98 struct sim_breakpoint *bp;
100 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
101 if (bp->addr == CIA_ADDR (cia))
104 if (!bp || !(bp->flags & SIM_BREAK_INSERTED))
107 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia, sim_stopped, SIM_SIGTRAP);
110 /* Handler functions for simulator resume and suspend events. */
116 struct sim_breakpoint *bp;
118 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
119 insert_breakpoint (sd, bp);
128 struct sim_breakpoint *bp;
130 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
131 remove_breakpoint (sd, bp);
136 /* Called from simulator module initialization. */
139 sim_break_install (sd)
142 sim_module_add_resume_fn (sd, resume_handler);
143 sim_module_add_suspend_fn (sd, suspend_handler);
148 /* Install a breakpoint. This is a user-function. The breakpoint isn't
149 actually installed here. We just record it. Resume_handler does the
154 sim_set_breakpoint (sd, addr)
158 struct sim_breakpoint *bp;
160 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
161 if (bp->addr == addr)
162 return SIM_RC_DUPLICATE_BREAKPOINT; /* Already there */
164 break; /* FIXME: why not scan all bp's? */
166 bp = ZALLOC (struct sim_breakpoint);
169 bp->next = STATE_BREAKPOINTS (sd);
171 STATE_BREAKPOINTS (sd) = bp;
176 /* Delete a breakpoint. All knowlege of the breakpoint is removed from the
181 sim_clear_breakpoint (sd, addr)
185 struct sim_breakpoint *bp, *bpprev;
187 for (bp = STATE_BREAKPOINTS (sd), bpprev = NULL;
189 bpprev = bp, bp = bp->next)
190 if (bp->addr == addr)
194 return SIM_RC_UNKNOWN_BREAKPOINT;
196 remove_breakpoint (sd, bp);
199 bpprev->next = bp->next;
201 STATE_BREAKPOINTS (sd) = NULL;
209 sim_clear_all_breakpoints (sd)
212 while (STATE_BREAKPOINTS (sd))
213 sim_clear_breakpoint (sd, STATE_BREAKPOINTS (sd)->addr);
219 sim_enable_breakpoint (sd, addr)
223 struct sim_breakpoint *bp;
225 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
226 if (bp->addr == addr)
230 return SIM_RC_UNKNOWN_BREAKPOINT;
232 bp->flags &= ~SIM_BREAK_DISABLED;
238 sim_disable_breakpoint (sd, addr)
242 struct sim_breakpoint *bp;
244 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
245 if (bp->addr == addr)
249 return SIM_RC_UNKNOWN_BREAKPOINT;
251 bp->flags |= SIM_BREAK_DISABLED;
257 sim_enable_all_breakpoints (sd)
260 struct sim_breakpoint *bp;
262 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
263 bp->flags &= ~SIM_BREAK_DISABLED;
269 sim_disable_all_breakpoints (sd)
272 struct sim_breakpoint *bp;
274 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
275 bp->flags |= SIM_BREAK_DISABLED;