mem-break.c revision 1.1.1.3 1 1.1 christos /* Simulate breakpoints by patching locations in the target system, for GDB.
2 1.1 christos
3 1.1.1.2 christos Copyright (C) 1990-2015 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos Contributed by Cygnus Support. Written by John Gilmore.
6 1.1 christos
7 1.1 christos This file is part of GDB.
8 1.1 christos
9 1.1 christos This program is free software; you can redistribute it and/or modify
10 1.1 christos it under the terms of the GNU General Public License as published by
11 1.1 christos the Free Software Foundation; either version 3 of the License, or
12 1.1 christos (at your option) any later version.
13 1.1 christos
14 1.1 christos This program is distributed in the hope that it will be useful,
15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 1.1 christos GNU General Public License for more details.
18 1.1 christos
19 1.1 christos You should have received a copy of the GNU General Public License
20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 1.1 christos
22 1.1 christos #include "defs.h"
23 1.1 christos #include "symtab.h"
24 1.1 christos #include "breakpoint.h"
25 1.1 christos #include "inferior.h"
26 1.1 christos #include "target.h"
27 1.1 christos /* Insert a breakpoint on targets that don't have any better
28 1.1 christos breakpoint support. We read the contents of the target location
29 1.1 christos and stash it, then overwrite it with a breakpoint instruction.
30 1.1 christos BP_TGT->placed_address is the target location in the target
31 1.1 christos machine. BP_TGT->shadow_contents is some memory allocated for
32 1.1 christos saving the target contents. It is guaranteed by the caller to be
33 1.1 christos long enough to save BREAKPOINT_LEN bytes (this is accomplished via
34 1.1 christos BREAKPOINT_MAX). */
35 1.1 christos
36 1.1 christos int
37 1.1 christos default_memory_insert_breakpoint (struct gdbarch *gdbarch,
38 1.1 christos struct bp_target_info *bp_tgt)
39 1.1 christos {
40 1.1.1.2 christos CORE_ADDR addr = bp_tgt->reqstd_address;
41 1.1 christos const unsigned char *bp;
42 1.1 christos gdb_byte *readbuf;
43 1.1.1.2 christos int bplen;
44 1.1.1.2 christos int val;
45 1.1 christos
46 1.1 christos /* Determine appropriate breakpoint contents and size for this address. */
47 1.1.1.2 christos bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
48 1.1 christos if (bp == NULL)
49 1.1 christos error (_("Software breakpoints not implemented for this target."));
50 1.1 christos
51 1.1.1.2 christos bp_tgt->placed_address = addr;
52 1.1.1.2 christos bp_tgt->placed_size = bplen;
53 1.1.1.2 christos
54 1.1 christos /* Save the memory contents in the shadow_contents buffer and then
55 1.1 christos write the breakpoint instruction. */
56 1.1.1.2 christos readbuf = alloca (bplen);
57 1.1.1.2 christos val = target_read_memory (addr, readbuf, bplen);
58 1.1 christos if (val == 0)
59 1.1 christos {
60 1.1.1.3 christos /* These must be set together, either before or after the shadow
61 1.1.1.3 christos read, so that if we're "reinserting" a breakpoint that
62 1.1.1.3 christos doesn't have a shadow yet, the breakpoint masking code inside
63 1.1.1.3 christos target_read_memory doesn't mask out this breakpoint using an
64 1.1.1.3 christos unfilled shadow buffer. The core may be trying to reinsert a
65 1.1.1.3 christos permanent breakpoint, for targets that support breakpoint
66 1.1.1.3 christos conditions/commands on the target side for some types of
67 1.1.1.3 christos breakpoints, such as target remote. */
68 1.1.1.3 christos bp_tgt->shadow_len = bplen;
69 1.1.1.2 christos memcpy (bp_tgt->shadow_contents, readbuf, bplen);
70 1.1.1.3 christos
71 1.1.1.2 christos val = target_write_raw_memory (addr, bp, bplen);
72 1.1 christos }
73 1.1 christos
74 1.1 christos return val;
75 1.1 christos }
76 1.1 christos
77 1.1 christos
78 1.1 christos int
79 1.1 christos default_memory_remove_breakpoint (struct gdbarch *gdbarch,
80 1.1 christos struct bp_target_info *bp_tgt)
81 1.1 christos {
82 1.1 christos return target_write_raw_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
83 1.1 christos bp_tgt->placed_size);
84 1.1 christos }
85 1.1 christos
86 1.1 christos
87 1.1 christos int
88 1.1.1.2 christos memory_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
89 1.1 christos struct bp_target_info *bp_tgt)
90 1.1 christos {
91 1.1 christos return gdbarch_memory_insert_breakpoint (gdbarch, bp_tgt);
92 1.1 christos }
93 1.1 christos
94 1.1 christos int
95 1.1.1.2 christos memory_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
96 1.1 christos struct bp_target_info *bp_tgt)
97 1.1 christos {
98 1.1 christos return gdbarch_memory_remove_breakpoint (gdbarch, bp_tgt);
99 1.1 christos }
100 1.1.1.2 christos
101 1.1.1.2 christos int
102 1.1.1.2 christos memory_validate_breakpoint (struct gdbarch *gdbarch,
103 1.1.1.2 christos struct bp_target_info *bp_tgt)
104 1.1.1.2 christos {
105 1.1.1.2 christos CORE_ADDR addr = bp_tgt->placed_address;
106 1.1.1.2 christos const gdb_byte *bp;
107 1.1.1.2 christos int val;
108 1.1.1.2 christos int bplen;
109 1.1.1.2 christos gdb_byte cur_contents[BREAKPOINT_MAX];
110 1.1.1.2 christos struct cleanup *cleanup;
111 1.1.1.2 christos int ret;
112 1.1.1.2 christos
113 1.1.1.2 christos /* Determine appropriate breakpoint contents and size for this
114 1.1.1.2 christos address. */
115 1.1.1.2 christos bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
116 1.1.1.2 christos
117 1.1.1.2 christos if (bp == NULL || bp_tgt->placed_size != bplen)
118 1.1.1.2 christos return 0;
119 1.1.1.2 christos
120 1.1.1.2 christos /* Make sure we see the memory breakpoints. */
121 1.1.1.2 christos cleanup = make_show_memory_breakpoints_cleanup (1);
122 1.1.1.2 christos val = target_read_memory (addr, cur_contents, bplen);
123 1.1.1.2 christos
124 1.1.1.2 christos /* If our breakpoint is no longer at the address, this means that
125 1.1.1.2 christos the program modified the code on us, so it is wrong to put back
126 1.1.1.2 christos the old value. */
127 1.1.1.2 christos ret = (val == 0 && memcmp (bp, cur_contents, bplen) == 0);
128 1.1.1.2 christos
129 1.1.1.2 christos do_cleanups (cleanup);
130 1.1.1.2 christos return ret;
131 1.1.1.2 christos }
132