Commit c33a346edff5910dddeea84792b73cb117518911
1 parent
61a2ad53
first part of single stepping support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@342 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
35 additions
and
1 deletions
cpu-all.h
| ... | ... | @@ -315,6 +315,7 @@ void cpu_interrupt(CPUState *s, int mask); |
| 315 | 315 | |
| 316 | 316 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc); |
| 317 | 317 | int cpu_breakpoint_remove(CPUState *env, uint32_t pc); |
| 318 | +void cpu_single_step(CPUState *env, int enabled); | |
| 318 | 319 | |
| 319 | 320 | /* gdb stub API */ |
| 320 | 321 | extern int gdbstub_fd; | ... | ... |
exec.c
| ... | ... | @@ -617,7 +617,8 @@ static void tb_reset_jump_recursive(TranslationBlock *tb) |
| 617 | 617 | tb_reset_jump_recursive2(tb, 1); |
| 618 | 618 | } |
| 619 | 619 | |
| 620 | -/* add a breakpoint */ | |
| 620 | +/* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a | |
| 621 | + breakpoint is reached */ | |
| 621 | 622 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc) |
| 622 | 623 | { |
| 623 | 624 | #if defined(TARGET_I386) |
| ... | ... | @@ -659,6 +660,20 @@ int cpu_breakpoint_remove(CPUState *env, uint32_t pc) |
| 659 | 660 | #endif |
| 660 | 661 | } |
| 661 | 662 | |
| 663 | +/* enable or disable single step mode. EXCP_DEBUG is returned by the | |
| 664 | + CPU loop after each instruction */ | |
| 665 | +void cpu_single_step(CPUState *env, int enabled) | |
| 666 | +{ | |
| 667 | +#if defined(TARGET_I386) | |
| 668 | + if (env->singlestep_enabled != enabled) { | |
| 669 | + env->singlestep_enabled = enabled; | |
| 670 | + /* must flush all the translated code to avoid inconsistancies */ | |
| 671 | + tb_flush(); | |
| 672 | + } | |
| 673 | +#endif | |
| 674 | +} | |
| 675 | + | |
| 676 | + | |
| 662 | 677 | /* mask must never be zero */ |
| 663 | 678 | void cpu_interrupt(CPUState *env, int mask) |
| 664 | 679 | { | ... | ... |
gdbstub.c
| ... | ... | @@ -324,6 +324,24 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
| 324 | 324 | snprintf(buf, sizeof(buf), "S%02x", ret); |
| 325 | 325 | put_packet(buf); |
| 326 | 326 | break; |
| 327 | + case 's': | |
| 328 | + env = cpu_gdbstub_get_env(opaque); | |
| 329 | + if (*p != '\0') { | |
| 330 | + addr = strtoul(p, (char **)&p, 16); | |
| 331 | +#if defined(TARGET_I386) | |
| 332 | + env->eip = addr; | |
| 333 | +#endif | |
| 334 | + } | |
| 335 | + cpu_single_step(env, 1); | |
| 336 | + ret = main_loop(opaque); | |
| 337 | + cpu_single_step(env, 0); | |
| 338 | + if (ret == EXCP_DEBUG) | |
| 339 | + ret = SIGTRAP; | |
| 340 | + else | |
| 341 | + ret = 0; | |
| 342 | + snprintf(buf, sizeof(buf), "S%02x", ret); | |
| 343 | + put_packet(buf); | |
| 344 | + break; | |
| 327 | 345 | case 'g': |
| 328 | 346 | env = cpu_gdbstub_get_env(opaque); |
| 329 | 347 | registers = (void *)mem_buf; | ... | ... |