Mercurial > repos > blastem
comparison gdb_remote.c @ 2107:f80c6111e1ae
Move some debugger state to a per-CPU structure. Add m command for returning to main CPU from sub CPU
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 12 Feb 2022 15:20:43 -0800 |
parents | 3a46ff899fa6 |
children | 8554751f17b5 |
comparison
equal
deleted
inserted
replaced
2106:d2989e32c026 | 2107:f80c6111e1ae |
---|---|
48 int cont = 0; | 48 int cont = 0; |
49 int expect_break_response=0; | 49 int expect_break_response=0; |
50 uint32_t resume_pc; | 50 uint32_t resume_pc; |
51 | 51 |
52 | 52 |
53 static uint16_t branch_t; | |
54 static uint16_t branch_f; | |
55 | |
56 static bp_def * breakpoints = NULL; | |
57 static uint32_t bp_index = 0; | |
58 | |
59 | |
60 void hex_32(uint32_t num, char * out) | 53 void hex_32(uint32_t num, char * out) |
61 { | 54 { |
62 for (int32_t shift = 28; shift >= 0; shift -= 4) | 55 for (int32_t shift = 28; shift >= 0; shift -= 4) |
63 { | 56 { |
64 uint8_t nibble = num >> shift & 0xF; | 57 uint8_t nibble = num >> shift & 0xF; |
169 | 162 |
170 void gdb_run_command(m68k_context * context, uint32_t pc, char * command) | 163 void gdb_run_command(m68k_context * context, uint32_t pc, char * command) |
171 { | 164 { |
172 char send_buf[512]; | 165 char send_buf[512]; |
173 dfprintf(stderr, "Received command %s\n", command); | 166 dfprintf(stderr, "Received command %s\n", command); |
167 debug_root *root = find_root(context); | |
168 if (!root) { | |
169 fatal_error("Could not find debug root for CPU %p\n", context); | |
170 } | |
174 switch(*command) | 171 switch(*command) |
175 { | 172 { |
176 | 173 |
177 case 'c': | 174 case 'c': |
178 if (*(command+1) != 0) { | 175 if (*(command+1) != 0) { |
200 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); | 197 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); |
201 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { | 198 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { |
202 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); | 199 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); |
203 } else if(m68k_is_branch(&inst)) { | 200 } else if(m68k_is_branch(&inst)) { |
204 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { | 201 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { |
205 branch_f = after; | 202 root->branch_f = after; |
206 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 203 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
207 insert_breakpoint(context, branch_t, gdb_debug_enter); | 204 insert_breakpoint(context, root->branch_t, gdb_debug_enter); |
208 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { | 205 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { |
209 branch_t = after; | 206 root->branch_t = after; |
210 branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 207 root->branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
211 insert_breakpoint(context, branch_f, gdb_debug_enter); | 208 insert_breakpoint(context, root->branch_f, gdb_debug_enter); |
212 } else { | 209 } else { |
213 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 210 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
214 } | 211 } |
215 } | 212 } |
216 insert_breakpoint(context, after, gdb_debug_enter); | 213 insert_breakpoint(context, after, gdb_debug_enter); |
231 uint8_t type = command[1]; | 228 uint8_t type = command[1]; |
232 if (type < '2') { | 229 if (type < '2') { |
233 uint32_t address = strtoul(command+3, NULL, 16); | 230 uint32_t address = strtoul(command+3, NULL, 16); |
234 insert_breakpoint(context, address, gdb_debug_enter); | 231 insert_breakpoint(context, address, gdb_debug_enter); |
235 bp_def *new_bp = malloc(sizeof(bp_def)); | 232 bp_def *new_bp = malloc(sizeof(bp_def)); |
236 new_bp->next = breakpoints; | 233 new_bp->next = root->breakpoints; |
237 new_bp->address = address; | 234 new_bp->address = address; |
238 new_bp->index = bp_index++; | 235 new_bp->index = root->bp_index++; |
239 breakpoints = new_bp; | 236 root->breakpoints = new_bp; |
240 gdb_send_command("OK"); | 237 gdb_send_command("OK"); |
241 } else { | 238 } else { |
242 //watchpoints are not currently supported | 239 //watchpoints are not currently supported |
243 gdb_send_command(""); | 240 gdb_send_command(""); |
244 } | 241 } |
247 case 'z': { | 244 case 'z': { |
248 uint8_t type = command[1]; | 245 uint8_t type = command[1]; |
249 if (type < '2') { | 246 if (type < '2') { |
250 uint32_t address = strtoul(command+3, NULL, 16); | 247 uint32_t address = strtoul(command+3, NULL, 16); |
251 remove_breakpoint(context, address); | 248 remove_breakpoint(context, address); |
252 bp_def **found = find_breakpoint(&breakpoints, address); | 249 bp_def **found = find_breakpoint(&root->breakpoints, address); |
253 if (*found) | 250 if (*found) |
254 { | 251 { |
255 bp_def * to_remove = *found; | 252 bp_def * to_remove = *found; |
256 *found = to_remove->next; | 253 *found = to_remove->next; |
257 free(to_remove); | 254 free(to_remove); |
428 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); | 425 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); |
429 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { | 426 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { |
430 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); | 427 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); |
431 } else if(m68k_is_branch(&inst)) { | 428 } else if(m68k_is_branch(&inst)) { |
432 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { | 429 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { |
433 branch_f = after; | 430 root->branch_f = after; |
434 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 431 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
435 insert_breakpoint(context, branch_t, gdb_debug_enter); | 432 insert_breakpoint(context, root->branch_t, gdb_debug_enter); |
436 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { | 433 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { |
437 branch_t = after; | 434 root->branch_t = after; |
438 branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 435 root->branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
439 insert_breakpoint(context, branch_f, gdb_debug_enter); | 436 insert_breakpoint(context, root->branch_f, gdb_debug_enter); |
440 } else { | 437 } else { |
441 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 438 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
442 } | 439 } |
443 } | 440 } |
444 insert_breakpoint(context, after, gdb_debug_enter); | 441 insert_breakpoint(context, after, gdb_debug_enter); |
471 dfprintf(stderr, "Entered debugger at address %X\n", pc); | 468 dfprintf(stderr, "Entered debugger at address %X\n", pc); |
472 if (expect_break_response) { | 469 if (expect_break_response) { |
473 gdb_send_command("S05"); | 470 gdb_send_command("S05"); |
474 expect_break_response = 0; | 471 expect_break_response = 0; |
475 } | 472 } |
476 if ((pc & 0xFFFFFF) == branch_t) { | 473 debug_root *root = find_root(context); |
477 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); | 474 if (!root) { |
475 fatal_error("Could not find debug root for CPU %p\n", context); | |
476 } | |
477 if ((pc & 0xFFFFFF) == root->branch_t) { | |
478 bp_def ** f_bp = find_breakpoint(&root->breakpoints, root->branch_f); | |
478 if (!*f_bp) { | 479 if (!*f_bp) { |
479 remove_breakpoint(context, branch_f); | 480 remove_breakpoint(context, root->branch_f); |
480 } | 481 } |
481 branch_t = branch_f = 0; | 482 root->branch_t = root->branch_f = 0; |
482 } else if((pc & 0xFFFFFF) == branch_f) { | 483 } else if((pc & 0xFFFFFF) == root->branch_f) { |
483 bp_def ** t_bp = find_breakpoint(&breakpoints, branch_t); | 484 bp_def ** t_bp = find_breakpoint(&root->breakpoints, root->branch_t); |
484 if (!*t_bp) { | 485 if (!*t_bp) { |
485 remove_breakpoint(context, branch_t); | 486 remove_breakpoint(context, root->branch_t); |
486 } | 487 } |
487 branch_t = branch_f = 0; | 488 root->branch_t = root->branch_f = 0; |
488 } | 489 } |
489 //Check if this is a user set breakpoint, or just a temporary one | 490 //Check if this is a user set breakpoint, or just a temporary one |
490 bp_def ** this_bp = find_breakpoint(&breakpoints, pc & 0xFFFFFF); | 491 bp_def ** this_bp = find_breakpoint(&root->breakpoints, pc & 0xFFFFFF); |
491 if (!*this_bp) { | 492 if (!*this_bp) { |
492 remove_breakpoint(context, pc & 0xFFFFFF); | 493 remove_breakpoint(context, pc & 0xFFFFFF); |
493 } | 494 } |
494 resume_pc = pc; | 495 resume_pc = pc; |
495 cont = 0; | 496 cont = 0; |