jim tests: use installed
[openocd.git] / src / target / breakpoints.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "target.h"
25 #include <helper/log.h>
26 #include "breakpoints.h"
27
28
29 static char *breakpoint_type_strings[] =
30 {
31 "hardware",
32 "software"
33 };
34
35 static char *watchpoint_rw_strings[] =
36 {
37 "read",
38 "write",
39 "access"
40 };
41
42 // monotonic counter/id-number for breakpoints and watch points
43 static int bpwp_unique_id;
44
45 int breakpoint_add(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type)
46 {
47 struct breakpoint *breakpoint = target->breakpoints;
48 struct breakpoint **breakpoint_p = &target->breakpoints;
49 int retval;
50 int n;
51
52 n = 0;
53 while (breakpoint)
54 {
55 n++;
56 if (breakpoint->address == address) {
57 /* FIXME don't assume "same address" means "same
58 * breakpoint" ... check all the parameters before
59 * succeeding.
60 */
61 LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %d)",
62 address, breakpoint->unique_id );
63 return ERROR_OK;
64 }
65 breakpoint_p = &breakpoint->next;
66 breakpoint = breakpoint->next;
67 }
68
69 (*breakpoint_p) = malloc(sizeof(struct breakpoint));
70 (*breakpoint_p)->address = address;
71 (*breakpoint_p)->length = length;
72 (*breakpoint_p)->type = type;
73 (*breakpoint_p)->set = 0;
74 (*breakpoint_p)->orig_instr = malloc(length);
75 (*breakpoint_p)->next = NULL;
76 (*breakpoint_p)->unique_id = bpwp_unique_id++;
77
78 retval = target_add_breakpoint(target, *breakpoint_p);
79 if (retval != ERROR_OK)
80 {
81 LOG_ERROR("could not add breakpoint");
82 free((*breakpoint_p)->orig_instr);
83 free(*breakpoint_p);
84 *breakpoint_p = NULL;
85 return retval;
86 }
87
88 LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)",
89 breakpoint_type_strings[(*breakpoint_p)->type],
90 (*breakpoint_p)->address, (*breakpoint_p)->length,
91 (*breakpoint_p)->unique_id );
92
93 return ERROR_OK;
94 }
95
96 /* free up a breakpoint */
97 static void breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)
98 {
99 struct breakpoint *breakpoint = target->breakpoints;
100 struct breakpoint **breakpoint_p = &target->breakpoints;
101 int retval;
102
103 while (breakpoint)
104 {
105 if (breakpoint == breakpoint_to_remove)
106 break;
107 breakpoint_p = &breakpoint->next;
108 breakpoint = breakpoint->next;
109 }
110
111 if (breakpoint == NULL)
112 return;
113
114 retval = target_remove_breakpoint(target, breakpoint);
115
116 LOG_DEBUG("free BPID: %d --> %d", breakpoint->unique_id, retval);
117 (*breakpoint_p) = breakpoint->next;
118 free(breakpoint->orig_instr);
119 free(breakpoint);
120 }
121
122 void breakpoint_remove(struct target *target, uint32_t address)
123 {
124 struct breakpoint *breakpoint = target->breakpoints;
125 struct breakpoint **breakpoint_p = &target->breakpoints;
126
127 while (breakpoint)
128 {
129 if (breakpoint->address == address)
130 break;
131 breakpoint_p = &breakpoint->next;
132 breakpoint = breakpoint->next;
133 }
134
135 if (breakpoint)
136 {
137 breakpoint_free(target, breakpoint);
138 }
139 else
140 {
141 LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
142 }
143 }
144
145 void breakpoint_clear_target(struct target *target)
146 {
147 struct breakpoint *breakpoint;
148
149 LOG_DEBUG("Delete all breakpoints for target: %s",
150 target_name(target));
151 while ((breakpoint = target->breakpoints) != NULL)
152 {
153 breakpoint_free(target, breakpoint);
154 }
155 }
156
157 struct breakpoint* breakpoint_find(struct target *target, uint32_t address)
158 {
159 struct breakpoint *breakpoint = target->breakpoints;
160
161 while (breakpoint)
162 {
163 if (breakpoint->address == address)
164 return breakpoint;
165 breakpoint = breakpoint->next;
166 }
167
168 return NULL;
169 }
170
171 int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
172 enum watchpoint_rw rw, uint32_t value, uint32_t mask)
173 {
174 struct watchpoint *watchpoint = target->watchpoints;
175 struct watchpoint **watchpoint_p = &target->watchpoints;
176 int retval;
177
178 while (watchpoint)
179 {
180 if (watchpoint->address == address) {
181 if (watchpoint->length != length
182 || watchpoint->value != value
183 || watchpoint->mask != mask
184 || watchpoint->rw != rw) {
185 LOG_ERROR("address 0x%8.8" PRIx32
186 "already has watchpoint %d",
187 address, watchpoint->unique_id);
188 return ERROR_FAIL;
189 }
190
191 /* ignore duplicate watchpoint */
192 return ERROR_OK;
193 }
194 watchpoint_p = &watchpoint->next;
195 watchpoint = watchpoint->next;
196 }
197
198 (*watchpoint_p) = calloc(1, sizeof(struct watchpoint));
199 (*watchpoint_p)->address = address;
200 (*watchpoint_p)->length = length;
201 (*watchpoint_p)->value = value;
202 (*watchpoint_p)->mask = mask;
203 (*watchpoint_p)->rw = rw;
204 (*watchpoint_p)->unique_id = bpwp_unique_id++;
205
206 retval = target_add_watchpoint(target, *watchpoint_p);
207 if (retval != ERROR_OK)
208 {
209 LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32,
210 watchpoint_rw_strings[(*watchpoint_p)->rw],
211 address);
212 free (*watchpoint_p);
213 *watchpoint_p = NULL;
214 return retval;
215 }
216
217 LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32
218 " of length 0x%8.8" PRIx32 " (WPID: %d)",
219 watchpoint_rw_strings[(*watchpoint_p)->rw],
220 (*watchpoint_p)->address,
221 (*watchpoint_p)->length,
222 (*watchpoint_p)->unique_id );
223
224 return ERROR_OK;
225 }
226
227 static void watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
228 {
229 struct watchpoint *watchpoint = target->watchpoints;
230 struct watchpoint **watchpoint_p = &target->watchpoints;
231 int retval;
232
233 while (watchpoint)
234 {
235 if (watchpoint == watchpoint_to_remove)
236 break;
237 watchpoint_p = &watchpoint->next;
238 watchpoint = watchpoint->next;
239 }
240
241 if (watchpoint == NULL)
242 return;
243 retval = target_remove_watchpoint(target, watchpoint);
244 LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
245 (*watchpoint_p) = watchpoint->next;
246 free(watchpoint);
247 }
248
249 void watchpoint_remove(struct target *target, uint32_t address)
250 {
251 struct watchpoint *watchpoint = target->watchpoints;
252 struct watchpoint **watchpoint_p = &target->watchpoints;
253
254 while (watchpoint)
255 {
256 if (watchpoint->address == address)
257 break;
258 watchpoint_p = &watchpoint->next;
259 watchpoint = watchpoint->next;
260 }
261
262 if (watchpoint)
263 {
264 watchpoint_free(target, watchpoint);
265 }
266 else
267 {
268 LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address);
269 }
270 }
271
272 void watchpoint_clear_target(struct target *target)
273 {
274 struct watchpoint *watchpoint;
275
276 LOG_DEBUG("Delete all watchpoints for target: %s",
277 target_name(target));
278 while ((watchpoint = target->watchpoints) != NULL)
279 {
280 watchpoint_free(target, watchpoint);
281 }
282 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)