- remove target specific variant and use target->variant member
[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(length);
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 LOG_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 LOG_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 break;
88 }
89 }
90
91 LOG_DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x",
92 breakpoint_type_strings[(*breakpoint_p)->type],
93 (*breakpoint_p)->address, (*breakpoint_p)->length);
94
95 return ERROR_OK;
96 }
97
98 /* free up a breakpoint */
99 static void breakpoint_free(target_t *target, breakpoint_t *breakpoint_remove)
100 {
101 breakpoint_t *breakpoint = target->breakpoints;
102 breakpoint_t **breakpoint_p = &target->breakpoints;
103
104 while (breakpoint)
105 {
106 if (breakpoint==breakpoint_remove)
107 break;
108 breakpoint_p = &breakpoint->next;
109 breakpoint = breakpoint->next;
110 }
111
112 if (breakpoint==NULL)
113 return;
114
115 target->type->remove_breakpoint(target, breakpoint);
116
117 (*breakpoint_p) = breakpoint->next;
118 free(breakpoint->orig_instr);
119 free(breakpoint);
120 }
121
122 void breakpoint_remove(target_t *target, u32 address)
123 {
124 breakpoint_t *breakpoint = target->breakpoints;
125 breakpoint_t **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.8x found", address);
142 }
143 }
144
145 void breakpoint_clear_target(target_t *target)
146 {
147 breakpoint_t *breakpoint;
148 while ((breakpoint = target->breakpoints)!=NULL)
149 {
150 breakpoint_free(target, breakpoint);
151 }
152 }
153
154 breakpoint_t* breakpoint_find(target_t *target, u32 address)
155 {
156 breakpoint_t *breakpoint = target->breakpoints;
157
158 while (breakpoint)
159 {
160 if (breakpoint->address == address)
161 return breakpoint;
162 breakpoint = breakpoint->next;
163 }
164
165 return NULL;
166 }
167
168 int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw rw, u32 value, u32 mask)
169 {
170 watchpoint_t *watchpoint = target->watchpoints;
171 watchpoint_t **watchpoint_p = &target->watchpoints;
172 int retval;
173
174 while (watchpoint)
175 {
176 if (watchpoint->address == address)
177 return ERROR_OK;
178 watchpoint_p = &watchpoint->next;
179 watchpoint = watchpoint->next;
180 }
181
182 (*watchpoint_p) = malloc(sizeof(watchpoint_t));
183 (*watchpoint_p)->address = address;
184 (*watchpoint_p)->length = length;
185 (*watchpoint_p)->value = value;
186 (*watchpoint_p)->mask = mask;
187 (*watchpoint_p)->rw = rw;
188 (*watchpoint_p)->set = 0;
189 (*watchpoint_p)->next = NULL;
190
191 if ((retval = target->type->add_watchpoint(target, *watchpoint_p)) != ERROR_OK)
192 {
193 switch (retval)
194 {
195 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
196 LOG_INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[(*watchpoint_p)->rw]);
197 free (*watchpoint_p);
198 *watchpoint_p = NULL;
199 return retval;
200 break;
201 case ERROR_TARGET_NOT_HALTED:
202 LOG_INFO("can't add watchpoint while target is running");
203 free (*watchpoint_p);
204 *watchpoint_p = NULL;
205 return retval;
206 break;
207 default:
208 LOG_ERROR("unknown error");
209 exit(-1);
210 break;
211 }
212 }
213
214 LOG_DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x",
215 watchpoint_rw_strings[(*watchpoint_p)->rw],
216 (*watchpoint_p)->address, (*watchpoint_p)->length);
217
218 return ERROR_OK;
219 }
220
221 static void watchpoint_free(target_t *target, watchpoint_t *watchpoint_remove)
222 {
223 watchpoint_t *watchpoint = target->watchpoints;
224 watchpoint_t **watchpoint_p = &target->watchpoints;
225
226 while (watchpoint)
227 {
228 if (watchpoint == watchpoint_remove)
229 break;
230 watchpoint_p = &watchpoint->next;
231 watchpoint = watchpoint->next;
232 }
233
234 if (watchpoint==NULL)
235 return;
236 target->type->remove_watchpoint(target, watchpoint);
237 (*watchpoint_p) = watchpoint->next;
238 free(watchpoint);
239 }
240
241 void watchpoint_remove(target_t *target, u32 address)
242 {
243 watchpoint_t *watchpoint = target->watchpoints;
244 watchpoint_t **watchpoint_p = &target->watchpoints;
245
246 while (watchpoint)
247 {
248 if (watchpoint->address == address)
249 break;
250 watchpoint_p = &watchpoint->next;
251 watchpoint = watchpoint->next;
252 }
253
254 if (watchpoint)
255 {
256 watchpoint_free(target, watchpoint);
257 }
258 else
259 {
260 LOG_ERROR("no watchpoint at address 0x%8.8x found", address);
261 }
262 }
263
264 void watchpoint_clear_target(target_t *target)
265 {
266 watchpoint_t *watchpoint;
267 while ((watchpoint = target->watchpoints)!=NULL)
268 {
269 watchpoint_free(target, watchpoint);
270 }
271 }

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)