1 /* Memory breakpoint operations for the remote server for GDB.
2 Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010
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 3 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, see <http://www.gnu.org/licenses/>. */
24 const unsigned char *breakpoint_data
;
27 #define MAX_BREAKPOINT_LEN 8
31 struct breakpoint
*next
;
33 unsigned char old_data
[MAX_BREAKPOINT_LEN
];
35 /* Non-zero if this breakpoint is currently inserted in the
39 /* Function to call when we hit this breakpoint. If it returns 1,
40 the breakpoint shall be deleted; 0, it will be left inserted. */
41 int (*handler
) (CORE_ADDR
);
44 static struct breakpoint
*
45 set_raw_breakpoint_at (CORE_ADDR where
)
47 struct process_info
*proc
= current_process ();
48 struct breakpoint
*bp
;
51 if (breakpoint_data
== NULL
)
52 error ("Target does not support breakpoints.");
54 bp
= xcalloc (1, sizeof (*bp
));
57 err
= (*the_target
->read_memory
) (where
, bp
->old_data
,
63 "Failed to read shadow memory of"
64 " breakpoint at 0x%s (%s).\n",
65 paddress (where
), strerror (err
));
70 err
= (*the_target
->write_memory
) (where
, breakpoint_data
,
76 "Failed to insert breakpoint at 0x%s (%s).\n",
77 paddress (where
), strerror (err
));
82 /* Link the breakpoint in. */
84 bp
->next
= proc
->breakpoints
;
85 proc
->breakpoints
= bp
;
90 set_breakpoint_at (CORE_ADDR where
, int (*handler
) (CORE_ADDR
))
92 struct process_info
*proc
= current_process ();
93 struct breakpoint
*bp
;
95 bp
= set_raw_breakpoint_at (where
);
103 bp
= xcalloc (1, sizeof (struct breakpoint
));
104 bp
->handler
= handler
;
106 bp
->next
= proc
->breakpoints
;
107 proc
->breakpoints
= bp
;
111 delete_breakpoint (struct breakpoint
*bp
)
113 struct process_info
*proc
= current_process ();
114 struct breakpoint
*cur
;
116 if (proc
->breakpoints
== bp
)
118 proc
->breakpoints
= bp
->next
;
119 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
124 cur
= proc
->breakpoints
;
129 cur
->next
= bp
->next
;
130 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
136 warning ("Could not find breakpoint in list.");
139 static struct breakpoint
*
140 find_breakpoint_at (CORE_ADDR where
)
142 struct process_info
*proc
= current_process ();
143 struct breakpoint
*bp
= proc
->breakpoints
;
156 delete_breakpoint_at (CORE_ADDR addr
)
158 struct breakpoint
*bp
= find_breakpoint_at (addr
);
160 delete_breakpoint (bp
);
164 set_reinsert_breakpoint (CORE_ADDR stop_at
)
166 set_breakpoint_at (stop_at
, NULL
);
170 delete_reinsert_breakpoints (void)
172 struct process_info
*proc
= current_process ();
173 struct breakpoint
*bp
, **bp_link
;
175 bp
= proc
->breakpoints
;
176 bp_link
= &proc
->breakpoints
;
181 delete_breakpoint (bp
);
187 uninsert_breakpoint (struct breakpoint
*bp
)
194 err
= (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
202 "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
203 paddress (bp
->pc
), strerror (err
));
209 uninsert_breakpoints_at (CORE_ADDR pc
)
211 struct breakpoint
*bp
;
213 bp
= find_breakpoint_at (pc
);
216 /* This can happen when we remove all breakpoints while handling
220 "Could not find breakpoint at 0x%s "
221 "in list (uninserting).\n",
227 uninsert_breakpoint (bp
);
231 reinsert_breakpoint (struct breakpoint
*bp
)
236 error ("Breakpoint already inserted at reinsert time.");
238 err
= (*the_target
->write_memory
) (bp
->pc
, breakpoint_data
,
242 else if (debug_threads
)
244 "Failed to reinsert breakpoint at 0x%s (%s).\n",
245 paddress (bp
->pc
), strerror (err
));
249 reinsert_breakpoints_at (CORE_ADDR pc
)
251 struct breakpoint
*bp
;
253 bp
= find_breakpoint_at (pc
);
256 /* This can happen when we remove all breakpoints while handling
260 "Could not find breakpoint at 0x%s "
261 "in list (reinserting).\n",
266 reinsert_breakpoint (bp
);
270 check_breakpoints (CORE_ADDR stop_pc
)
272 struct process_info
*proc
= current_process ();
273 struct breakpoint
*bp
, **bp_link
;
275 bp
= proc
->breakpoints
;
276 bp_link
= &proc
->breakpoints
;
280 if (bp
->pc
== stop_pc
)
284 warning ("Hit a removed breakpoint?");
288 if (bp
->handler
!= NULL
&& (*bp
->handler
) (stop_pc
))
292 delete_breakpoint (bp
);
305 set_breakpoint_data (const unsigned char *bp_data
, int bp_len
)
307 breakpoint_data
= bp_data
;
308 breakpoint_len
= bp_len
;
312 breakpoint_here (CORE_ADDR addr
)
314 struct process_info
*proc
= current_process ();
315 struct breakpoint
*bp
;
317 for (bp
= proc
->breakpoints
; bp
!= NULL
; bp
= bp
->next
)
325 breakpoint_inserted_here (CORE_ADDR addr
)
327 struct process_info
*proc
= current_process ();
328 struct breakpoint
*bp
;
330 for (bp
= proc
->breakpoints
; bp
!= NULL
; bp
= bp
->next
)
331 if (bp
->pc
== addr
&& bp
->inserted
)
338 check_mem_read (CORE_ADDR mem_addr
, unsigned char *buf
, int mem_len
)
340 struct process_info
*proc
= current_process ();
341 struct breakpoint
*bp
= proc
->breakpoints
;
342 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
344 for (; bp
!= NULL
; bp
= bp
->next
)
346 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
347 CORE_ADDR start
, end
;
348 int copy_offset
, copy_len
, buf_offset
;
350 if (mem_addr
>= bp_end
)
352 if (bp
->pc
>= mem_end
)
356 if (mem_addr
> start
)
363 copy_len
= end
- start
;
364 copy_offset
= start
- bp
->pc
;
365 buf_offset
= start
- mem_addr
;
367 memcpy (buf
+ buf_offset
, bp
->old_data
+ copy_offset
, copy_len
);
372 check_mem_write (CORE_ADDR mem_addr
, unsigned char *buf
, int mem_len
)
374 struct process_info
*proc
= current_process ();
375 struct breakpoint
*bp
= proc
->breakpoints
;
376 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
378 for (; bp
!= NULL
; bp
= bp
->next
)
380 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
381 CORE_ADDR start
, end
;
382 int copy_offset
, copy_len
, buf_offset
;
384 if (mem_addr
>= bp_end
)
386 if (bp
->pc
>= mem_end
)
390 if (mem_addr
> start
)
397 copy_len
= end
- start
;
398 copy_offset
= start
- bp
->pc
;
399 buf_offset
= start
- mem_addr
;
401 memcpy (bp
->old_data
+ copy_offset
, buf
+ buf_offset
, copy_len
);
403 memcpy (buf
+ buf_offset
, breakpoint_data
+ copy_offset
, copy_len
);
407 /* Delete all breakpoints, and un-insert them from the inferior. */
410 delete_all_breakpoints (void)
412 struct process_info
*proc
= current_process ();
414 while (proc
->breakpoints
)
415 delete_breakpoint (proc
->breakpoints
);
418 /* Release all breakpoints, but do not try to un-insert them from the
422 free_all_breakpoints (struct process_info
*proc
)
424 struct breakpoint
*bp
;
426 while (proc
->breakpoints
)
428 bp
= proc
->breakpoints
;
429 proc
->breakpoints
= bp
->next
;
This page took 0.039727 seconds and 4 git commands to generate.