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
29 /* The type of a breakpoint. */
32 /* A basic-software-single-step breakpoint. */
35 /* Any other breakpoint type that doesn't require specific
36 treatment goes here. E.g., an event breakpoint. */
42 struct breakpoint
*next
;
44 unsigned char old_data
[MAX_BREAKPOINT_LEN
];
46 /* Non-zero if this breakpoint is currently inserted in the
50 /* The breakpoint's type. */
53 /* Function to call when we hit this breakpoint. If it returns 1,
54 the breakpoint shall be deleted; 0, it will be left inserted. */
55 int (*handler
) (CORE_ADDR
);
58 static void uninsert_breakpoint (struct breakpoint
*bp
);
60 static struct breakpoint
*
61 set_raw_breakpoint_at (CORE_ADDR where
)
63 struct process_info
*proc
= current_process ();
64 struct breakpoint
*bp
;
67 if (breakpoint_data
== NULL
)
68 error ("Target does not support breakpoints.");
70 bp
= xcalloc (1, sizeof (*bp
));
73 err
= (*the_target
->read_memory
) (where
, bp
->old_data
,
79 "Failed to read shadow memory of"
80 " breakpoint at 0x%s (%s).\n",
81 paddress (where
), strerror (err
));
86 err
= (*the_target
->write_memory
) (where
, breakpoint_data
,
92 "Failed to insert breakpoint at 0x%s (%s).\n",
93 paddress (where
), strerror (err
));
98 /* Link the breakpoint in. */
100 bp
->next
= proc
->breakpoints
;
101 proc
->breakpoints
= bp
;
106 set_breakpoint_at (CORE_ADDR where
, int (*handler
) (CORE_ADDR
))
108 struct process_info
*proc
= current_process ();
109 struct breakpoint
*bp
;
111 bp
= set_raw_breakpoint_at (where
);
119 bp
= xcalloc (1, sizeof (struct breakpoint
));
120 bp
->type
= other_breakpoint
;
121 bp
->handler
= handler
;
123 bp
->next
= proc
->breakpoints
;
124 proc
->breakpoints
= bp
;
130 delete_breakpoint (struct breakpoint
*todel
)
132 struct process_info
*proc
= current_process ();
133 struct breakpoint
*bp
, **bp_link
;
135 bp
= proc
->breakpoints
;
136 bp_link
= &proc
->breakpoints
;
144 uninsert_breakpoint (bp
);
155 warning ("Could not find breakpoint in list.");
158 static struct breakpoint
*
159 find_breakpoint_at (CORE_ADDR where
)
161 struct process_info
*proc
= current_process ();
162 struct breakpoint
*bp
= proc
->breakpoints
;
175 delete_breakpoint_at (CORE_ADDR addr
)
177 struct breakpoint
*bp
= find_breakpoint_at (addr
);
179 delete_breakpoint (bp
);
183 set_reinsert_breakpoint (CORE_ADDR stop_at
)
185 struct breakpoint
*bp
;
187 bp
= set_breakpoint_at (stop_at
, NULL
);
189 bp
->type
= reinsert_breakpoint
;
193 delete_reinsert_breakpoints (void)
195 struct process_info
*proc
= current_process ();
196 struct breakpoint
*bp
, **bp_link
;
198 bp
= proc
->breakpoints
;
199 bp_link
= &proc
->breakpoints
;
203 if (bp
->type
== reinsert_breakpoint
)
207 /* If something goes wrong, maybe this is a shared library
208 breakpoint, and the shared library has been unmapped.
209 Assume the breakpoint is gone anyway. */
210 uninsert_breakpoint (bp
);
224 uninsert_breakpoint (struct breakpoint
*bp
)
231 err
= (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
239 "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
240 paddress (bp
->pc
), strerror (err
));
246 uninsert_breakpoints_at (CORE_ADDR pc
)
248 struct breakpoint
*bp
;
250 bp
= find_breakpoint_at (pc
);
253 /* This can happen when we remove all breakpoints while handling
257 "Could not find breakpoint at 0x%s "
258 "in list (uninserting).\n",
264 uninsert_breakpoint (bp
);
268 reinsert_raw_breakpoint (struct breakpoint
*bp
)
273 error ("Breakpoint already inserted at reinsert time.");
275 err
= (*the_target
->write_memory
) (bp
->pc
, breakpoint_data
,
279 else if (debug_threads
)
281 "Failed to reinsert breakpoint at 0x%s (%s).\n",
282 paddress (bp
->pc
), strerror (err
));
286 reinsert_breakpoints_at (CORE_ADDR pc
)
288 struct breakpoint
*bp
;
290 bp
= find_breakpoint_at (pc
);
293 /* This can happen when we remove all breakpoints while handling
297 "Could not find breakpoint at 0x%s "
298 "in list (reinserting).\n",
303 reinsert_raw_breakpoint (bp
);
307 check_breakpoints (CORE_ADDR stop_pc
)
309 struct process_info
*proc
= current_process ();
310 struct breakpoint
*bp
, **bp_link
;
312 bp
= proc
->breakpoints
;
313 bp_link
= &proc
->breakpoints
;
317 if (bp
->pc
== stop_pc
)
321 warning ("Hit a removed breakpoint?");
325 if (bp
->handler
!= NULL
&& (*bp
->handler
) (stop_pc
))
329 delete_breakpoint (bp
);
342 set_breakpoint_data (const unsigned char *bp_data
, int bp_len
)
344 breakpoint_data
= bp_data
;
345 breakpoint_len
= bp_len
;
349 breakpoint_here (CORE_ADDR addr
)
351 struct process_info
*proc
= current_process ();
352 struct breakpoint
*bp
;
354 for (bp
= proc
->breakpoints
; bp
!= NULL
; bp
= bp
->next
)
362 breakpoint_inserted_here (CORE_ADDR addr
)
364 struct process_info
*proc
= current_process ();
365 struct breakpoint
*bp
;
367 for (bp
= proc
->breakpoints
; bp
!= NULL
; bp
= bp
->next
)
368 if (bp
->pc
== addr
&& bp
->inserted
)
375 check_mem_read (CORE_ADDR mem_addr
, unsigned char *buf
, int mem_len
)
377 struct process_info
*proc
= current_process ();
378 struct breakpoint
*bp
= proc
->breakpoints
;
379 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
381 for (; bp
!= NULL
; bp
= bp
->next
)
383 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
384 CORE_ADDR start
, end
;
385 int copy_offset
, copy_len
, buf_offset
;
387 if (mem_addr
>= bp_end
)
389 if (bp
->pc
>= mem_end
)
393 if (mem_addr
> start
)
400 copy_len
= end
- start
;
401 copy_offset
= start
- bp
->pc
;
402 buf_offset
= start
- mem_addr
;
404 memcpy (buf
+ buf_offset
, bp
->old_data
+ copy_offset
, copy_len
);
409 check_mem_write (CORE_ADDR mem_addr
, unsigned char *buf
, int mem_len
)
411 struct process_info
*proc
= current_process ();
412 struct breakpoint
*bp
= proc
->breakpoints
;
413 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
415 for (; bp
!= NULL
; bp
= bp
->next
)
417 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
418 CORE_ADDR start
, end
;
419 int copy_offset
, copy_len
, buf_offset
;
421 if (mem_addr
>= bp_end
)
423 if (bp
->pc
>= mem_end
)
427 if (mem_addr
> start
)
434 copy_len
= end
- start
;
435 copy_offset
= start
- bp
->pc
;
436 buf_offset
= start
- mem_addr
;
438 memcpy (bp
->old_data
+ copy_offset
, buf
+ buf_offset
, copy_len
);
440 memcpy (buf
+ buf_offset
, breakpoint_data
+ copy_offset
, copy_len
);
444 /* Delete all breakpoints, and un-insert them from the inferior. */
447 delete_all_breakpoints (void)
449 struct process_info
*proc
= current_process ();
451 while (proc
->breakpoints
)
452 delete_breakpoint (proc
->breakpoints
);
455 /* Release all breakpoints, but do not try to un-insert them from the
459 free_all_breakpoints (struct process_info
*proc
)
461 struct breakpoint
*bp
;
463 while (proc
->breakpoints
)
465 bp
= proc
->breakpoints
;
466 proc
->breakpoints
= bp
->next
;
This page took 0.040137 seconds and 4 git commands to generate.