1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) ST-Ericsson SA 2011 *
6 * michel.jaouen@stericsson.com : smp minimum support *
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. *
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. *
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 ***************************************************************************/
28 #include <helper/log.h>
29 #include "breakpoints.h"
32 static char *breakpoint_type_strings
[] =
38 static char *watchpoint_rw_strings
[] =
45 // monotonic counter/id-number for breakpoints and watch points
46 static int bpwp_unique_id
;
48 int breakpoint_add_internal(struct target
*target
, uint32_t address
, uint32_t length
, enum breakpoint_type type
)
50 struct breakpoint
*breakpoint
= target
->breakpoints
;
51 struct breakpoint
**breakpoint_p
= &target
->breakpoints
;
60 if (breakpoint
->address
== address
) {
61 /* FIXME don't assume "same address" means "same
62 * breakpoint" ... check all the parameters before
65 LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32
" (BP %d)",
66 address
, breakpoint
->unique_id
);
69 breakpoint_p
= &breakpoint
->next
;
70 breakpoint
= breakpoint
->next
;
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
++;
82 retval
= target_add_breakpoint(target
, *breakpoint_p
);
86 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE
:
87 reason
= "resource not available";
89 case ERROR_TARGET_NOT_HALTED
:
90 reason
= "target running";
93 reason
= "unknown reason";
95 LOG_ERROR("can't add breakpoint: %s", reason
);
96 free((*breakpoint_p
)->orig_instr
);
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
);
110 int breakpoint_add(struct target
*target
, uint32_t address
, uint32_t length
, enum breakpoint_type type
)
113 int retval
= ERROR_OK
;
116 struct target_list
*head
;
119 while(head
!= (struct target_list
*)NULL
)
122 retval
= breakpoint_add_internal(curr
, address
,length
, type
);
123 if (retval
!= ERROR_OK
) return retval
;
129 return(breakpoint_add_internal(target
, address
, length
, type
));
133 /* free up a breakpoint */
134 static void breakpoint_free(struct target
*target
, struct breakpoint
*breakpoint_to_remove
)
136 struct breakpoint
*breakpoint
= target
->breakpoints
;
137 struct breakpoint
**breakpoint_p
= &target
->breakpoints
;
142 if (breakpoint
== breakpoint_to_remove
)
144 breakpoint_p
= &breakpoint
->next
;
145 breakpoint
= breakpoint
->next
;
148 if (breakpoint
== NULL
)
151 retval
= target_remove_breakpoint(target
, breakpoint
);
153 LOG_DEBUG("free BPID: %d --> %d", breakpoint
->unique_id
, retval
);
154 (*breakpoint_p
) = breakpoint
->next
;
155 free(breakpoint
->orig_instr
);
159 void breakpoint_remove_internal(struct target
*target
, uint32_t address
)
161 struct breakpoint
*breakpoint
= target
->breakpoints
;
162 struct breakpoint
**breakpoint_p
= &target
->breakpoints
;
166 if (breakpoint
->address
== address
)
168 breakpoint_p
= &breakpoint
->next
;
169 breakpoint
= breakpoint
->next
;
174 breakpoint_free(target
, breakpoint
);
178 LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32
" found", address
);
181 void breakpoint_remove(struct target
*target
, uint32_t address
)
185 struct target_list
*head
;
188 while(head
!= (struct target_list
*)NULL
)
191 breakpoint_remove_internal(curr
, address
);
195 else breakpoint_remove_internal(target
, address
);
198 void breakpoint_clear_target_internal(struct target
*target
)
200 struct breakpoint
*breakpoint
;
202 LOG_DEBUG("Delete all breakpoints for target: %s",
203 target_name(target
));
204 while ((breakpoint
= target
->breakpoints
) != NULL
)
206 breakpoint_free(target
, breakpoint
);
210 void breakpoint_clear_target(struct target
*target
)
214 struct target_list
*head
;
217 while(head
!= (struct target_list
*)NULL
)
220 breakpoint_clear_target_internal(curr
);
224 else breakpoint_clear_target_internal(target
);
229 struct breakpoint
* breakpoint_find(struct target
*target
, uint32_t address
)
231 struct breakpoint
*breakpoint
= target
->breakpoints
;
235 if (breakpoint
->address
== address
)
237 breakpoint
= breakpoint
->next
;
243 int watchpoint_add(struct target
*target
, uint32_t address
, uint32_t length
,
244 enum watchpoint_rw rw
, uint32_t value
, uint32_t mask
)
246 struct watchpoint
*watchpoint
= target
->watchpoints
;
247 struct watchpoint
**watchpoint_p
= &target
->watchpoints
;
253 if (watchpoint
->address
== address
) {
254 if (watchpoint
->length
!= length
255 || watchpoint
->value
!= value
256 || watchpoint
->mask
!= mask
257 || watchpoint
->rw
!= rw
) {
258 LOG_ERROR("address 0x%8.8" PRIx32
259 "already has watchpoint %d",
260 address
, watchpoint
->unique_id
);
264 /* ignore duplicate watchpoint */
267 watchpoint_p
= &watchpoint
->next
;
268 watchpoint
= watchpoint
->next
;
271 (*watchpoint_p
) = calloc(1, sizeof(struct watchpoint
));
272 (*watchpoint_p
)->address
= address
;
273 (*watchpoint_p
)->length
= length
;
274 (*watchpoint_p
)->value
= value
;
275 (*watchpoint_p
)->mask
= mask
;
276 (*watchpoint_p
)->rw
= rw
;
277 (*watchpoint_p
)->unique_id
= bpwp_unique_id
++;
279 retval
= target_add_watchpoint(target
, *watchpoint_p
);
283 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE
:
284 reason
= "resource not available";
286 case ERROR_TARGET_NOT_HALTED
:
287 reason
= "target running";
290 reason
= "unrecognized error";
292 LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32
", %s",
293 watchpoint_rw_strings
[(*watchpoint_p
)->rw
],
295 free (*watchpoint_p
);
296 *watchpoint_p
= NULL
;
300 LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32
301 " of length 0x%8.8" PRIx32
" (WPID: %d)",
302 watchpoint_rw_strings
[(*watchpoint_p
)->rw
],
303 (*watchpoint_p
)->address
,
304 (*watchpoint_p
)->length
,
305 (*watchpoint_p
)->unique_id
);
310 static void watchpoint_free(struct target
*target
, struct watchpoint
*watchpoint_to_remove
)
312 struct watchpoint
*watchpoint
= target
->watchpoints
;
313 struct watchpoint
**watchpoint_p
= &target
->watchpoints
;
318 if (watchpoint
== watchpoint_to_remove
)
320 watchpoint_p
= &watchpoint
->next
;
321 watchpoint
= watchpoint
->next
;
324 if (watchpoint
== NULL
)
326 retval
= target_remove_watchpoint(target
, watchpoint
);
327 LOG_DEBUG("free WPID: %d --> %d", watchpoint
->unique_id
, retval
);
328 (*watchpoint_p
) = watchpoint
->next
;
332 void watchpoint_remove(struct target
*target
, uint32_t address
)
334 struct watchpoint
*watchpoint
= target
->watchpoints
;
335 struct watchpoint
**watchpoint_p
= &target
->watchpoints
;
339 if (watchpoint
->address
== address
)
341 watchpoint_p
= &watchpoint
->next
;
342 watchpoint
= watchpoint
->next
;
347 watchpoint_free(target
, watchpoint
);
351 LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32
" found", address
);
355 void watchpoint_clear_target(struct target
*target
)
357 struct watchpoint
*watchpoint
;
359 LOG_DEBUG("Delete all watchpoints for target: %s",
360 target_name(target
));
361 while ((watchpoint
= target
->watchpoints
) != NULL
)
363 watchpoint_free(target
, watchpoint
);
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)