Commit 1b530a6dfcfe4510f66cb90a1717698063ac7a4f

Authored by aurel32
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
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;
@@ -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;