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 33  
34 34 #define DEBUG_LOGFILE "/tmp/qemu.log"
35 35  
  36 +int singlestep;
  37 +
36 38 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
37 39 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
38 40 extern char **environ;
... ... @@ -378,6 +380,7 @@ static void usage(void)
378 380 "Debug options:\n"
379 381 "-d options activate log (logfile=%s)\n"
380 382 "-p pagesize set the host page size to 'pagesize'\n"
  383 + "-singlestep always run in singlestep mode\n"
381 384 "-strace log system calls\n"
382 385 "\n"
383 386 "Environment variables:\n"
... ... @@ -500,6 +503,8 @@ int main(int argc, char **argv)
500 503 usage();
501 504 }
502 505 optind++;
  506 + } else if (!strcmp(r, "singlestep")) {
  507 + singlestep = 1;
503 508 } else if (!strcmp(r, "strace")) {
504 509 do_strace = 1;
505 510 } else
... ...
darwin-user/main.c
... ... @@ -41,6 +41,8 @@
41 41 #include <mach/mach_init.h>
42 42 #include <mach/vm_map.h>
43 43  
  44 +int singlestep;
  45 +
44 46 const char *interp_prefix = "";
45 47  
46 48 asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
... ... @@ -751,6 +753,7 @@ void usage(void)
751 753 "-d options activate log (logfile='%s')\n"
752 754 "-g wait for gdb on port 1234\n"
753 755 "-p pagesize set the host page size to 'pagesize'\n",
  756 + "-singlestep always run in singlestep mode\n"
754 757 TARGET_ARCH,
755 758 TARGET_ARCH,
756 759 interp_prefix,
... ... @@ -842,6 +845,8 @@ int main(int argc, char **argv)
842 845 #endif
843 846 exit(1);
844 847 }
  848 + } else if (!strcmp(r, "singlestep")) {
  849 + singlestep = 1;
845 850 } else
846 851 {
847 852 usage();
... ...
exec-all.h
... ... @@ -384,4 +384,8 @@ static inline int kqemu_is_ok(CPUState *env)
384 384 typedef void (CPUDebugExcpHandler)(CPUState *env);
385 385  
386 386 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
  387 +
  388 +/* vl.c */
  389 +extern int singlestep;
  390 +
387 391 #endif
... ...
linux-user/main.c
... ... @@ -39,6 +39,8 @@
39 39  
40 40 char *exec_path;
41 41  
  42 +int singlestep;
  43 +
42 44 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
43 45 const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
44 46  
... ... @@ -2217,6 +2219,7 @@ static void usage(void)
2217 2219 "Debug options:\n"
2218 2220 "-d options activate log (logfile=%s)\n"
2219 2221 "-p pagesize set the host page size to 'pagesize'\n"
  2222 + "-singlestep always run in singlestep mode\n"
2220 2223 "-strace log system calls\n"
2221 2224 "\n"
2222 2225 "Environment variables:\n"
... ... @@ -2359,6 +2362,8 @@ int main(int argc, char **argv, char **envp)
2359 2362 }
2360 2363 } else if (!strcmp(r, "drop-ld-preload")) {
2361 2364 (void) envlist_unsetenv(envlist, "LD_PRELOAD");
  2365 + } else if (!strcmp(r, "singlestep")) {
  2366 + singlestep = 1;
2362 2367 } else if (!strcmp(r, "strace")) {
2363 2368 do_strace = 1;
2364 2369 } else
... ...
monitor.c
... ... @@ -527,6 +527,17 @@ static void do_log(Monitor *mon, const char *items)
527 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 541 static void do_stop(Monitor *mon)
531 542 {
532 543 vm_stop(EXCP_INTERRUPT);
... ... @@ -1511,9 +1522,13 @@ static void do_inject_nmi(Monitor *mon, int cpu_index)
1511 1522  
1512 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 1532 monitor_printf(mon, "VM status: paused\n");
1518 1533 }
1519 1534  
... ... @@ -1644,6 +1659,8 @@ static const mon_cmd_t mon_cmds[] = {
1644 1659 "tag|id", "restore a VM snapshot from its tag or id" },
1645 1660 { "delvm", "s", do_delvm,
1646 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 1664 { "stop", "", do_stop,
1648 1665 "", "stop emulation", },
1649 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 490 @item delvm @var{tag}|@var{id}
491 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 497 @item stop
494 498 Stop emulation.
495 499  
... ... @@ -2370,6 +2374,8 @@ Activate log (logfile=/tmp/qemu.log)
2370 2374 Act as if the host page size was 'pagesize' bytes
2371 2375 @item -g port
2372 2376 Wait gdb connection to port
  2377 +@item -singlestep
  2378 +Run the emulation in single step mode.
2373 2379 @end table
2374 2380  
2375 2381 Environment variables:
... ... @@ -2488,6 +2494,8 @@ Debug options:
2488 2494 Activate log (logfile=/tmp/qemu.log)
2489 2495 @item -p pagesize
2490 2496 Act as if the host page size was 'pagesize' bytes
  2497 +@item -singlestep
  2498 +Run the emulation in single step mode.
2491 2499 @end table
2492 2500  
2493 2501 @node BSD User space emulator
... ... @@ -2550,6 +2558,8 @@ Debug options:
2550 2558 Activate log (logfile=/tmp/qemu.log)
2551 2559 @item -p pagesize
2552 2560 Act as if the host page size was 'pagesize' bytes
  2561 +@item -singlestep
  2562 +Run the emulation in single step mode.
2553 2563 @end table
2554 2564  
2555 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 1209 from a script.
1210 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 1219 DEF("S", 0, QEMU_OPTION_S, \
1213 1220 "-S freeze CPU at startup (use 'c' to start execution)\n")
1214 1221 STEXI
... ...
target-alpha/translate.c
... ... @@ -2412,11 +2412,11 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
2412 2412 if (env->singlestep_enabled) {
2413 2413 gen_excp(&ctx, EXCP_DEBUG, 0);
2414 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 2421 if (ret != 1 && ret != 3) {
2422 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 8791 num_insns ++;
8792 8792 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8793 8793 !env->singlestep_enabled &&
  8794 + !singlestep &&
8794 8795 dc->pc < next_page_start &&
8795 8796 num_insns < max_insns);
8796 8797  
... ...
target-cris/translate.c
... ... @@ -3272,6 +3272,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3272 3272 break;
3273 3273 } while (!dc->is_jmp && !dc->cpustate_changed
3274 3274 && gen_opc_ptr < gen_opc_end
  3275 + && !singlestep
3275 3276 && (dc->pc < next_page_start)
3276 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 7733 gen_eob(dc);
7734 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 7742 if (tb->cflags & CF_LAST_IO)
7738 7743 gen_io_end();
... ...
target-m68k/translate.c
... ... @@ -3031,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3031 3031 num_insns++;
3032 3032 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3033 3033 !env->singlestep_enabled &&
  3034 + !singlestep &&
3034 3035 (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
3035 3036 num_insns < max_insns);
3036 3037  
... ...
target-mips/translate.c
... ... @@ -38,7 +38,6 @@
38 38  
39 39 //#define MIPS_DEBUG_DISAS
40 40 //#define MIPS_DEBUG_SIGN_EXTENSIONS
41   -//#define MIPS_SINGLE_STEP
42 41  
43 42 /* MIPS major opcodes */
44 43 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
... ... @@ -8140,9 +8139,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8140 8139  
8141 8140 if (num_insns >= max_insns)
8142 8141 break;
8143   -#if defined (MIPS_SINGLE_STEP)
8144   - break;
8145   -#endif
  8142 +
  8143 + if (singlestep)
  8144 + break;
8146 8145 }
8147 8146 if (tb->cflags & CF_LAST_IO)
8148 8147 gen_io_end();
... ...
target-ppc/translate.c
... ... @@ -39,7 +39,6 @@
39 39 #define GDBSTUB_SINGLE_STEP 0x4
40 40  
41 41 /* Include definitions for instructions classes and implementations flags */
42   -//#define DO_SINGLE_STEP
43 42 //#define PPC_DEBUG_DISAS
44 43 //#define DO_PPC_STATISTICS
45 44  
... ... @@ -8288,15 +8287,13 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
8288 8287 gen_exception(ctxp, POWERPC_EXCP_TRACE);
8289 8288 } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
8290 8289 (env->singlestep_enabled) ||
  8290 + singlestep ||
