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