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; |