# HG changeset patch # User Michael Pavone # Date 1703397273 28800 # Node ID 39a009aea11315dcd51446202cc918e54b0eff69 # Parent bf4f1a8d1d48c85bb502a9f3a898f28381585af6 Implement watchpoints in gdb remote protocol diff -r bf4f1a8d1d48 -r 39a009aea113 gdb_remote.c --- a/gdb_remote.c Sat Dec 23 17:37:57 2023 -0800 +++ b/gdb_remote.c Sat Dec 23 21:54:33 2023 -0800 @@ -221,8 +221,10 @@ break; case 'Z': { uint8_t type = command[1]; + char *after_address; + uint32_t address = strtoul(command+3, &after_address, 16); + uint32_t kind = strtoul(after_address +1, NULL, 16); if (type < '2') { - uint32_t address = strtoul(command+3, NULL, 16); insert_breakpoint(context, address, gdb_debug_enter); bp_def *new_bp = malloc(sizeof(bp_def)); new_bp->next = root->breakpoints; @@ -232,16 +234,28 @@ new_bp->index = root->bp_index++; root->breakpoints = new_bp; gdb_send_command("OK"); + } else if (type == '2') { + m68k_add_watchpoint(context, address, kind); + bp_def *new_bp = malloc(sizeof(bp_def)); + new_bp->next = root->breakpoints; + new_bp->address = address; + new_bp->mask = kind; + new_bp->type = BP_TYPE_CPU_WATCH; + new_bp->index = root->bp_index++; + root->breakpoints = new_bp; + gdb_send_command("OK"); } else { - //watchpoints are not currently supported + //read and access watchpoints are not currently supported gdb_send_command(""); } break; } case 'z': { uint8_t type = command[1]; + char *after_address; + uint32_t address = strtoul(command+3, &after_address, 16); + uint32_t kind = strtoul(after_address +1, NULL, 16); if (type < '2') { - uint32_t address = strtoul(command+3, NULL, 16); remove_breakpoint(context, address); bp_def **found = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU); if (*found) @@ -251,8 +265,24 @@ free(to_remove); } gdb_send_command("OK"); + } else if (type == '2') { + m68k_remove_watchpoint(context, address, kind); + bp_def **cur = &root->breakpoints; + while (*cur) + { + if ((*cur)->type == BP_TYPE_CPU_WATCH && (*cur)->address == address && (*cur)->mask == kind) { + break; + } + cur = &(*cur)->next; + } + if (*cur) { + bp_def *to_remove = *cur; + *cur = to_remove->next; + free(to_remove); + } + gdb_send_command("OK"); } else { - //watchpoints are not currently supported + //read and access watchpoints are not currently supported gdb_send_command(""); } break; @@ -459,7 +489,14 @@ { dfprintf(stderr, "Entered debugger at address %X\n", pc); if (expect_break_response) { - gdb_send_command("S05"); + if (context->wp_hit) { + context->wp_hit = 0; + char reply[128]; + snprintf(reply, sizeof(reply), "T05watch:%X;", context->wp_hit_address); + gdb_send_command(reply); + } else { + gdb_send_command("S05"); + } expect_break_response = 0; } debug_root *root = find_root(context);