1 /* Memory breakpoint operations for the remote server for GDB.
2 Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
4 Contributed by MontaVista Software.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 const unsigned char *breakpoint_data;
26 #define MAX_BREAKPOINT_LEN 8
30 struct breakpoint *next;
32 unsigned char old_data[MAX_BREAKPOINT_LEN];
34 /* Non-zero iff we are stepping over this breakpoint. */
37 /* Non-NULL iff this breakpoint was inserted to step over
38 another one. Points to the other breakpoint (which is also
39 in the *next chain somewhere). */
40 struct breakpoint *breakpoint_to_reinsert;
42 /* Function to call when we hit this breakpoint. */
43 void (*handler) (CORE_ADDR);
46 struct breakpoint *breakpoints;
49 set_breakpoint_at (CORE_ADDR where, void (*handler) (CORE_ADDR))
51 struct breakpoint *bp;
53 if (breakpoint_data == NULL)
54 error ("Target does not support breakpoints.");
56 bp = malloc (sizeof (struct breakpoint));
57 memset (bp, 0, sizeof (struct breakpoint));
59 (*the_target->read_memory) (where, bp->old_data,
61 (*the_target->write_memory) (where, breakpoint_data,
65 bp->handler = handler;
67 bp->next = breakpoints;
72 delete_breakpoint (struct breakpoint *bp)
74 struct breakpoint *cur;
76 if (breakpoints == bp)
78 breakpoints = bp->next;
79 (*the_target->write_memory) (bp->pc, bp->old_data,
90 (*the_target->write_memory) (bp->pc, bp->old_data,
96 warning ("Could not find breakpoint in list.");
99 static struct breakpoint *
100 find_breakpoint_at (CORE_ADDR where)
102 struct breakpoint *bp = breakpoints;
115 delete_breakpoint_at (CORE_ADDR addr)
117 struct breakpoint *bp = find_breakpoint_at (addr);
119 delete_breakpoint (bp);
123 reinsert_breakpoint_handler (CORE_ADDR stop_pc)
125 struct breakpoint *stop_bp, *orig_bp;
127 stop_bp = find_breakpoint_at (stop_pc);
129 error ("lost the stopping breakpoint.");
131 orig_bp = stop_bp->breakpoint_to_reinsert;
133 error ("no breakpoint to reinsert");
135 (*the_target->write_memory) (orig_bp->pc, breakpoint_data,
137 orig_bp->reinserting = 0;
138 delete_breakpoint (stop_bp);
142 reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at)
144 struct breakpoint *bp, *orig_bp;
146 set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
148 orig_bp = find_breakpoint_at (stop_pc);
150 error ("Could not find original breakpoint in list.");
152 bp = find_breakpoint_at (stop_at);
154 error ("Could not find breakpoint in list (reinserting by breakpoint).");
155 bp->breakpoint_to_reinsert = orig_bp;
157 (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data,
159 orig_bp->reinserting = 1;
163 uninsert_breakpoint (CORE_ADDR stopped_at)
165 struct breakpoint *bp;
167 bp = find_breakpoint_at (stopped_at);
169 error ("Could not find breakpoint in list (uninserting).");
171 (*the_target->write_memory) (bp->pc, bp->old_data,
177 reinsert_breakpoint (CORE_ADDR stopped_at)
179 struct breakpoint *bp;
181 bp = find_breakpoint_at (stopped_at);
183 error ("Could not find breakpoint in list (uninserting).");
184 if (! bp->reinserting)
185 error ("Breakpoint already inserted at reinsert time.");
187 (*the_target->write_memory) (bp->pc, breakpoint_data,
193 check_breakpoints (CORE_ADDR stop_pc)
195 struct breakpoint *bp;
197 bp = find_breakpoint_at (stop_pc);
202 warning ("Hit a removed breakpoint?");
206 (*bp->handler) (bp->pc);
211 set_breakpoint_data (const unsigned char *bp_data, int bp_len)
213 breakpoint_data = bp_data;
214 breakpoint_len = bp_len;
218 check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
220 struct breakpoint *bp = breakpoints;
221 CORE_ADDR mem_end = mem_addr + mem_len;
223 for (; bp != NULL; bp = bp->next)
225 CORE_ADDR bp_end = bp->pc + breakpoint_len;
226 CORE_ADDR start, end;
227 int copy_offset, copy_len, buf_offset;
229 if (mem_addr >= bp_end)
231 if (bp->pc >= mem_end)
235 if (mem_addr > start)
242 copy_len = end - start;
243 copy_offset = start - bp->pc;
244 buf_offset = start - mem_addr;
246 memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
251 check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
253 struct breakpoint *bp = breakpoints;
254 CORE_ADDR mem_end = mem_addr + mem_len;
256 for (; bp != NULL; bp = bp->next)
258 CORE_ADDR bp_end = bp->pc + breakpoint_len;
259 CORE_ADDR start, end;
260 int copy_offset, copy_len, buf_offset;
262 if (mem_addr >= bp_end)
264 if (bp->pc >= mem_end)
268 if (mem_addr > start)
275 copy_len = end - start;
276 copy_offset = start - bp->pc;
277 buf_offset = start - mem_addr;
279 memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
280 if (bp->reinserting == 0)
281 memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
285 /* Delete all breakpoints. */
288 delete_all_breakpoints (void)
291 delete_breakpoint (breakpoints);