- Added support for native MinGW builds (thanks to Spencer Oliver and Michael Fischer...
[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 if ((retval = target->type->add_breakpoint(target, address, length, type)) != ERROR_OK)
61 {
62 switch (retval)
63 {
64 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
65 INFO("can't add %s breakpoint, resource not available", breakpoint_type_strings[type]);
66 return retval;
67 break;
68 case ERROR_TARGET_NOT_HALTED:
69 INFO("can't add breakpoint while target is running");
70 return retval;
71 break;
72 default:
73 ERROR("unknown error");
74 exit(-1);
75 break;
76 }
77 }
78
79 (*breakpoint_p) = malloc(sizeof(breakpoint_t));
80 (*breakpoint_p)->address = address;
81 (*breakpoint_p)->length = length;
82 (*breakpoint_p)->type = type;
83 (*breakpoint_p)->set = 0;
84 (*breakpoint_p)->orig_instr = malloc(CEIL(length, 8));
85 (*breakpoint_p)->next = NULL;
86
87 DEBUG("added %s breakpoint at 0x%8.8x of length 0x%8.8x", breakpoint_type_strings[type], address, length);
88
89 return ERROR_OK;
90 }
91
92 int breakpoint_remove(target_t *target, u32 address)
93 {
94 breakpoint_t *breakpoint = target->breakpoints;
95 breakpoint_t **breakpoint_p = &target->breakpoints;
96 int retval;
97
98 while (breakpoint)
99 {
100 if (breakpoint->address == address)
101 break;
102 breakpoint_p = &breakpoint->next;
103 breakpoint = breakpoint->next;
104 }
105
106 if (breakpoint)
107 {
108 if ((retval = target->type->remove_breakpoint(target, breakpoint)) != ERROR_OK)
109 {
110 switch (retval)
111 {
112 case ERROR_TARGET_NOT_HALTED:
113 INFO("can't remove breakpoint while target is running");
114 return retval;
115 break;
116 default:
117 ERROR("unknown error");
118 exit(-1);
119 break;
120 }
121 }
122 (*breakpoint_p) = breakpoint->next;
123 free(breakpoint->orig_instr);
124 free(breakpoint);
125 }
126 else
127 {
128 ERROR("no breakpoint at address 0x%8.8x found", address);
129 }
130
131 return ERROR_OK;
132 }
133
134 breakpoint_t* breakpoint_find(target_t *target, u32 address)
135 {
136 breakpoint_t *breakpoint = target->breakpoints;
137
138 while (breakpoint)
139 {
140 if (breakpoint->address == address)
141 return breakpoint;
142 breakpoint = breakpoint->next;
143 }
144
145 return NULL;
146 }
147
148 int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw rw, u32 value, u32 mask)
149 {
150 watchpoint_t *watchpoint = target->watchpoints;
151 watchpoint_t **watchpoint_p = &target->watchpoints;
152 int retval;
153
154 while (watchpoint)
155 {
156 if (watchpoint->address == address)
157 return ERROR_OK;
158 watchpoint_p = &watchpoint->next;
159 watchpoint = watchpoint->next;
160 }
161
162 if ((retval = target->type->add_watchpoint(target, address, length, rw)) != ERROR_OK)
163 {
164 switch (retval)
165 {
166 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
167 INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[rw]);
168 return retval;
169 break;
170 default:
171 ERROR("unknown error");
172 exit(-1);
173 break;
174 }
175 }
176
177 (*watchpoint_p) = malloc(sizeof(watchpoint_t));
178 (*watchpoint_p)->address = address;
179 (*watchpoint_p)->length = length;
180 (*watchpoint_p)->value = value;
181 (*watchpoint_p)->mask = mask;
182 (*watchpoint_p)->rw = rw;
183 (*watchpoint_p)->set = 0;
184 (*watchpoint_p)->next = NULL;
185
186 DEBUG("added %s watchpoint at 0x%8.8x of length 0x%8.8x", watchpoint_rw_strings[rw], address, length);
187
188 return ERROR_OK;
189 }
190
191 int watchpoint_remove(target_t *target, u32 address)
192 {
193 watchpoint_t *watchpoint = target->watchpoints;
194 watchpoint_t **watchpoint_p = &target->watchpoints;
195 int retval;
196
197 while (watchpoint)
198 {
199 if (watchpoint->address == address)
200 break;
201 watchpoint_p = &watchpoint->next;
202 watchpoint = watchpoint->next;
203 }
204
205 if (watchpoint)
206 {
207 if ((retval = target->type->remove_watchpoint(target, watchpoint)) != ERROR_OK)
208 {
209 ERROR("BUG: can't remove watchpoint");
210 exit(-1);
211 }
212 (*watchpoint_p) = watchpoint->next;
213 free(watchpoint);
214 }
215 else
216 {
217 ERROR("no watchpoint at address 0x%8.8x found", address);
218 }
219
220 return ERROR_OK;
221 }

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)