]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/sim-break.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / sim / common / sim-break.c
CommitLineData
b9d580a4
SG
1/* Simulator breakpoint support.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include <stdio.h>
b9d580a4
SG
22
23#include "sim-main.h"
24#include "sim-assert.h"
25#include "sim-break.h"
26
27#ifndef SIM_BREAKPOINT
28#define SIM_BREAKPOINT {0x00}
29#define SIM_BREAKPOINT_SIZE (1)
30#endif
31
32struct
33sim_breakpoint
34{
35 struct sim_breakpoint *next;
36 SIM_ADDR addr; /* Address of this breakpoint */
37 int flags;
38 unsigned char loc_contents[SIM_BREAKPOINT_SIZE]; /* Contents of addr while
39 BP is enabled */
40};
41
42#define SIM_BREAK_INSERTED 0x1 /* Breakpoint has been inserted */
43#define SIM_BREAK_DISABLED 0x2 /* Breakpoint is disabled */
44
45static unsigned char sim_breakpoint [] = SIM_BREAKPOINT;
46
47static void insert_breakpoint PARAMS ((SIM_DESC sd,
48 struct sim_breakpoint *bp));
49static void remove_breakpoint PARAMS ((SIM_DESC sd,
50 struct sim_breakpoint *bp));
51static SIM_RC resume_handler PARAMS ((SIM_DESC sd));
52static SIM_RC suspend_handler PARAMS ((SIM_DESC sd));
53
54
eefc25e5
AC
55/* Do the actual work of inserting a breakpoint into the instruction
56 stream. */
b9d580a4
SG
57
58static void
59insert_breakpoint (sd, bp)
60 SIM_DESC sd;
61 struct sim_breakpoint *bp;
62{
63 if (bp->flags & (SIM_BREAK_INSERTED | SIM_BREAK_DISABLED))
64 return;
65
eefc25e5 66 sim_core_read_buffer (sd, NULL, exec_map, bp->loc_contents,
b9d580a4 67 bp->addr, SIM_BREAKPOINT_SIZE);
eefc25e5 68 sim_core_write_buffer (sd, NULL, exec_map, sim_breakpoint,
b9d580a4
SG
69 bp->addr, SIM_BREAKPOINT_SIZE);
70 bp->flags |= SIM_BREAK_INSERTED;
71}
72
73/* Do the actual work of removing a breakpoint. */
74
75static void
76remove_breakpoint (sd, bp)
77 SIM_DESC sd;
78 struct sim_breakpoint *bp;
79{
80 if (!(bp->flags & SIM_BREAK_INSERTED))
81 return;
82
eefc25e5 83 sim_core_write_buffer (sd, NULL, exec_map, bp->loc_contents,
b9d580a4 84 bp->addr, SIM_BREAKPOINT_SIZE);
84c6d152 85 bp->flags &= ~SIM_BREAK_INSERTED;
b9d580a4
SG
86}
87
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. */
91
92void
93sim_handle_breakpoint (sd, cpu, cia)
94 SIM_DESC sd;
95 sim_cpu *cpu;
96 sim_cia cia;
97{
98 struct sim_breakpoint *bp;
99
100 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
13c9499d 101 if (bp->addr == CIA_ADDR (cia))
b9d580a4
SG
102 break;
103
104 if (!bp || !(bp->flags & SIM_BREAK_INSERTED))
105 return;
106
1ebc7e0e 107 sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia, sim_stopped, SIM_SIGTRAP);
b9d580a4
SG
108}
109
110/* Handler functions for simulator resume and suspend events. */
111
112static SIM_RC
113resume_handler (sd)
114 SIM_DESC sd;
115{
116 struct sim_breakpoint *bp;
117
118 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
119 insert_breakpoint (sd, bp);
120
121 return SIM_RC_OK;
122}
123
124static SIM_RC
125suspend_handler (sd)
126 SIM_DESC sd;
127{
128 struct sim_breakpoint *bp;
129
130 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
131 remove_breakpoint (sd, bp);
132
133 return SIM_RC_OK;
134}
135
136/* Called from simulator module initialization. */
137
138SIM_RC
139sim_break_install (sd)
140 SIM_DESC sd;
141{
142 sim_module_add_resume_fn (sd, resume_handler);
143 sim_module_add_suspend_fn (sd, suspend_handler);
144
145 return SIM_RC_OK;
146}
147
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
150 actual work.
151*/
152
153SIM_RC
154sim_set_breakpoint (sd, addr)
155 SIM_DESC sd;
156 SIM_ADDR addr;
157{
158 struct sim_breakpoint *bp;
159
160 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
161 if (bp->addr == addr)
162 return SIM_RC_DUPLICATE_BREAKPOINT; /* Already there */
163 else
84c6d152 164 break; /* FIXME: why not scan all bp's? */
b9d580a4 165
68f92f98 166 bp = ZALLOC (struct sim_breakpoint);
b9d580a4
SG
167
168 bp->addr = addr;
169 bp->next = STATE_BREAKPOINTS (sd);
170 bp->flags = 0;
171 STATE_BREAKPOINTS (sd) = bp;
172
173 return SIM_RC_OK;
174}
175
176/* Delete a breakpoint. All knowlege of the breakpoint is removed from the
177 simulator.
178*/
179
180SIM_RC
181sim_clear_breakpoint (sd, addr)
182 SIM_DESC sd;
183 SIM_ADDR addr;
184{
185 struct sim_breakpoint *bp, *bpprev;
186
187 for (bp = STATE_BREAKPOINTS (sd), bpprev = NULL;
188 bp;
189 bpprev = bp, bp = bp->next)
190 if (bp->addr == addr)
191 break;
192
193 if (!bp)
194 return SIM_RC_UNKNOWN_BREAKPOINT;
195
196 remove_breakpoint (sd, bp);
197
198 if (bpprev)
199 bpprev->next = bp->next;
200 else
201 STATE_BREAKPOINTS (sd) = NULL;
202
68f92f98 203 zfree (bp);
b9d580a4
SG
204
205 return SIM_RC_OK;
206}
207
208SIM_RC
209sim_clear_all_breakpoints (sd)
210 SIM_DESC sd;
211{
212 while (STATE_BREAKPOINTS (sd))
213 sim_clear_breakpoint (sd, STATE_BREAKPOINTS (sd)->addr);
214
215 return SIM_RC_OK;
216}
217
218SIM_RC
219sim_enable_breakpoint (sd, addr)
220 SIM_DESC sd;
221 SIM_ADDR addr;
222{
223 struct sim_breakpoint *bp;
224
225 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
226 if (bp->addr == addr)
227 break;
228
229 if (!bp)
230 return SIM_RC_UNKNOWN_BREAKPOINT;
231
232 bp->flags &= ~SIM_BREAK_DISABLED;
233
234 return SIM_RC_OK;
235}
236
237SIM_RC
238sim_disable_breakpoint (sd, addr)
239 SIM_DESC sd;
240 SIM_ADDR addr;
241{
242 struct sim_breakpoint *bp;
243
244 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
245 if (bp->addr == addr)
246 break;
247
248 if (!bp)
249 return SIM_RC_UNKNOWN_BREAKPOINT;
250
251 bp->flags |= SIM_BREAK_DISABLED;
252
253 return SIM_RC_OK;
254}
255
256SIM_RC
257sim_enable_all_breakpoints (sd)
258 SIM_DESC sd;
259{
260 struct sim_breakpoint *bp;
261
262 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
263 bp->flags &= ~SIM_BREAK_DISABLED;
264
265 return SIM_RC_OK;
266}
267
268SIM_RC
269sim_disable_all_breakpoints (sd)
270 SIM_DESC sd;
271{
272 struct sim_breakpoint *bp;
273
274 for (bp = STATE_BREAKPOINTS (sd); bp; bp = bp->next)
275 bp->flags |= SIM_BREAK_DISABLED;
276
277 return SIM_RC_OK;
278}