Merge {i386,amd64}_linux_read_description
[deliverable/binutils-gdb.git] / gdb / mem-break.c
CommitLineData
c906108c 1/* Simulate breakpoints by patching locations in the target system, for GDB.
f4f9705a 2
ecd75fc8 3 Copyright (C) 1990-2014 Free Software Foundation, Inc.
f4f9705a 4
c906108c
SS
5 Contributed by Cygnus Support. Written by John Gilmore.
6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
c5aa993b 12 (at your option) any later version.
c906108c 13
c5aa993b
JM
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.
c906108c 18
c5aa993b 19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
c906108c
SS
23#include "symtab.h"
24#include "breakpoint.h"
25#include "inferior.h"
26#include "target.h"
0e9f083f 27#include <string.h>
c906108c
SS
28
29
8181d85f
DJ
30/* Insert a breakpoint on targets that don't have any better
31 breakpoint support. We read the contents of the target location
32 and stash it, then overwrite it with a breakpoint instruction.
33 BP_TGT->placed_address is the target location in the target
34 machine. BP_TGT->shadow_contents is some memory allocated for
35 saving the target contents. It is guaranteed by the caller to be
36 long enough to save BREAKPOINT_LEN bytes (this is accomplished via
37 BREAKPOINT_MAX). */
c906108c
SS
38
39int
ae4b2284
MD
40default_memory_insert_breakpoint (struct gdbarch *gdbarch,
41 struct bp_target_info *bp_tgt)
c906108c
SS
42{
43 int val;
f4f9705a 44 const unsigned char *bp;
35c63cd8 45 gdb_byte *readbuf;
c906108c
SS
46
47 /* Determine appropriate breakpoint contents and size for this address. */
3b3b875c 48 bp = gdbarch_breakpoint_from_pc
ae4b2284 49 (gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
c906108c 50 if (bp == NULL)
8a3fe4f8 51 error (_("Software breakpoints not implemented for this target."));
c906108c 52
35c63cd8
JB
53 /* Save the memory contents in the shadow_contents buffer and then
54 write the breakpoint instruction. */
8181d85f 55 bp_tgt->shadow_len = bp_tgt->placed_size;
35c63cd8
JB
56 readbuf = alloca (bp_tgt->placed_size);
57 val = target_read_memory (bp_tgt->placed_address, readbuf,
8181d85f 58 bp_tgt->placed_size);
c906108c 59 if (val == 0)
35c63cd8
JB
60 {
61 memcpy (bp_tgt->shadow_contents, readbuf, bp_tgt->placed_size);
62 val = target_write_raw_memory (bp_tgt->placed_address, bp,
63 bp_tgt->placed_size);
64 }
c906108c
SS
65
66 return val;
67}
68
69
70int
ae4b2284
MD
71default_memory_remove_breakpoint (struct gdbarch *gdbarch,
72 struct bp_target_info *bp_tgt)
c906108c 73{
f0ba3972
PA
74 return target_write_raw_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
75 bp_tgt->placed_size);
c906108c 76}
917317f4
JM
77
78
917317f4 79int
3db08215 80memory_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
a6d9a66e 81 struct bp_target_info *bp_tgt)
917317f4 82{
a6d9a66e 83 return gdbarch_memory_insert_breakpoint (gdbarch, bp_tgt);
917317f4
JM
84}
85
917317f4 86int
3db08215 87memory_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
a6d9a66e 88 struct bp_target_info *bp_tgt)
917317f4 89{
a6d9a66e 90 return gdbarch_memory_remove_breakpoint (gdbarch, bp_tgt);
917317f4 91}
08351840
PA
92
93int
94memory_validate_breakpoint (struct gdbarch *gdbarch,
95 struct bp_target_info *bp_tgt)
96{
97 CORE_ADDR addr = bp_tgt->placed_address;
98 const gdb_byte *bp;
99 int val;
100 int bplen;
101 gdb_byte cur_contents[BREAKPOINT_MAX];
102 struct cleanup *cleanup;
103 int ret;
104
105 /* Determine appropriate breakpoint contents and size for this
106 address. */
107 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
108
109 if (bp == NULL || bp_tgt->placed_size != bplen)
110 return 0;
111
112 /* Make sure we see the memory breakpoints. */
113 cleanup = make_show_memory_breakpoints_cleanup (1);
114 val = target_read_memory (addr, cur_contents, bplen);
115
116 /* If our breakpoint is no longer at the address, this means that
117 the program modified the code on us, so it is wrong to put back
118 the old value. */
119 ret = (val == 0 && memcmp (bp, cur_contents, bplen) == 0);
120
121 do_cleanups (cleanup);
122 return ret;
123}
This page took 1.226186 seconds and 4 git commands to generate.