Fix "unused variable" warnings (errors) detected with GCC 4.7.0 - trivial fixes
[openocd.git] / src / target / breakpoints.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) ST-Ericsson SA 2011 *
6 * michel.jaouen@stericsson.com : smp minimum support *
7 * *
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. *
12 * *
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. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "target.h"
28 #include <helper/log.h>
29 #include "breakpoints.h"
30
31
32 static char *breakpoint_type_strings[] =
33 {
34 "hardware",
35 "software"
36 };
37
38 static char *watchpoint_rw_strings[] =
39 {
40 "read",
41 "write",
42 "access"
43 };
44
45 // monotonic counter/id-number for breakpoints and watch points
46 static int bpwp_unique_id;
47
48 int breakpoint_add_internal(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type)
49 {
50 struct breakpoint *breakpoint = target->breakpoints;
51 struct breakpoint **breakpoint_p = &target->breakpoints;
52 char *reason;
53 int retval;
54 int n;
55
56 n = 0;
57 while (breakpoint)
58 {
59 n++;
60 if (breakpoint->address == address) {
61 /* FIXME don't assume "same address" means "same
62 * breakpoint" ... check all the parameters before
63 * succeeding.
64 */
65 LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %d)",
66 address, breakpoint->unique_id );
67 return ERROR_OK;
68 }
69 breakpoint_p = &breakpoint->next;
70 breakpoint = breakpoint->next;
71 }
72
73 (*breakpoint_p) = malloc(sizeof(struct breakpoint));
74 (*breakpoint_p)->address = address;
75 (*breakpoint_p)->length = length;
76 (*breakpoint_p)->type = type;
77 (*breakpoint_p)->set = 0;
78 (*breakpoint_p)->orig_instr = malloc(length);
79 (*breakpoint_p)->next = NULL;
80 (*breakpoint_p)->unique_id = bpwp_unique_id++;
81
82 retval = target_add_breakpoint(target, *breakpoint_p);
83 switch (retval) {
84 case ERROR_OK:
85 break;
86 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
87 reason = "resource not available";
88 goto fail;
89 case ERROR_TARGET_NOT_HALTED:
90 reason = "target running";
91 goto fail;
92 default:
93 reason = "unknown reason";
94 fail:
95 LOG_ERROR("can't add breakpoint: %s", reason);
96 free((*breakpoint_p)->orig_instr);
97 free(*breakpoint_p);
98 *breakpoint_p = NULL;
99 return retval;
100 }
101
102 LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)",
103 breakpoint_type_strings[(*breakpoint_p)->type],
104 (*breakpoint_p)->address, (*breakpoint_p)->length,
105 (*breakpoint_p)->unique_id );
106
107 return ERROR_OK;
108 }
109
110 int breakpoint_add(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type)
111 {
112
113 int retval = ERROR_OK;
114 if (target->smp)
115 {
116 struct target_list *head;
117 struct target *curr;
118 head = target->head;
119 while(head != (struct target_list*)NULL)
120 {
121 curr = head->target;
122 retval = breakpoint_add_internal(curr, address,length, type);
123 if (retval != ERROR_OK) return retval;
124 head = head->next;
125 }
126 return retval;
127 }
128 else
129 return(breakpoint_add_internal(target, address, length, type));
130
131 }
132
133 /* free up a breakpoint */
134 static void breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)
135 {
136 struct breakpoint *breakpoint = target->breakpoints;
137 struct breakpoint **breakpoint_p = &target->breakpoints;
138 int retval;
139
140 while (breakpoint)
141 {
142 if (breakpoint == breakpoint_to_remove)
143 break;
144 breakpoint_p = &breakpoint->next;
145 breakpoint = breakpoint->next;
146 }
147
148 if (breakpoint == NULL)
149 return;
150
151 retval = target_remove_breakpoint(target, breakpoint);
152
153 LOG_DEBUG("free BPID: %d --> %d", breakpoint->unique_id, retval);
154 (*breakpoint_p) = breakpoint->next;
155 free(breakpoint->orig_instr);
156 free(breakpoint);
157 }
158
159 void breakpoint_remove_internal(struct target *target, uint32_t address)
160 {
161 struct breakpoint *breakpoint = target->breakpoints;
162
163 while (breakpoint)
164 {
165 if (breakpoint->address == address)
166 break;
167 breakpoint = breakpoint->next;
168 }
169
170 if (breakpoint)
171 {
172 breakpoint_free(target, breakpoint);
173 }
174 else
175 {
176 LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
177 }
178 }
179 void breakpoint_remove(struct target *target, uint32_t address)
180 {
181 if ((target->smp))
182 {
183 struct target_list *head;
184 struct target *curr;
185 head = target->head;
186 while(head != (struct target_list*)NULL)
187 {
188 curr = head->target;
189 breakpoint_remove_internal(curr, address);
190 head = head->next;
191 }
192 }
193 else breakpoint_remove_internal(target, address);
194 }
195
196 void breakpoint_clear_target_internal(struct target *target)
197 {
198 struct breakpoint *breakpoint;
199
200 LOG_DEBUG("Delete all breakpoints for target: %s",
201 target_name(target));
202 while ((breakpoint = target->breakpoints) != NULL)
203 {
204 breakpoint_free(target, breakpoint);
205 }
206 }
207
208 void breakpoint_clear_target(struct target *target)
209 {
210 if (target->smp)
211 {
212 struct target_list *head;
213 struct target *curr;
214 head = target->head;
215 while(head != (struct target_list*)NULL)
216 {
217 curr = head->target;
218 breakpoint_clear_target_internal(curr);
219 head = head->next;
220 }
221 }
222 else breakpoint_clear_target_internal(target);
223
224 }
225
226
227 struct breakpoint* breakpoint_find(struct target *target, uint32_t address)
228 {
229 struct breakpoint *breakpoint = target->breakpoints;
230
231 while (breakpoint)
232 {
233 if (breakpoint->address == address)
234 return breakpoint;
235 breakpoint = breakpoint->next;
236 }
237
238 return NULL;
239 }
240
241 int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
242 enum watchpoint_rw rw, uint32_t value, uint32_t mask)
243 {
244 struct watchpoint *watchpoint = target->watchpoints;
245 struct watchpoint **watchpoint_p = &target->watchpoints;
246 int retval;
247 char *reason;
248
249 while (watchpoint)
250 {
251 if (watchpoint->address == address) {
252 if (watchpoint->length != length
253 || watchpoint->value != value
254 || watchpoint->mask != mask
255 || watchpoint->rw != rw) {
256 LOG_ERROR("address 0x%8.8" PRIx32
257 "already has watchpoint %d",
258 address, watchpoint->unique_id);
259 return ERROR_FAIL;
260 }
261
262 /* ignore duplicate watchpoint */
263 return ERROR_OK;
264 }
265 watchpoint_p = &watchpoint->next;
266 watchpoint = watchpoint->next;
267 }
268
269 (*watchpoint_p) = calloc(1, sizeof(struct watchpoint));
270 (*watchpoint_p)->address = address;
271 (*watchpoint_p)->length = length;
272 (*watchpoint_p)->value = value;
273 (*watchpoint_p)->mask = mask;
274 (*watchpoint_p)->rw = rw;
275 (*watchpoint_p)->unique_id = bpwp_unique_id++;
276
277 retval = target_add_watchpoint(target, *watchpoint_p);
278 switch (retval) {
279 case ERROR_OK:
280 break;
281 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
282 reason = "resource not available";
283 goto bye;
284 case ERROR_TARGET_NOT_HALTED:
285 reason = "target running";
286 goto bye;
287 default:
288 reason = "unrecognized error";
289 bye:
290 LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32 ", %s",
291 watchpoint_rw_strings[(*watchpoint_p)->rw],
292 address, reason);
293 free (*watchpoint_p);
294 *watchpoint_p = NULL;
295 return retval;
296 }
297
298 LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32
299 " of length 0x%8.8" PRIx32 " (WPID: %d)",
300 watchpoint_rw_strings[(*watchpoint_p)->rw],
301 (*watchpoint_p)->address,
302 (*watchpoint_p)->length,
303 (*watchpoint_p)->unique_id );
304
305 return ERROR_OK;
306 }
307
308 static void watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
309 {
310 struct watchpoint *watchpoint = target->watchpoints;
311 struct watchpoint **watchpoint_p = &target->watchpoints;
312 int retval;
313
314 while (watchpoint)
315 {
316 if (watchpoint == watchpoint_to_remove)
317 break;
318 watchpoint_p = &watchpoint->next;
319 watchpoint = watchpoint->next;
320 }
321
322 if (watchpoint == NULL)
323 return;
324 retval = target_remove_watchpoint(target, watchpoint);
325 LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
326 (*watchpoint_p) = watchpoint->next;
327 free(watchpoint);
328 }
329
330 void watchpoint_remove(struct target *target, uint32_t address)
331 {
332 struct watchpoint *watchpoint = target->watchpoints;
333
334 while (watchpoint)
335 {
336 if (watchpoint->address == address)
337 break;
338 watchpoint = watchpoint->next;
339 }
340
341 if (watchpoint)
342 {
343 watchpoint_free(target, watchpoint);
344 }
345 else
346 {
347 LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address);
348 }
349 }
350
351 void watchpoint_clear_target(struct target *target)
352 {
353 struct watchpoint *watchpoint;
354
355 LOG_DEBUG("Delete all watchpoints for target: %s",
356 target_name(target));
357 while ((watchpoint = target->watchpoints) != NULL)
358 {
359 watchpoint_free(target, watchpoint);
360 }
361 }

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)