1 /* Memory breakpoint operations for the remote server for GDB.
3 Free Software Foundation, Inc.
5 Contributed by MontaVista Software.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
26 const char *breakpoint_data
;
29 #define MAX_BREAKPOINT_LEN 8
33 struct breakpoint
*next
;
35 unsigned char old_data
[MAX_BREAKPOINT_LEN
];
37 /* Non-zero iff we are stepping over this breakpoint. */
40 /* Non-NULL iff this breakpoint was inserted to step over
41 another one. Points to the other breakpoint (which is also
42 in the *next chain somewhere). */
43 struct breakpoint
*breakpoint_to_reinsert
;
45 /* Function to call when we hit this breakpoint. */
46 void (*handler
) (CORE_ADDR
);
49 struct breakpoint
*breakpoints
;
52 set_breakpoint_at (CORE_ADDR where
, void (*handler
) (CORE_ADDR
))
54 struct breakpoint
*bp
;
56 if (breakpoint_data
== NULL
)
57 error ("Target does not support breakpoints.");
59 bp
= malloc (sizeof (struct breakpoint
));
60 memset (bp
, 0, sizeof (struct breakpoint
));
62 (*the_target
->read_memory
) (where
, bp
->old_data
,
64 (*the_target
->write_memory
) (where
, breakpoint_data
,
68 bp
->handler
= handler
;
70 bp
->next
= breakpoints
;
75 delete_breakpoint (struct breakpoint
*bp
)
77 struct breakpoint
*cur
;
79 if (breakpoints
== bp
)
81 breakpoints
= bp
->next
;
82 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
93 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
99 warning ("Could not find breakpoint in list.");
102 static struct breakpoint
*
103 find_breakpoint_at (CORE_ADDR where
)
105 struct breakpoint
*bp
= breakpoints
;
118 reinsert_breakpoint_handler (CORE_ADDR stop_pc
)
120 struct breakpoint
*stop_bp
, *orig_bp
;
122 stop_bp
= find_breakpoint_at (stop_pc
);
124 error ("lost the stopping breakpoint.");
126 orig_bp
= stop_bp
->breakpoint_to_reinsert
;
128 error ("no breakpoint to reinsert");
130 (*the_target
->write_memory
) (orig_bp
->pc
, breakpoint_data
,
132 orig_bp
->reinserting
= 0;
133 delete_breakpoint (stop_bp
);
137 reinsert_breakpoint_by_bp (CORE_ADDR stop_pc
, CORE_ADDR stop_at
)
139 struct breakpoint
*bp
, *orig_bp
;
141 set_breakpoint_at (stop_at
, reinsert_breakpoint_handler
);
143 orig_bp
= find_breakpoint_at (stop_pc
);
145 error ("Could not find original breakpoint in list.");
147 bp
= find_breakpoint_at (stop_at
);
149 error ("Could not find breakpoint in list (reinserting by breakpoint).");
150 bp
->breakpoint_to_reinsert
= orig_bp
;
152 (*the_target
->write_memory
) (orig_bp
->pc
, orig_bp
->old_data
,
154 orig_bp
->reinserting
= 1;
158 uninsert_breakpoint (CORE_ADDR stopped_at
)
160 struct breakpoint
*bp
;
162 bp
= find_breakpoint_at (stopped_at
);
164 error ("Could not find breakpoint in list (uninserting).");
166 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
172 reinsert_breakpoint (CORE_ADDR stopped_at
)
174 struct breakpoint
*bp
;
176 bp
= find_breakpoint_at (stopped_at
);
178 error ("Could not find breakpoint in list (uninserting).");
179 if (! bp
->reinserting
)
180 error ("Breakpoint already inserted at reinsert time.");
182 (*the_target
->write_memory
) (bp
->pc
, breakpoint_data
,
188 check_breakpoints (CORE_ADDR stop_pc
)
190 struct breakpoint
*bp
;
192 bp
= find_breakpoint_at (stop_pc
);
197 warning ("Hit a removed breakpoint?");
201 (*bp
->handler
) (bp
->pc
);
206 set_breakpoint_data (const char *bp_data
, int bp_len
)
208 breakpoint_data
= bp_data
;
209 breakpoint_len
= bp_len
;
213 check_mem_read (CORE_ADDR mem_addr
, char *buf
, int mem_len
)
215 struct breakpoint
*bp
= breakpoints
;
216 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
218 for (; bp
!= NULL
; bp
= bp
->next
)
220 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
221 CORE_ADDR start
, end
;
222 int copy_offset
, copy_len
, buf_offset
;
224 if (mem_addr
>= bp_end
)
226 if (bp
->pc
>= mem_end
)
230 if (mem_addr
> start
)
237 copy_len
= end
- start
;
238 copy_offset
= start
- bp
->pc
;
239 buf_offset
= start
- mem_addr
;
241 memcpy (buf
+ buf_offset
, bp
->old_data
+ copy_offset
, copy_len
);
246 check_mem_write (CORE_ADDR mem_addr
, char *buf
, int mem_len
)
248 struct breakpoint
*bp
= breakpoints
;
249 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
251 for (; bp
!= NULL
; bp
= bp
->next
)
253 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
254 CORE_ADDR start
, end
;
255 int copy_offset
, copy_len
, buf_offset
;
257 if (mem_addr
>= bp_end
)
259 if (bp
->pc
>= mem_end
)
263 if (mem_addr
> start
)
270 copy_len
= end
- start
;
271 copy_offset
= start
- bp
->pc
;
272 buf_offset
= start
- mem_addr
;
274 memcpy (bp
->old_data
+ copy_offset
, buf
+ buf_offset
, copy_len
);
275 if (bp
->reinserting
== 0)
276 memcpy (buf
+ buf_offset
, breakpoint_data
+ copy_offset
, copy_len
);