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 2 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, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
25 const unsigned char *breakpoint_data
;
28 #define MAX_BREAKPOINT_LEN 8
32 struct breakpoint
*next
;
34 unsigned char old_data
[MAX_BREAKPOINT_LEN
];
36 /* Non-zero iff we are stepping over this breakpoint. */
39 /* Non-NULL iff this breakpoint was inserted to step over
40 another one. Points to the other breakpoint (which is also
41 in the *next chain somewhere). */
42 struct breakpoint
*breakpoint_to_reinsert
;
44 /* Function to call when we hit this breakpoint. */
45 void (*handler
) (CORE_ADDR
);
48 struct breakpoint
*breakpoints
;
51 set_breakpoint_at (CORE_ADDR where
, void (*handler
) (CORE_ADDR
))
53 struct breakpoint
*bp
;
55 if (breakpoint_data
== NULL
)
56 error ("Target does not support breakpoints.");
58 bp
= malloc (sizeof (struct breakpoint
));
59 memset (bp
, 0, sizeof (struct breakpoint
));
61 (*the_target
->read_memory
) (where
, bp
->old_data
,
63 (*the_target
->write_memory
) (where
, breakpoint_data
,
67 bp
->handler
= handler
;
69 bp
->next
= breakpoints
;
74 delete_breakpoint (struct breakpoint
*bp
)
76 struct breakpoint
*cur
;
78 if (breakpoints
== bp
)
80 breakpoints
= bp
->next
;
81 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
92 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
98 warning ("Could not find breakpoint in list.");
101 static struct breakpoint
*
102 find_breakpoint_at (CORE_ADDR where
)
104 struct breakpoint
*bp
= breakpoints
;
117 reinsert_breakpoint_handler (CORE_ADDR stop_pc
)
119 struct breakpoint
*stop_bp
, *orig_bp
;
121 stop_bp
= find_breakpoint_at (stop_pc
);
123 error ("lost the stopping breakpoint.");
125 orig_bp
= stop_bp
->breakpoint_to_reinsert
;
127 error ("no breakpoint to reinsert");
129 (*the_target
->write_memory
) (orig_bp
->pc
, breakpoint_data
,
131 orig_bp
->reinserting
= 0;
132 delete_breakpoint (stop_bp
);
136 reinsert_breakpoint_by_bp (CORE_ADDR stop_pc
, CORE_ADDR stop_at
)
138 struct breakpoint
*bp
, *orig_bp
;
140 set_breakpoint_at (stop_at
, reinsert_breakpoint_handler
);
142 orig_bp
= find_breakpoint_at (stop_pc
);
144 error ("Could not find original breakpoint in list.");
146 bp
= find_breakpoint_at (stop_at
);
148 error ("Could not find breakpoint in list (reinserting by breakpoint).");
149 bp
->breakpoint_to_reinsert
= orig_bp
;
151 (*the_target
->write_memory
) (orig_bp
->pc
, orig_bp
->old_data
,
153 orig_bp
->reinserting
= 1;
157 uninsert_breakpoint (CORE_ADDR stopped_at
)
159 struct breakpoint
*bp
;
161 bp
= find_breakpoint_at (stopped_at
);
163 error ("Could not find breakpoint in list (uninserting).");
165 (*the_target
->write_memory
) (bp
->pc
, bp
->old_data
,
171 reinsert_breakpoint (CORE_ADDR stopped_at
)
173 struct breakpoint
*bp
;
175 bp
= find_breakpoint_at (stopped_at
);
177 error ("Could not find breakpoint in list (uninserting).");
178 if (! bp
->reinserting
)
179 error ("Breakpoint already inserted at reinsert time.");
181 (*the_target
->write_memory
) (bp
->pc
, breakpoint_data
,
187 check_breakpoints (CORE_ADDR stop_pc
)
189 struct breakpoint
*bp
;
191 bp
= find_breakpoint_at (stop_pc
);
196 warning ("Hit a removed breakpoint?");
200 (*bp
->handler
) (bp
->pc
);
205 set_breakpoint_data (const unsigned char *bp_data
, int bp_len
)
207 breakpoint_data
= bp_data
;
208 breakpoint_len
= bp_len
;
212 check_mem_read (CORE_ADDR mem_addr
, unsigned char *buf
, int mem_len
)
214 struct breakpoint
*bp
= breakpoints
;
215 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
217 for (; bp
!= NULL
; bp
= bp
->next
)
219 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
220 CORE_ADDR start
, end
;
221 int copy_offset
, copy_len
, buf_offset
;
223 if (mem_addr
>= bp_end
)
225 if (bp
->pc
>= mem_end
)
229 if (mem_addr
> start
)
236 copy_len
= end
- start
;
237 copy_offset
= start
- bp
->pc
;
238 buf_offset
= start
- mem_addr
;
240 memcpy (buf
+ buf_offset
, bp
->old_data
+ copy_offset
, copy_len
);
245 check_mem_write (CORE_ADDR mem_addr
, unsigned char *buf
, int mem_len
)
247 struct breakpoint
*bp
= breakpoints
;
248 CORE_ADDR mem_end
= mem_addr
+ mem_len
;
250 for (; bp
!= NULL
; bp
= bp
->next
)
252 CORE_ADDR bp_end
= bp
->pc
+ breakpoint_len
;
253 CORE_ADDR start
, end
;
254 int copy_offset
, copy_len
, buf_offset
;
256 if (mem_addr
>= bp_end
)
258 if (bp
->pc
>= mem_end
)
262 if (mem_addr
> start
)
269 copy_len
= end
- start
;
270 copy_offset
= start
- bp
->pc
;
271 buf_offset
= start
- mem_addr
;
273 memcpy (bp
->old_data
+ copy_offset
, buf
+ buf_offset
, copy_len
);
274 if (bp
->reinserting
== 0)
275 memcpy (buf
+ buf_offset
, breakpoint_data
+ copy_offset
, copy_len
);