Commit 1b530a6dfcfe4510f66cb90a1717698063ac7a4f
1 parent
79d342dc
Add new command line option -singlestep for tcg single stepping.
This replaces a compile time option for some targets and adds this feature to targets which did not have a compile time option. Add monitor command to enable or disable single step mode. Modify monitor command "info status" to display single step mode. Signed-off-by: Stefan Weil <weil@mail.berlios.de> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7004 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
17 changed files
with
79 additions
and
19 deletions
bsd-user/main.c
| @@ -33,6 +33,8 @@ | @@ -33,6 +33,8 @@ | ||
| 33 | 33 | ||
| 34 | #define DEBUG_LOGFILE "/tmp/qemu.log" | 34 | #define DEBUG_LOGFILE "/tmp/qemu.log" |
| 35 | 35 | ||
| 36 | +int singlestep; | ||
| 37 | + | ||
| 36 | static const char *interp_prefix = CONFIG_QEMU_PREFIX; | 38 | static const char *interp_prefix = CONFIG_QEMU_PREFIX; |
| 37 | const char *qemu_uname_release = CONFIG_UNAME_RELEASE; | 39 | const char *qemu_uname_release = CONFIG_UNAME_RELEASE; |
| 38 | extern char **environ; | 40 | extern char **environ; |
| @@ -378,6 +380,7 @@ static void usage(void) | @@ -378,6 +380,7 @@ static void usage(void) | ||
| 378 | "Debug options:\n" | 380 | "Debug options:\n" |
| 379 | "-d options activate log (logfile=%s)\n" | 381 | "-d options activate log (logfile=%s)\n" |
| 380 | "-p pagesize set the host page size to 'pagesize'\n" | 382 | "-p pagesize set the host page size to 'pagesize'\n" |
| 383 | + "-singlestep always run in singlestep mode\n" | ||
| 381 | "-strace log system calls\n" | 384 | "-strace log system calls\n" |
| 382 | "\n" | 385 | "\n" |
| 383 | "Environment variables:\n" | 386 | "Environment variables:\n" |
| @@ -500,6 +503,8 @@ int main(int argc, char **argv) | @@ -500,6 +503,8 @@ int main(int argc, char **argv) | ||
| 500 | usage(); | 503 | usage(); |
| 501 | } | 504 | } |
| 502 | optind++; | 505 | optind++; |
| 506 | + } else if (!strcmp(r, "singlestep")) { | ||
| 507 | + singlestep = 1; | ||
| 503 | } else if (!strcmp(r, "strace")) { | 508 | } else if (!strcmp(r, "strace")) { |
| 504 | do_strace = 1; | 509 | do_strace = 1; |
| 505 | } else | 510 | } else |
darwin-user/main.c
| @@ -41,6 +41,8 @@ | @@ -41,6 +41,8 @@ | ||
| 41 | #include <mach/mach_init.h> | 41 | #include <mach/mach_init.h> |
| 42 | #include <mach/vm_map.h> | 42 | #include <mach/vm_map.h> |
| 43 | 43 | ||
| 44 | +int singlestep; | ||
| 45 | + | ||
| 44 | const char *interp_prefix = ""; | 46 | const char *interp_prefix = ""; |
| 45 | 47 | ||
| 46 | asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000"); | 48 | asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000"); |
| @@ -751,6 +753,7 @@ void usage(void) | @@ -751,6 +753,7 @@ void usage(void) | ||
| 751 | "-d options activate log (logfile='%s')\n" | 753 | "-d options activate log (logfile='%s')\n" |
| 752 | "-g wait for gdb on port 1234\n" | 754 | "-g wait for gdb on port 1234\n" |
| 753 | "-p pagesize set the host page size to 'pagesize'\n", | 755 | "-p pagesize set the host page size to 'pagesize'\n", |
| 756 | + "-singlestep always run in singlestep mode\n" | ||
| 754 | TARGET_ARCH, | 757 | TARGET_ARCH, |
| 755 | TARGET_ARCH, | 758 | TARGET_ARCH, |
| 756 | interp_prefix, | 759 | interp_prefix, |
| @@ -842,6 +845,8 @@ int main(int argc, char **argv) | @@ -842,6 +845,8 @@ int main(int argc, char **argv) | ||
| 842 | #endif | 845 | #endif |
| 843 | exit(1); | 846 | exit(1); |
| 844 | } | 847 | } |
| 848 | + } else if (!strcmp(r, "singlestep")) { | ||
| 849 | + singlestep = 1; | ||
| 845 | } else | 850 | } else |
| 846 | { | 851 | { |
| 847 | usage(); | 852 | usage(); |
exec-all.h
| @@ -384,4 +384,8 @@ static inline int kqemu_is_ok(CPUState *env) | @@ -384,4 +384,8 @@ static inline int kqemu_is_ok(CPUState *env) | ||
| 384 | typedef void (CPUDebugExcpHandler)(CPUState *env); | 384 | typedef void (CPUDebugExcpHandler)(CPUState *env); |
| 385 | 385 | ||
| 386 | CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); | 386 | CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); |
| 387 | + | ||
| 388 | +/* vl.c */ | ||
| 389 | +extern int singlestep; | ||
| 390 | + | ||
| 387 | #endif | 391 | #endif |
linux-user/main.c
| @@ -39,6 +39,8 @@ | @@ -39,6 +39,8 @@ | ||
| 39 | 39 | ||
| 40 | char *exec_path; | 40 | char *exec_path; |
| 41 | 41 | ||
| 42 | +int singlestep; | ||
| 43 | + | ||
| 42 | static const char *interp_prefix = CONFIG_QEMU_PREFIX; | 44 | static const char *interp_prefix = CONFIG_QEMU_PREFIX; |
| 43 | const char *qemu_uname_release = CONFIG_UNAME_RELEASE; | 45 | const char *qemu_uname_release = CONFIG_UNAME_RELEASE; |
| 44 | 46 | ||
| @@ -2217,6 +2219,7 @@ static void usage(void) | @@ -2217,6 +2219,7 @@ static void usage(void) | ||
| 2217 | "Debug options:\n" | 2219 | "Debug options:\n" |
| 2218 | "-d options activate log (logfile=%s)\n" | 2220 | "-d options activate log (logfile=%s)\n" |
| 2219 | "-p pagesize set the host page size to 'pagesize'\n" | 2221 | "-p pagesize set the host page size to 'pagesize'\n" |
| 2222 | + "-singlestep always run in singlestep mode\n" | ||
| 2220 | "-strace log system calls\n" | 2223 | "-strace log system calls\n" |
| 2221 | "\n" | 2224 | "\n" |
| 2222 | "Environment variables:\n" | 2225 | "Environment variables:\n" |
| @@ -2359,6 +2362,8 @@ int main(int argc, char **argv, char **envp) | @@ -2359,6 +2362,8 @@ int main(int argc, char **argv, char **envp) | ||
| 2359 | } | 2362 | } |
| 2360 | } else if (!strcmp(r, "drop-ld-preload")) { | 2363 | } else if (!strcmp(r, "drop-ld-preload")) { |
| 2361 | (void) envlist_unsetenv(envlist, "LD_PRELOAD"); | 2364 | (void) envlist_unsetenv(envlist, "LD_PRELOAD"); |
| 2365 | + } else if (!strcmp(r, "singlestep")) { | ||
| 2366 | + singlestep = 1; | ||
| 2362 | } else if (!strcmp(r, "strace")) { | 2367 | } else if (!strcmp(r, "strace")) { |
| 2363 | do_strace = 1; | 2368 | do_strace = 1; |
| 2364 | } else | 2369 | } else |
monitor.c
| @@ -527,6 +527,17 @@ static void do_log(Monitor *mon, const char *items) | @@ -527,6 +527,17 @@ static void do_log(Monitor *mon, const char *items) | ||
| 527 | cpu_set_log(mask); | 527 | cpu_set_log(mask); |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | +static void do_singlestep(Monitor *mon, const char *option) | ||
| 531 | +{ | ||
| 532 | + if (!option || !strcmp(option, "on")) { | ||
| 533 | + singlestep = 1; | ||
| 534 | + } else if (!strcmp(option, "off")) { | ||
| 535 | + singlestep = 0; | ||
| 536 | + } else { | ||
| 537 | + monitor_printf(mon, "unexpected option %s\n", option); | ||
| 538 | + } | ||
| 539 | +} | ||
| 540 | + | ||
| 530 | static void do_stop(Monitor *mon) | 541 | static void do_stop(Monitor *mon) |
| 531 | { | 542 | { |
| 532 | vm_stop(EXCP_INTERRUPT); | 543 | vm_stop(EXCP_INTERRUPT); |
| @@ -1511,9 +1522,13 @@ static void do_inject_nmi(Monitor *mon, int cpu_index) | @@ -1511,9 +1522,13 @@ static void do_inject_nmi(Monitor *mon, int cpu_index) | ||
| 1511 | 1522 | ||
| 1512 | static void do_info_status(Monitor *mon) | 1523 | static void do_info_status(Monitor *mon) |
| 1513 | { | 1524 | { |
| 1514 | - if (vm_running) | ||
| 1515 | - monitor_printf(mon, "VM status: running\n"); | ||
| 1516 | - else | 1525 | + if (vm_running) { |
| 1526 | + if (singlestep) { | ||
| 1527 | + monitor_printf(mon, "VM status: running (single step mode)\n"); | ||
| 1528 | + } else { | ||
| 1529 | + monitor_printf(mon, "VM status: running\n"); | ||
| 1530 | + } | ||
| 1531 | + } else | ||
| 1517 | monitor_printf(mon, "VM status: paused\n"); | 1532 | monitor_printf(mon, "VM status: paused\n"); |
| 1518 | } | 1533 | } |
| 1519 | 1534 | ||
| @@ -1644,6 +1659,8 @@ static const mon_cmd_t mon_cmds[] = { | @@ -1644,6 +1659,8 @@ static const mon_cmd_t mon_cmds[] = { | ||
| 1644 | "tag|id", "restore a VM snapshot from its tag or id" }, | 1659 | "tag|id", "restore a VM snapshot from its tag or id" }, |
| 1645 | { "delvm", "s", do_delvm, | 1660 | { "delvm", "s", do_delvm, |
| 1646 | "tag|id", "delete a VM snapshot from its tag or id" }, | 1661 | "tag|id", "delete a VM snapshot from its tag or id" }, |
| 1662 | + { "singlestep", "s?", do_singlestep, | ||
| 1663 | + "[on|off]", "run emulation in singlestep mode or switch to normal mode", }, | ||
| 1647 | { "stop", "", do_stop, | 1664 | { "stop", "", do_stop, |
| 1648 | "", "stop emulation", }, | 1665 | "", "stop emulation", }, |
| 1649 | { "c|cont", "", do_cont, | 1666 | { "c|cont", "", do_cont, |
qemu-doc.texi
| @@ -490,6 +490,10 @@ Set the whole virtual machine to the snapshot identified by the tag | @@ -490,6 +490,10 @@ Set the whole virtual machine to the snapshot identified by the tag | ||
| 490 | @item delvm @var{tag}|@var{id} | 490 | @item delvm @var{tag}|@var{id} |
| 491 | Delete the snapshot identified by @var{tag} or @var{id}. | 491 | Delete the snapshot identified by @var{tag} or @var{id}. |
| 492 | 492 | ||
| 493 | +@item singlestep [off] | ||
| 494 | +Run the emulation in single step mode. | ||
| 495 | +If called with option off, the emulation returns to normal mode. | ||
| 496 | + | ||
| 493 | @item stop | 497 | @item stop |
| 494 | Stop emulation. | 498 | Stop emulation. |
| 495 | 499 | ||
| @@ -2370,6 +2374,8 @@ Activate log (logfile=/tmp/qemu.log) | @@ -2370,6 +2374,8 @@ Activate log (logfile=/tmp/qemu.log) | ||
| 2370 | Act as if the host page size was 'pagesize' bytes | 2374 | Act as if the host page size was 'pagesize' bytes |
| 2371 | @item -g port | 2375 | @item -g port |
| 2372 | Wait gdb connection to port | 2376 | Wait gdb connection to port |
| 2377 | +@item -singlestep | ||
| 2378 | +Run the emulation in single step mode. | ||
| 2373 | @end table | 2379 | @end table |
| 2374 | 2380 | ||
| 2375 | Environment variables: | 2381 | Environment variables: |
| @@ -2488,6 +2494,8 @@ Debug options: | @@ -2488,6 +2494,8 @@ Debug options: | ||
| 2488 | Activate log (logfile=/tmp/qemu.log) | 2494 | Activate log (logfile=/tmp/qemu.log) |
| 2489 | @item -p pagesize | 2495 | @item -p pagesize |
| 2490 | Act as if the host page size was 'pagesize' bytes | 2496 | Act as if the host page size was 'pagesize' bytes |
| 2497 | +@item -singlestep | ||
| 2498 | +Run the emulation in single step mode. | ||
| 2491 | @end table | 2499 | @end table |
| 2492 | 2500 | ||
| 2493 | @node BSD User space emulator | 2501 | @node BSD User space emulator |
| @@ -2550,6 +2558,8 @@ Debug options: | @@ -2550,6 +2558,8 @@ Debug options: | ||
| 2550 | Activate log (logfile=/tmp/qemu.log) | 2558 | Activate log (logfile=/tmp/qemu.log) |
| 2551 | @item -p pagesize | 2559 | @item -p pagesize |
| 2552 | Act as if the host page size was 'pagesize' bytes | 2560 | Act as if the host page size was 'pagesize' bytes |
| 2561 | +@item -singlestep | ||
| 2562 | +Run the emulation in single step mode. | ||
| 2553 | @end table | 2563 | @end table |
| 2554 | 2564 | ||
| 2555 | @node compilation | 2565 | @node compilation |
qemu-options.hx
| @@ -1209,6 +1209,13 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU | @@ -1209,6 +1209,13 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU | ||
| 1209 | from a script. | 1209 | from a script. |
| 1210 | ETEXI | 1210 | ETEXI |
| 1211 | 1211 | ||
| 1212 | +DEF("singlestep", 0, QEMU_OPTION_singlestep, \ | ||
| 1213 | + "-singlestep always run in singlestep mode\n") | ||
| 1214 | +STEXI | ||
| 1215 | +@item -singlestep | ||
| 1216 | +Run the emulation in single step mode. | ||
| 1217 | +ETEXI | ||
| 1218 | + | ||
| 1212 | DEF("S", 0, QEMU_OPTION_S, \ | 1219 | DEF("S", 0, QEMU_OPTION_S, \ |
| 1213 | "-S freeze CPU at startup (use 'c' to start execution)\n") | 1220 | "-S freeze CPU at startup (use 'c' to start execution)\n") |
| 1214 | STEXI | 1221 | STEXI |
target-alpha/translate.c
| @@ -2412,11 +2412,11 @@ static always_inline void gen_intermediate_code_internal (CPUState *env, | @@ -2412,11 +2412,11 @@ static always_inline void gen_intermediate_code_internal (CPUState *env, | ||
| 2412 | if (env->singlestep_enabled) { | 2412 | if (env->singlestep_enabled) { |
| 2413 | gen_excp(&ctx, EXCP_DEBUG, 0); | 2413 | gen_excp(&ctx, EXCP_DEBUG, 0); |
| 2414 | break; | 2414 | break; |
| 2415 | - } | 2415 | + } |
| 2416 | 2416 | ||
| 2417 | -#if defined (DO_SINGLE_STEP) | ||
| 2418 | - break; | ||
| 2419 | -#endif | 2417 | + if (singlestep) { |
| 2418 | + break; | ||
| 2419 | + } | ||
| 2420 | } | 2420 | } |
| 2421 | if (ret != 1 && ret != 3) { | 2421 | if (ret != 1 && ret != 3) { |
| 2422 | tcg_gen_movi_i64(cpu_pc, ctx.pc); | 2422 | tcg_gen_movi_i64(cpu_pc, ctx.pc); |
target-arm/translate.c
| @@ -8791,6 +8791,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, | @@ -8791,6 +8791,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, | ||
| 8791 | num_insns ++; | 8791 | num_insns ++; |
| 8792 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && | 8792 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
| 8793 | !env->singlestep_enabled && | 8793 | !env->singlestep_enabled && |
| 8794 | + !singlestep && | ||
| 8794 | dc->pc < next_page_start && | 8795 | dc->pc < next_page_start && |
| 8795 | num_insns < max_insns); | 8796 | num_insns < max_insns); |
| 8796 | 8797 |
target-cris/translate.c
| @@ -3272,6 +3272,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | @@ -3272,6 +3272,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
| 3272 | break; | 3272 | break; |
| 3273 | } while (!dc->is_jmp && !dc->cpustate_changed | 3273 | } while (!dc->is_jmp && !dc->cpustate_changed |
| 3274 | && gen_opc_ptr < gen_opc_end | 3274 | && gen_opc_ptr < gen_opc_end |
| 3275 | + && !singlestep | ||
| 3275 | && (dc->pc < next_page_start) | 3276 | && (dc->pc < next_page_start) |
| 3276 | && num_insns < max_insns); | 3277 | && num_insns < max_insns); |
| 3277 | 3278 |
target-i386/translate.c
| @@ -7733,6 +7733,11 @@ static inline void gen_intermediate_code_internal(CPUState *env, | @@ -7733,6 +7733,11 @@ static inline void gen_intermediate_code_internal(CPUState *env, | ||
| 7733 | gen_eob(dc); | 7733 | gen_eob(dc); |
| 7734 | break; | 7734 | break; |
| 7735 | } | 7735 | } |
| 7736 | + if (singlestep) { | ||
| 7737 | + gen_jmp_im(pc_ptr - dc->cs_base); | ||
| 7738 | + gen_eob(dc); | ||
| 7739 | + break; | ||
| 7740 | + } | ||
| 7736 | } | 7741 | } |
| 7737 | if (tb->cflags & CF_LAST_IO) | 7742 | if (tb->cflags & CF_LAST_IO) |
| 7738 | gen_io_end(); | 7743 | gen_io_end(); |
target-m68k/translate.c
| @@ -3031,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | @@ -3031,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
| 3031 | num_insns++; | 3031 | num_insns++; |
| 3032 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && | 3032 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
| 3033 | !env->singlestep_enabled && | 3033 | !env->singlestep_enabled && |
| 3034 | + !singlestep && | ||
| 3034 | (pc_offset) < (TARGET_PAGE_SIZE - 32) && | 3035 | (pc_offset) < (TARGET_PAGE_SIZE - 32) && |
| 3035 | num_insns < max_insns); | 3036 | num_insns < max_insns); |
| 3036 | 3037 |
target-mips/translate.c
| @@ -38,7 +38,6 @@ | @@ -38,7 +38,6 @@ | ||
| 38 | 38 | ||
| 39 | //#define MIPS_DEBUG_DISAS | 39 | //#define MIPS_DEBUG_DISAS |
| 40 | //#define MIPS_DEBUG_SIGN_EXTENSIONS | 40 | //#define MIPS_DEBUG_SIGN_EXTENSIONS |
| 41 | -//#define MIPS_SINGLE_STEP | ||
| 42 | 41 | ||
| 43 | /* MIPS major opcodes */ | 42 | /* MIPS major opcodes */ |
| 44 | #define MASK_OP_MAJOR(op) (op & (0x3F << 26)) | 43 | #define MASK_OP_MAJOR(op) (op & (0x3F << 26)) |
| @@ -8140,9 +8139,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -8140,9 +8139,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 8140 | 8139 | ||
| 8141 | if (num_insns >= max_insns) | 8140 | if (num_insns >= max_insns) |
| 8142 | break; | 8141 | break; |
| 8143 | -#if defined (MIPS_SINGLE_STEP) | ||
| 8144 | - break; | ||
| 8145 | -#endif | 8142 | + |
| 8143 | + if (singlestep) | ||
| 8144 | + break; | ||
| 8146 | } | 8145 | } |
| 8147 | if (tb->cflags & CF_LAST_IO) | 8146 | if (tb->cflags & CF_LAST_IO) |
| 8148 | gen_io_end(); | 8147 | gen_io_end(); |
target-ppc/translate.c
| @@ -39,7 +39,6 @@ | @@ -39,7 +39,6 @@ | ||
| 39 | #define GDBSTUB_SINGLE_STEP 0x4 | 39 | #define GDBSTUB_SINGLE_STEP 0x4 |
| 40 | 40 | ||
| 41 | /* Include definitions for instructions classes and implementations flags */ | 41 | /* Include definitions for instructions classes and implementations flags */ |
| 42 | -//#define DO_SINGLE_STEP | ||
| 43 | //#define PPC_DEBUG_DISAS | 42 | //#define PPC_DEBUG_DISAS |
| 44 | //#define DO_PPC_STATISTICS | 43 | //#define DO_PPC_STATISTICS |
| 45 | 44 | ||
| @@ -8288,15 +8287,13 @@ static always_inline void gen_intermediate_code_internal (CPUState *env, | @@ -8288,15 +8287,13 @@ static always_inline void gen_intermediate_code_internal (CPUState *env, | ||
| 8288 | gen_exception(ctxp, POWERPC_EXCP_TRACE); | 8287 | gen_exception(ctxp, POWERPC_EXCP_TRACE); |
| 8289 | } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || | 8288 | } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || |
| 8290 | (env->singlestep_enabled) || | 8289 | (env->singlestep_enabled) || |
| 8290 | + singlestep || | ||
| 8291 | num_insns >= max_insns)) { | 8291 | num_insns >= max_insns)) { |
| 8292 | /* if we reach a page boundary or are single stepping, stop | 8292 | /* if we reach a page boundary or are single stepping, stop |
| 8293 | * generation | 8293 | * generation |
| 8294 | */ | 8294 | */ |
| 8295 | break; | 8295 | break; |
| 8296 | } | 8296 | } |
| 8297 | -#if defined (DO_SINGLE_STEP) | ||
| 8298 | - break; | ||
| 8299 | -#endif | ||
| 8300 | } | 8297 | } |
| 8301 | if (tb->cflags & CF_LAST_IO) | 8298 | if (tb->cflags & CF_LAST_IO) |
| 8302 | gen_io_end(); | 8299 | gen_io_end(); |
target-sh4/translate.c
| @@ -1967,9 +1967,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | @@ -1967,9 +1967,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | ||
| 1967 | break; | 1967 | break; |
| 1968 | if (num_insns >= max_insns) | 1968 | if (num_insns >= max_insns) |
| 1969 | break; | 1969 | break; |
| 1970 | -#ifdef SH4_SINGLE_STEP | ||
| 1971 | - break; | ||
| 1972 | -#endif | 1970 | + if (singlestep) |
| 1971 | + break; | ||
| 1973 | } | 1972 | } |
| 1974 | if (tb->cflags & CF_LAST_IO) | 1973 | if (tb->cflags & CF_LAST_IO) |
| 1975 | gen_io_end(); | 1974 | gen_io_end(); |
target-sparc/translate.c
| @@ -4838,7 +4838,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, | @@ -4838,7 +4838,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, | ||
| 4838 | break; | 4838 | break; |
| 4839 | /* if single step mode, we generate only one instruction and | 4839 | /* if single step mode, we generate only one instruction and |
| 4840 | generate an exception */ | 4840 | generate an exception */ |
| 4841 | - if (env->singlestep_enabled) { | 4841 | + if (env->singlestep_enabled || singlestep) { |
| 4842 | tcg_gen_movi_tl(cpu_pc, dc->pc); | 4842 | tcg_gen_movi_tl(cpu_pc, dc->pc); |
| 4843 | tcg_gen_exit_tb(0); | 4843 | tcg_gen_exit_tb(0); |
| 4844 | break; | 4844 | break; |
vl.c
| @@ -236,6 +236,7 @@ int win2k_install_hack = 0; | @@ -236,6 +236,7 @@ int win2k_install_hack = 0; | ||
| 236 | int rtc_td_hack = 0; | 236 | int rtc_td_hack = 0; |
| 237 | #endif | 237 | #endif |
| 238 | int usb_enabled = 0; | 238 | int usb_enabled = 0; |
| 239 | +int singlestep = 0; | ||
| 239 | int smp_cpus = 1; | 240 | int smp_cpus = 1; |
| 240 | const char *vnc_display; | 241 | const char *vnc_display; |
| 241 | int acpi_enabled = 1; | 242 | int acpi_enabled = 1; |
| @@ -4660,6 +4661,9 @@ int main(int argc, char **argv, char **envp) | @@ -4660,6 +4661,9 @@ int main(int argc, char **argv, char **envp) | ||
| 4660 | case QEMU_OPTION_bios: | 4661 | case QEMU_OPTION_bios: |
| 4661 | bios_name = optarg; | 4662 | bios_name = optarg; |
| 4662 | break; | 4663 | break; |
| 4664 | + case QEMU_OPTION_singlestep: | ||
| 4665 | + singlestep = 1; | ||
| 4666 | + break; | ||
| 4663 | case QEMU_OPTION_S: | 4667 | case QEMU_OPTION_S: |
| 4664 | autostart = 0; | 4668 | autostart = 0; |
| 4665 | break; | 4669 | break; |