* linux-low.c (linux_wait_1): Avoid setting need_step_over is
[deliverable/binutils-gdb.git] / gdb / gdbserver / mem-break.c
... / ...
CommitLineData
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.
4
5 Contributed by MontaVista Software.
6
7 This file is part of GDB.
8
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.
13
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.
18
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/>. */
21
22#include "server.h"
23
24const unsigned char *breakpoint_data;
25int breakpoint_len;
26
27#define MAX_BREAKPOINT_LEN 8
28
29/* GDB will never try to install multiple breakpoints at the same
30 address. But, we need to keep track of internal breakpoints too,
31 and so we do need to be able to install multiple breakpoints at the
32 same address transparently. We keep track of two different, and
33 closely related structures. A raw breakpoint, which manages the
34 low level, close to the metal aspect of a breakpoint. It holds the
35 breakpoint address, and a buffer holding a copy of the instructions
36 that would be in memory had not been a breakpoint there (we call
37 that the shadow memory of the breakpoint). We occasionally need to
38 temporarilly uninsert a breakpoint without the client knowing about
39 it (e.g., to step over an internal breakpoint), so we keep an
40 `inserted' state associated with this low level breakpoint
41 structure. There can only be one such object for a given address.
42 Then, we have (a bit higher level) breakpoints. This structure
43 holds a callback to be called whenever a breakpoint is hit, a
44 high-level type, and a link to a low level raw breakpoint. There
45 can be many high-level breakpoints at the same address, and all of
46 them will point to the same raw breakpoint, which is reference
47 counted. */
48
49/* The low level, physical, raw breakpoint. */
50struct raw_breakpoint
51{
52 struct raw_breakpoint *next;
53
54 /* A reference count. Each high level breakpoint referencing this
55 raw breakpoint accounts for one reference. */
56 int refcount;
57
58 /* The breakpoint's insertion address. There can only be one raw
59 breakpoint for a given PC. */
60 CORE_ADDR pc;
61
62 /* The breakpoint's shadow memory. */
63 unsigned char old_data[MAX_BREAKPOINT_LEN];
64
65 /* Non-zero if this breakpoint is currently inserted in the
66 inferior. */
67 int inserted;
68};
69
70/* The type of a breakpoint. */
71enum bkpt_type
72 {
73 /* A GDB breakpoint, requested with a Z0 packet. */
74 gdb_breakpoint,
75
76 /* A basic-software-single-step breakpoint. */
77 reinsert_breakpoint,
78
79 /* Any other breakpoint type that doesn't require specific
80 treatment goes here. E.g., an event breakpoint. */
81 other_breakpoint,
82 };
83
84/* A high level (in gdbserver's perspective) breakpoint. */
85struct breakpoint
86{
87 struct breakpoint *next;
88
89 /* The breakpoint's type. */
90 enum bkpt_type type;
91
92 /* Link to this breakpoint's raw breakpoint. This is always
93 non-NULL. */
94 struct raw_breakpoint *raw;
95
96 /* Function to call when we hit this breakpoint. If it returns 1,
97 the breakpoint shall be deleted; 0 or if this callback is NULL,
98 it will be left inserted. */
99 int (*handler) (CORE_ADDR);
100};
101
102static struct raw_breakpoint *
103find_raw_breakpoint_at (CORE_ADDR where)
104{
105 struct process_info *proc = current_process ();
106 struct raw_breakpoint *bp;
107
108 for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
109 if (bp->pc == where)
110 return bp;
111
112 return NULL;
113}
114
115static struct raw_breakpoint *
116set_raw_breakpoint_at (CORE_ADDR where)
117{
118 struct process_info *proc = current_process ();
119 struct raw_breakpoint *bp;
120 int err;
121
122 if (breakpoint_data == NULL)
123 error ("Target does not support breakpoints.");
124
125 bp = find_raw_breakpoint_at (where);
126 if (bp != NULL)
127 {
128 bp->refcount++;
129 return bp;
130 }
131
132 bp = xcalloc (1, sizeof (*bp));
133 bp->pc = where;
134 bp->refcount = 1;
135
136 err = (*the_target->read_memory) (where, bp->old_data,
137 breakpoint_len);
138 if (err != 0)
139 {
140 if (debug_threads)
141 fprintf (stderr,
142 "Failed to read shadow memory of"
143 " breakpoint at 0x%s (%s).\n",
144 paddress (where), strerror (err));
145 free (bp);
146 return NULL;
147 }
148
149 err = (*the_target->write_memory) (where, breakpoint_data,
150 breakpoint_len);
151 if (err != 0)
152 {
153 if (debug_threads)
154 fprintf (stderr,
155 "Failed to insert breakpoint at 0x%s (%s).\n",
156 paddress (where), strerror (err));
157 free (bp);
158 return NULL;
159 }
160
161 /* Link the breakpoint in. */
162 bp->inserted = 1;
163 bp->next = proc->raw_breakpoints;
164 proc->raw_breakpoints = bp;
165 return bp;
166}
167
168struct breakpoint *
169set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
170{
171 struct process_info *proc = current_process ();
172 struct breakpoint *bp;
173 struct raw_breakpoint *raw;
174
175 raw = set_raw_breakpoint_at (where);
176
177 if (raw == NULL)
178 {
179 /* warn? */
180 return NULL;
181 }
182
183 bp = xcalloc (1, sizeof (struct breakpoint));
184 bp->type = other_breakpoint;
185
186 bp->raw = raw;
187 bp->handler = handler;
188
189 bp->next = proc->breakpoints;
190 proc->breakpoints = bp;
191
192 return bp;
193}
194
195static int
196delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
197{
198 struct raw_breakpoint *bp, **bp_link;
199 int ret;
200
201 bp = proc->raw_breakpoints;
202 bp_link = &proc->raw_breakpoints;
203
204 while (bp)
205 {
206 if (bp == todel)
207 {
208 if (bp->inserted)
209 {
210 struct raw_breakpoint *prev_bp_link = *bp_link;
211
212 *bp_link = bp->next;
213
214 ret = (*the_target->write_memory) (bp->pc, bp->old_data,
215 breakpoint_len);
216 if (ret != 0)
217 {
218 /* Something went wrong, relink the breakpoint. */
219 *bp_link = prev_bp_link;
220
221 if (debug_threads)
222 fprintf (stderr,
223 "Failed to uninsert raw breakpoint "
224 "at 0x%s (%s) while deleting it.\n",
225 paddress (bp->pc), strerror (ret));
226 return ret;
227 }
228
229 }
230 else
231 *bp_link = bp->next;
232
233 free (bp);
234 return 0;
235 }
236 else
237 {
238 bp_link = &bp->next;
239 bp = *bp_link;
240 }
241 }
242
243 warning ("Could not find raw breakpoint in list.");
244 return ENOENT;
245}
246
247static int
248release_breakpoint (struct process_info *proc, struct breakpoint *bp)
249{
250 int newrefcount;
251 int ret;
252
253 newrefcount = bp->raw->refcount - 1;
254 if (newrefcount == 0)
255 {
256 ret = delete_raw_breakpoint (proc, bp->raw);
257 if (ret != 0)
258 return ret;
259 }
260 else
261 bp->raw->refcount = newrefcount;
262
263 free (bp);
264
265 return 0;
266}
267
268static int
269delete_breakpoint_1 (struct process_info *proc, struct breakpoint *todel)
270{
271 struct breakpoint *bp, **bp_link;
272 int err;
273
274 bp = proc->breakpoints;
275 bp_link = &proc->breakpoints;
276
277 while (bp)
278 {
279 if (bp == todel)
280 {
281 *bp_link = bp->next;
282
283 err = release_breakpoint (proc, bp);
284 if (err != 0)
285 return err;
286
287 bp = *bp_link;
288 return 0;
289 }
290 else
291 {
292 bp_link = &bp->next;
293 bp = *bp_link;
294 }
295 }
296
297 warning ("Could not find breakpoint in list.");
298 return ENOENT;
299}
300
301static int
302delete_breakpoint (struct breakpoint *todel)
303{
304 struct process_info *proc = current_process ();
305 return delete_breakpoint_1 (proc, todel);
306}
307
308static struct breakpoint *
309find_gdb_breakpoint_at (CORE_ADDR where)
310{
311 struct process_info *proc = current_process ();
312 struct breakpoint *bp;
313
314 for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
315 if (bp->type == gdb_breakpoint && bp->raw->pc == where)
316 return bp;
317
318 return NULL;
319}
320
321int
322set_gdb_breakpoint_at (CORE_ADDR where)
323{
324 struct breakpoint *bp;
325
326 if (breakpoint_data == NULL)
327 return 1;
328
329 bp = set_breakpoint_at (where, NULL);
330 if (bp == NULL)
331 return -1;
332
333 bp->type = gdb_breakpoint;
334 return 0;
335}
336
337int
338delete_gdb_breakpoint_at (CORE_ADDR addr)
339{
340 struct breakpoint *bp;
341 int err;
342
343 if (breakpoint_data == NULL)
344 return 1;
345
346 bp = find_gdb_breakpoint_at (addr);
347 if (bp == NULL)
348 return -1;
349
350 err = delete_breakpoint (bp);
351 if (err)
352 return -1;
353
354 return 0;
355}
356
357int
358gdb_breakpoint_here (CORE_ADDR where)
359{
360 struct breakpoint *bp = find_gdb_breakpoint_at (where);
361
362 return (bp != NULL);
363}
364
365void
366set_reinsert_breakpoint (CORE_ADDR stop_at)
367{
368 struct breakpoint *bp;
369
370 bp = set_breakpoint_at (stop_at, NULL);
371 bp->type = reinsert_breakpoint;
372}
373
374void
375delete_reinsert_breakpoints (void)
376{
377 struct process_info *proc = current_process ();
378 struct breakpoint *bp, **bp_link;
379
380 bp = proc->breakpoints;
381 bp_link = &proc->breakpoints;
382
383 while (bp)
384 {
385 if (bp->type == reinsert_breakpoint)
386 {
387 *bp_link = bp->next;
388 release_breakpoint (proc, bp);
389 bp = *bp_link;
390 }
391 else
392 {
393 bp_link = &bp->next;
394 bp = *bp_link;
395 }
396 }
397}
398
399static void
400uninsert_raw_breakpoint (struct raw_breakpoint *bp)
401{
402 if (bp->inserted)
403 {
404 int err;
405
406 bp->inserted = 0;
407 err = (*the_target->write_memory) (bp->pc, bp->old_data,
408 breakpoint_len);
409 if (err != 0)
410 {
411 bp->inserted = 1;
412
413 if (debug_threads)
414 fprintf (stderr,
415 "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
416 paddress (bp->pc), strerror (err));
417 }
418 }
419}
420
421void
422uninsert_breakpoints_at (CORE_ADDR pc)
423{
424 struct raw_breakpoint *bp;
425
426 bp = find_raw_breakpoint_at (pc);
427 if (bp == NULL)
428 {
429 /* This can happen when we remove all breakpoints while handling
430 a step-over. */
431 if (debug_threads)
432 fprintf (stderr,
433 "Could not find breakpoint at 0x%s "
434 "in list (uninserting).\n",
435 paddress (pc));
436 return;
437 }
438
439 if (bp->inserted)
440 uninsert_raw_breakpoint (bp);
441}
442
443static void
444reinsert_raw_breakpoint (struct raw_breakpoint *bp)
445{
446 int err;
447
448 if (bp->inserted)
449 error ("Breakpoint already inserted at reinsert time.");
450
451 err = (*the_target->write_memory) (bp->pc, breakpoint_data,
452 breakpoint_len);
453 if (err == 0)
454 bp->inserted = 1;
455 else if (debug_threads)
456 fprintf (stderr,
457 "Failed to reinsert breakpoint at 0x%s (%s).\n",
458 paddress (bp->pc), strerror (err));
459}
460
461void
462reinsert_breakpoints_at (CORE_ADDR pc)
463{
464 struct raw_breakpoint *bp;
465
466 bp = find_raw_breakpoint_at (pc);
467 if (bp == NULL)
468 {
469 /* This can happen when we remove all breakpoints while handling
470 a step-over. */
471 if (debug_threads)
472 fprintf (stderr,
473 "Could not find raw breakpoint at 0x%s "
474 "in list (reinserting).\n",
475 paddress (pc));
476 return;
477 }
478
479 reinsert_raw_breakpoint (bp);
480}
481
482void
483check_breakpoints (CORE_ADDR stop_pc)
484{
485 struct process_info *proc = current_process ();
486 struct breakpoint *bp, **bp_link;
487
488 bp = proc->breakpoints;
489 bp_link = &proc->breakpoints;
490
491 while (bp)
492 {
493 if (bp->raw->pc == stop_pc)
494 {
495 if (!bp->raw->inserted)
496 {
497 warning ("Hit a removed breakpoint?");
498 return;
499 }
500
501 if (bp->handler != NULL && (*bp->handler) (stop_pc))
502 {
503 *bp_link = bp->next;
504
505 release_breakpoint (proc, bp);
506
507 bp = *bp_link;
508 continue;
509 }
510 }
511
512 bp_link = &bp->next;
513 bp = *bp_link;
514 }
515}
516
517void
518set_breakpoint_data (const unsigned char *bp_data, int bp_len)
519{
520 breakpoint_data = bp_data;
521 breakpoint_len = bp_len;
522}
523
524int
525breakpoint_here (CORE_ADDR addr)
526{
527 return (find_raw_breakpoint_at (addr) != NULL);
528}
529
530int
531breakpoint_inserted_here (CORE_ADDR addr)
532{
533 struct raw_breakpoint *bp;
534
535 bp = find_raw_breakpoint_at (addr);
536
537 return (bp != NULL && bp->inserted);
538}
539
540void
541check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
542{
543 struct process_info *proc = current_process ();
544 struct raw_breakpoint *bp = proc->raw_breakpoints;
545 CORE_ADDR mem_end = mem_addr + mem_len;
546
547 for (; bp != NULL; bp = bp->next)
548 {
549 CORE_ADDR bp_end = bp->pc + breakpoint_len;
550 CORE_ADDR start, end;
551 int copy_offset, copy_len, buf_offset;
552
553 if (mem_addr >= bp_end)
554 continue;
555 if (bp->pc >= mem_end)
556 continue;
557
558 start = bp->pc;
559 if (mem_addr > start)
560 start = mem_addr;
561
562 end = bp_end;
563 if (end > mem_end)
564 end = mem_end;
565
566 copy_len = end - start;
567 copy_offset = start - bp->pc;
568 buf_offset = start - mem_addr;
569
570 if (bp->inserted)
571 memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
572 }
573}
574
575void
576check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
577{
578 struct process_info *proc = current_process ();
579 struct raw_breakpoint *bp = proc->raw_breakpoints;
580 CORE_ADDR mem_end = mem_addr + mem_len;
581
582 for (; bp != NULL; bp = bp->next)
583 {
584 CORE_ADDR bp_end = bp->pc + breakpoint_len;
585 CORE_ADDR start, end;
586 int copy_offset, copy_len, buf_offset;
587
588 if (mem_addr >= bp_end)
589 continue;
590 if (bp->pc >= mem_end)
591 continue;
592
593 start = bp->pc;
594 if (mem_addr > start)
595 start = mem_addr;
596
597 end = bp_end;
598 if (end > mem_end)
599 end = mem_end;
600
601 copy_len = end - start;
602 copy_offset = start - bp->pc;
603 buf_offset = start - mem_addr;
604
605 memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
606 if (bp->inserted)
607 memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
608 }
609}
610
611/* Delete all breakpoints, and un-insert them from the inferior. */
612
613void
614delete_all_breakpoints (void)
615{
616 struct process_info *proc = current_process ();
617
618 while (proc->breakpoints)
619 delete_breakpoint_1 (proc, proc->breakpoints);
620}
621
622/* Release all breakpoints, but do not try to un-insert them from the
623 inferior. */
624
625void
626free_all_breakpoints (struct process_info *proc)
627{
628 struct raw_breakpoint *raw_bp;
629
630 for (raw_bp = proc->raw_breakpoints; raw_bp != NULL; raw_bp = raw_bp->next)
631 raw_bp->inserted = 0;
632
633 /* Note: use PROC explicitly instead of deferring to
634 delete_all_breakpoints --- CURRENT_INFERIOR may already have been
635 released when we get here. There should be no call to
636 current_process from here on. */
637 while (proc->breakpoints)
638 delete_breakpoint_1 (proc, proc->breakpoints);
639}
This page took 0.034379 seconds and 4 git commands to generate.