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,6 +315,7 @@ void cpu_interrupt(CPUState *s, int mask); | ||
| 315 | 315 | ||
| 316 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc); | 316 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc); |
| 317 | int cpu_breakpoint_remove(CPUState *env, uint32_t pc); | 317 | int cpu_breakpoint_remove(CPUState *env, uint32_t pc); |
| 318 | +void cpu_single_step(CPUState *env, int enabled); | ||
| 318 | 319 | ||
| 319 | /* gdb stub API */ | 320 | /* gdb stub API */ |
| 320 | extern int gdbstub_fd; | 321 | extern int gdbstub_fd; |
exec.c
| @@ -617,7 +617,8 @@ static void tb_reset_jump_recursive(TranslationBlock *tb) | @@ -617,7 +617,8 @@ static void tb_reset_jump_recursive(TranslationBlock *tb) | ||
| 617 | tb_reset_jump_recursive2(tb, 1); | 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 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc) | 622 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc) |
| 622 | { | 623 | { |
| 623 | #if defined(TARGET_I386) | 624 | #if defined(TARGET_I386) |
| @@ -659,6 +660,20 @@ int cpu_breakpoint_remove(CPUState *env, uint32_t pc) | @@ -659,6 +660,20 @@ int cpu_breakpoint_remove(CPUState *env, uint32_t pc) | ||
| 659 | #endif | 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 | /* mask must never be zero */ | 677 | /* mask must never be zero */ |
| 663 | void cpu_interrupt(CPUState *env, int mask) | 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,6 +324,24 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) | ||
| 324 | snprintf(buf, sizeof(buf), "S%02x", ret); | 324 | snprintf(buf, sizeof(buf), "S%02x", ret); |
| 325 | put_packet(buf); | 325 | put_packet(buf); |
| 326 | break; | 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 | case 'g': | 345 | case 'g': |
| 328 | env = cpu_gdbstub_get_env(opaque); | 346 | env = cpu_gdbstub_get_env(opaque); |
| 329 | registers = (void *)mem_buf; | 347 | registers = (void *)mem_buf; |