8291 8291 num_insns >= max_insns)) {
8292 8292 /* if we reach a page boundary or are single stepping, stop
8293 8293 * generation
8294 8294 */
8295 8295 break;
8296 8296 }
8297   -#if defined (DO_SINGLE_STEP)
8298   - break;
8299   -#endif
8300 8297 }
8301 8298 if (tb->cflags & CF_LAST_IO)
8302 8299 gen_io_end();
... ...
target-sh4/translate.c
... ... @@ -1967,9 +1967,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1967 1967 break;
1968 1968 if (num_insns >= max_insns)
1969 1969 break;
1970   -#ifdef SH4_SINGLE_STEP
1971   - break;
1972   -#endif
  1970 + if (singlestep)
  1971 + break;
1973 1972 }
1974 1973 if (tb->cflags & CF_LAST_IO)
1975 1974 gen_io_end();
... ...
target-sparc/translate.c
... ... @@ -4838,7 +4838,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4838 4838 break;
4839 4839 /* if single step mode, we generate only one instruction and
4840 4840 generate an exception */
4841   - if (env->singlestep_enabled) {
  4841 + if (env->singlestep_enabled || singlestep) {
4842 4842 tcg_gen_movi_tl(cpu_pc, dc->pc);
4843 4843 tcg_gen_exit_tb(0);
4844 4844 break;
... ...
... ... @@ -236,6 +236,7 @@ int win2k_install_hack = 0;
236 236 int rtc_td_hack = 0;
237 237 #endif
238 238 int usb_enabled = 0;
  239 +int singlestep = 0;
239 240 int smp_cpus = 1;
240 241 const char *vnc_display;
241 242 int acpi_enabled = 1;
... ... @@ -4660,6 +4661,9 @@ int main(int argc, char **argv, char **envp)
4660 4661 case QEMU_OPTION_bios:
4661 4662 bios_name = optarg;
4662 4663 break;
  4664 + case QEMU_OPTION_singlestep:
  4665 + singlestep = 1;
  4666 + break;
4663 4667 case QEMU_OPTION_S:
4664 4668 autostart = 0;
4665 4669 break;
... ...