- trying to remove a breakpoint with target running should not exit(-1) from OpenOCD
[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 <stdlib.h>
25
26 #include "binarybuffer.h"
27 #include "target.h"
28 #include "log.h"
29 #include "types.h"
30
31 #include "breakpoints.h"
32
33 char *breakpoint_type_strings[] =
34 {
35 "hardware",
36 "software"
37 };
38
39 char *watchpoint_rw_strings[] =
40 {
41 "read",
42 "write",
43 "access"
44 };
45
46 int breakpoint_add(target_t *target, u32 address, u32 length, enum breakpoint_type type)
47 {
48 breakpoint_t *breakpoint = target->breakpoints;
49 breakpoint_t **breakpoint_p = &target->breakpoints;
50 int retval;
51
52 while (breakpoint)
53 {
54 if (breakpoint->address == address)
55 return ERROR_OK;
56 breakpoint_p = &breakpoint->next;
57 breakpoint = breakpoint->next;
58 }
59
60 (*breakpoint_p) = malloc(sizeof(breakpoint_t));
61 (*breakpoint_p)->address = address;
62 (*breakpoint_p)->length = length;
63 (*breakpoint_p)->type = type;
64 (*breakpoint_p)->set = 0;
65 (*breakpoint_p)->orig_instr = malloc(CEIL(length, 8));
66 (*breakpoint_p)->next = NULL;
67
68 if ((retval = target->type->add_breakpoint(target, *breakpoint_p)) != ERROR_OK)
69 {
70 switch (retval)
71 {
72 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
73 INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[(*breakpoint_p)->type]);
74 free((*breakpoint_p)->orig_instr);
75 free(*breakpoint_p);
76 *breakpoint_p = NULL;
77 return retval;
78 break;
79 case ERROR_TARGET_NOT_HALTED:
80 INFO("can't add breakpoint while target is running");
81 free((*breakpoint_p)->orig_instr);
82 free(*breakpoint_p);
83 *breakpoint_p = NULL;
84 return retval;
85 break;
86 default:
87 ERROR("unknown error");
88 exit(-1);
89 break;
90 }
91 }
92
93 DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x",
94 breakpoint_type_strings[(*breakpoint_p)->type],
95 (*breakpoint_p)->address, (*breakpoint_p)->length);
96
97 return ERROR_OK;
98 }
99
100 int breakpoint_remove(target_t *target, u32 address)
101 {
102 breakpoint_t *breakpoint = target->breakpoints;
103 breakpoint_t **breakpoint_p = &target->breakpoints;
104 int retval;
105
106 while (breakpoint)
107 {
108 if (breakpoint->address == address)
109 break;
110 breakpoint_p = &breakpoint->next;
111 breakpoint = breakpoint->next;
112 }
113
114 if (breakpoint)
115 {
116 if ((retval = target->type->remove_breakpoint(target, breakpoint)) != ERROR_OK)
117 {
118 switch (retval)
119 {
120 case ERROR_TARGET_NOT_HALTED:
121 INFO("can't remove breakpoint while target is running");
122 return retval;
123 break;
124 default:
125 ERROR("unknown error");
126 exit(-1);
127 break;
128 }
129 }
130 (*breakpoint_p) = breakpoint->next;
131 free(breakpoint->orig_instr);
132 free(breakpoint);
133 }
134 else
135 {
136 ERROR("no breakpoint at address 0x%8.8x found", address);
137 }
138
139 return ERROR_OK;
140 }
141
142 breakpoint_t* breakpoint_find(target_t *target, u32 address)
143 {
144 breakpoint_t *breakpoint = target->breakpoints;
145
146 while (breakpoint)
147 {
148 if (breakpoint->address == address)
149 return breakpoint;
150 breakpoint = breakpoint->next;
151 }
152
153 return NULL;
154 }
155
156 int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw rw, u32 value, u32 mask)
157 {
158 watchpoint_t *watchpoint = target->watchpoints;
159 watchpoint_t **watchpoint_p = &target->watchpoints;
160 int retval;
161
162 while (watchpoint)
163 {
164 if (watchpoint->address == address)
165 return ERROR_OK;
166 watchpoint_p = &watchpoint->next;
167 watchpoint = watchpoint->next;
168 }
169
170 (*watchpoint_p) = malloc(sizeof(watchpoint_t));
171 (*watchpoint_p)->address = address;
172 (*watchpoint_p)->length = length;
173 (*watchpoint_p)->value = value;
174 (*watchpoint_p)->mask = mask;
175 (*watchpoint_p)->rw = rw;
176 (*watchpoint_p)->set = 0;
177 (*watchpoint_p)->next = NULL;
178
179 if ((retval = target->type->add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
180 {
181 switch (retval)
182 {
183 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
184 INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[(*watchpoint_p)->rw]);
185 free (*watchpoint_p);
186 *watchpoint_p = NULL;
187 return retval;
188 break;
189 case ERROR_TARGET_NOT_HALTED:
190 INFO("can't add watchpoint while target is running");
191 free (*watchpoint_p);
192 *watchpoint_p = NULL;
193 return retval;
194 break;
195 default:
196 ERROR("unknown error");
197 exit(-1);
198 break;
199 }
200 }
201
202 DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x",
203 watchpoint_rw_strings[(*watchpoint_p)->rw],
204 (*watchpoint_p)->address, (*watchpoint_p)->length);
205
206 return ERROR_OK;
207 }
208
209 int watchpoint_remove(target_t *target, u32 address)
210 {
211 watchpoint_t *watchpoint = target->watchpoints;
212 watchpoint_t **watchpoint_p = &target->watchpoints;
213 int retval;
214
215 while (watchpoint)
216 {
217 if (watchpoint->address == address)
218 break;
219 watchpoint_p = &watchpoint->next;
220 watchpoint = watchpoint->next;
221 }
222
223 if (watchpoint)
224 {
225 if ((retval = target->type->remove_watchpoint(target, watchpoint)) != ERROR_OK)
226 {
227 switch (retval)
228 {
229 case ERROR_TARGET_NOT_HALTED:
230 INFO("can't remove watchpoint while target is running");
231 return retval;
232 break;
233 default:
234 ERROR("unknown error");
235 exit(-1);
236 break;
237 }
238 }
239 (*watchpoint_p) = watchpoint->next;
240 free(watchpoint);
241 }
242 else
243 {
244 ERROR("no watchpoint at address 0x%8.8x found", address);
245 }
246
247 return ERROR_OK;
248 }

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)