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. */
25 #include "sim-assert.h"
26 #include "sim-break.h"
28 #ifndef SIM_BREAKPOINT
29 #define SIM_BREAKPOINT {0x00}
30 #define SIM_BREAKPOINT_SIZE (1)
36 struct sim_breakpoint
*next
;
37 SIM_ADDR addr
; /* Address of this breakpoint */
39 unsigned char loc_contents
[SIM_BREAKPOINT_SIZE
]; /* Contents of addr while
43 #define SIM_BREAK_INSERTED 0x1 /* Breakpoint has been inserted */
44 #define SIM_BREAK_DISABLED 0x2 /* Breakpoint is disabled */
46 static unsigned char sim_breakpoint
[] = SIM_BREAKPOINT
;
48 static void insert_breakpoint
PARAMS ((SIM_DESC sd
,
49 struct sim_breakpoint
*bp
));
50 static void remove_breakpoint
PARAMS ((SIM_DESC sd
,
51 struct sim_breakpoint
*bp
));
52 static SIM_RC resume_handler
PARAMS ((SIM_DESC sd
));
53 static SIM_RC suspend_handler
PARAMS ((SIM_DESC sd
));
56 /* Do the actual work of inserting a breakpoint into the instruction stream. */
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
, sim_core_write_map
, bp
->loc_contents
,
67 bp
->addr
, SIM_BREAKPOINT_SIZE
);
68 sim_core_write_buffer (sd
, NULL
, sim_core_write_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
, sim_core_write_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
, 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 */
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
;