comparison gdb_remote.c @ 2397:39a009aea113

Implement watchpoints in gdb remote protocol
author Michael Pavone <pavone@retrodev.com>
date Sat, 23 Dec 2023 21:54:33 -0800
parents 3350b3c8faa8
children 8445e814d495
comparison
equal deleted inserted replaced
2396:bf4f1a8d1d48 2397:39a009aea113
219 goto not_impl; 219 goto not_impl;
220 } 220 }
221 break; 221 break;
222 case 'Z': { 222 case 'Z': {
223 uint8_t type = command[1]; 223 uint8_t type = command[1];
224 char *after_address;
225 uint32_t address = strtoul(command+3, &after_address, 16);
226 uint32_t kind = strtoul(after_address +1, NULL, 16);
224 if (type < '2') { 227 if (type < '2') {
225 uint32_t address = strtoul(command+3, NULL, 16);
226 insert_breakpoint(context, address, gdb_debug_enter); 228 insert_breakpoint(context, address, gdb_debug_enter);
227 bp_def *new_bp = malloc(sizeof(bp_def)); 229 bp_def *new_bp = malloc(sizeof(bp_def));
228 new_bp->next = root->breakpoints; 230 new_bp->next = root->breakpoints;
229 new_bp->address = address; 231 new_bp->address = address;
230 new_bp->mask = 0xFFFFFF; 232 new_bp->mask = 0xFFFFFF;
231 new_bp->type = BP_TYPE_CPU; 233 new_bp->type = BP_TYPE_CPU;
232 new_bp->index = root->bp_index++; 234 new_bp->index = root->bp_index++;
233 root->breakpoints = new_bp; 235 root->breakpoints = new_bp;
234 gdb_send_command("OK"); 236 gdb_send_command("OK");
235 } else { 237 } else if (type == '2') {
236 //watchpoints are not currently supported 238 m68k_add_watchpoint(context, address, kind);
239 bp_def *new_bp = malloc(sizeof(bp_def));
240 new_bp->next = root->breakpoints;
241 new_bp->address = address;
242 new_bp->mask = kind;
243 new_bp->type = BP_TYPE_CPU_WATCH;
244 new_bp->index = root->bp_index++;
245 root->breakpoints = new_bp;
246 gdb_send_command("OK");
247 } else {
248 //read and access watchpoints are not currently supported
237 gdb_send_command(""); 249 gdb_send_command("");
238 } 250 }
239 break; 251 break;
240 } 252 }
241 case 'z': { 253 case 'z': {
242 uint8_t type = command[1]; 254 uint8_t type = command[1];
255 char *after_address;
256 uint32_t address = strtoul(command+3, &after_address, 16);
257 uint32_t kind = strtoul(after_address +1, NULL, 16);
243 if (type < '2') { 258 if (type < '2') {
244 uint32_t address = strtoul(command+3, NULL, 16);
245 remove_breakpoint(context, address); 259 remove_breakpoint(context, address);
246 bp_def **found = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU); 260 bp_def **found = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU);
247 if (*found) 261 if (*found)
248 { 262 {
249 bp_def * to_remove = *found; 263 bp_def * to_remove = *found;
250 *found = to_remove->next; 264 *found = to_remove->next;
251 free(to_remove); 265 free(to_remove);
252 } 266 }
253 gdb_send_command("OK"); 267 gdb_send_command("OK");
254 } else { 268 } else if (type == '2') {
255 //watchpoints are not currently supported 269 m68k_remove_watchpoint(context, address, kind);
270 bp_def **cur = &root->breakpoints;
271 while (*cur)
272 {
273 if ((*cur)->type == BP_TYPE_CPU_WATCH && (*cur)->address == address && (*cur)->mask == kind) {
274 break;
275 }
276 cur = &(*cur)->next;
277 }
278 if (*cur) {
279 bp_def *to_remove = *cur;
280 *cur = to_remove->next;
281 free(to_remove);
282 }
283 gdb_send_command("OK");
284 } else {
285 //read and access watchpoints are not currently supported
256 gdb_send_command(""); 286 gdb_send_command("");
257 } 287 }
258 break; 288 break;
259 } 289 }
260 case 'g': { 290 case 'g': {
457 487
458 void gdb_debug_enter(m68k_context * context, uint32_t pc) 488 void gdb_debug_enter(m68k_context * context, uint32_t pc)
459 { 489 {
460 dfprintf(stderr, "Entered debugger at address %X\n", pc); 490 dfprintf(stderr, "Entered debugger at address %X\n", pc);
461 if (expect_break_response) { 491 if (expect_break_response) {
462 gdb_send_command("S05"); 492 if (context->wp_hit) {
493 context->wp_hit = 0;
494 char reply[128];
495 snprintf(reply, sizeof(reply), "T05watch:%X;", context->wp_hit_address);
496 gdb_send_command(reply);
497 } else {
498 gdb_send_command("S05");
499 }
463 expect_break_response = 0; 500 expect_break_response = 0;
464 } 501 }
465 debug_root *root = find_root(context); 502 debug_root *root = find_root(context);
466 if (!root) { 503 if (!root) {
467 fatal_error("Could not find debug root for CPU %p\n", context); 504 fatal_error("Could not find debug root for CPU %p\n", context);