Add new command line option for tcg single stepping. This replaces a compile time options 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 Index: trunk/target-sh4/translate.c =================================================================== --- trunk.orig/target-sh4/translate.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/target-sh4/translate.c 2008-12-20 15:22:48.000000000 +0100 @@ -17,22 +17,18 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include + #include #define DEBUG_DISAS #define SH4_DEBUG_DISAS -//#define SH4_SINGLE_STEP +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" -#include "qemu-common.h" #include "helper.h" #define GEN_HELPER 1 @@ -1882,9 +1878,8 @@ break; if (num_insns >= max_insns) break; -#ifdef SH4_SINGLE_STEP - break; -#endif + if (vm_singlestep) + break; } if (tb->cflags & CF_LAST_IO) gen_io_end(); Index: trunk/target-cris/translate.c =================================================================== --- trunk.orig/target-cris/translate.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/target-cris/translate.c 2008-12-20 16:23:09.000000000 +0100 @@ -24,20 +24,16 @@ * The condition code translation is in need of attention. */ -#include -#include -#include -#include -#include #include +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" #include "helper.h" #include "crisv32-decode.h" -#include "qemu-common.h" #define GEN_HELPER 1 #include "helper.h" @@ -3379,6 +3375,7 @@ break; } while (!dc->is_jmp && !dc->cpustate_changed && gen_opc_ptr < gen_opc_end + && !vm_singlestep && (dc->pc < next_page_start) && num_insns < max_insns); Index: trunk/target-alpha/translate.c =================================================================== --- trunk.orig/target-alpha/translate.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/target-alpha/translate.c 2008-12-20 15:22:48.000000000 +0100 @@ -18,22 +18,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include - +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" #include "host-utils.h" +#include "sysemu.h" #include "tcg-op.h" -#include "qemu-common.h" #include "helper.h" #define GEN_HELPER 1 #include "helper.h" -/* #define DO_SINGLE_STEP */ #define ALPHA_DEBUG_DISAS /* #define DO_TB_FLUSH */ @@ -2414,11 +2410,10 @@ if (env->singlestep_enabled) { gen_excp(&ctx, EXCP_DEBUG, 0); break; - } + } -#if defined (DO_SINGLE_STEP) - break; -#endif + if (vm_singlestep) + break; } if (ret != 1 && ret != 3) { tcg_gen_movi_i64(cpu_pc, ctx.pc); Index: trunk/linux-user/main.c =================================================================== --- trunk.orig/linux-user/main.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/linux-user/main.c 2008-12-20 15:22:48.000000000 +0100 @@ -2271,6 +2271,8 @@ } cpu_set_log(mask); } else if (!strcmp(r, "s")) { + if (optind >= argc) + break; r = argv[optind++]; x86_stack_size = strtol(r, (char **)&r, 0); if (x86_stack_size <= 0) @@ -2282,6 +2284,8 @@ } else if (!strcmp(r, "L")) { interp_prefix = argv[optind++]; } else if (!strcmp(r, "p")) { + if (optind >= argc) + break; qemu_host_page_size = atoi(argv[optind++]); if (qemu_host_page_size == 0 || (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { @@ -2289,12 +2293,14 @@ exit(1); } } else if (!strcmp(r, "g")) { + if (optind >= argc) + break; gdbstub_port = atoi(argv[optind++]); } else if (!strcmp(r, "r")) { qemu_uname_release = argv[optind++]; } else if (!strcmp(r, "cpu")) { cpu_model = argv[optind++]; - if (strcmp(cpu_model, "?") == 0) { + if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) { /* XXX: implement xxx_cpu_list for targets that still miss it */ #if defined(cpu_list) cpu_list(stdout, &fprintf); Index: trunk/vl.c =================================================================== --- trunk.orig/vl.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/vl.c 2008-12-20 15:22:48.000000000 +0100 @@ -189,6 +189,7 @@ int nb_nics; NICInfo nd_table[MAX_NICS]; int vm_running; +int vm_singlestep; static int rtc_utc = 1; static int rtc_date_offset = -1; /* -1 means no change */ int cirrus_vga_enabled = 1; @@ -3933,6 +3934,7 @@ "-serial dev redirect the serial port to char device 'dev'\n" "-parallel dev redirect the parallel port to char device 'dev'\n" "-pidfile file Write PID to 'file'\n" + "-singlestep always run in singlestep mode\n" "-S freeze CPU at startup (use 'c' to start execution)\n" "-s wait gdb connection to port\n" "-p port set gdb connection port [default=%s]\n" @@ -4031,6 +4033,7 @@ QEMU_OPTION_append, QEMU_OPTION_initrd, + QEMU_OPTION_singlestep, QEMU_OPTION_S, QEMU_OPTION_s, QEMU_OPTION_p, @@ -4132,6 +4135,7 @@ { "append", HAS_ARG, QEMU_OPTION_append }, { "initrd", HAS_ARG, QEMU_OPTION_initrd }, + { "singlestep", 0, QEMU_OPTION_singlestep }, { "S", 0, QEMU_OPTION_S }, { "s", 0, QEMU_OPTION_s }, { "p", HAS_ARG, QEMU_OPTION_p }, @@ -4874,6 +4878,9 @@ case QEMU_OPTION_bios: bios_name = optarg; break; + case QEMU_OPTION_singlestep: + vm_singlestep = 1; + break; case QEMU_OPTION_S: autostart = 0; break; Index: trunk/target-ppc/translate.c =================================================================== --- trunk.orig/target-ppc/translate.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/target-ppc/translate.c 2008-12-20 15:22:48.000000000 +0100 @@ -17,17 +17,13 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" -#include "qemu-common.h" #include "helper.h" #define GEN_HELPER 1 @@ -38,7 +34,6 @@ #define GDBSTUB_SINGLE_STEP 0x4 /* Include definitions for instructions classes and implementations flags */ -//#define DO_SINGLE_STEP //#define PPC_DEBUG_DISAS //#define DO_PPC_STATISTICS @@ -7902,9 +7897,9 @@ */ break; } -#if defined (DO_SINGLE_STEP) - break; -#endif + + if (vm_singlestep) + break; } if (tb->cflags & CF_LAST_IO) gen_io_end(); Index: trunk/target-mips/translate.c =================================================================== --- trunk.orig/target-mips/translate.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/target-mips/translate.c 2008-12-20 15:22:48.000000000 +0100 @@ -20,17 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include - +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" -#include "qemu-common.h" #include "helper.h" #define GEN_HELPER 1 @@ -38,7 +33,6 @@ //#define MIPS_DEBUG_DISAS //#define MIPS_DEBUG_SIGN_EXTENSIONS -//#define MIPS_SINGLE_STEP /* MIPS major opcodes */ #define MASK_OP_MAJOR(op) (op & (0x3F << 26)) @@ -8330,9 +8324,9 @@ if (num_insns >= max_insns) break; -#if defined (MIPS_SINGLE_STEP) - break; -#endif + + if (vm_singlestep) + break; } if (tb->cflags & CF_LAST_IO) gen_io_end(); Index: trunk/monitor.c =================================================================== --- trunk.orig/monitor.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/monitor.c 2008-12-20 16:11:21.000000000 +0100 @@ -489,6 +489,18 @@ cpu_set_log(mask); } +static void do_singlestep(const char *option) +{ + qemu_printf("setting vm_singlestep to %s\n", option); + if (!option) { + vm_singlestep = 1; + } else if (!strcmp(option, "off")) { + vm_singlestep = 0; + } else { + term_printf("unexpected option %s\n", option); + } +} + static void do_stop(void) { vm_stop(EXCP_INTERRUPT); @@ -1403,9 +1415,13 @@ static void do_info_status(void) { - if (vm_running) - term_printf("VM status: running\n"); - else + if (vm_running) { + if (vm_singlestep) { + term_printf("VM status: running (single step mode)\n"); + } else { + term_printf("VM status: running\n"); + } + } else term_printf("VM status: paused\n"); } @@ -1454,6 +1470,8 @@ "tag|id", "restore a VM snapshot from its tag or id" }, { "delvm", "s", do_delvm, "tag|id", "delete a VM snapshot from its tag or id" }, + { "singlestep", "s?", do_singlestep, + "[off]", "run emulation in singlestep mode or switch to normal mode", }, { "stop", "", do_stop, "", "stop emulation", }, { "c|cont", "", do_cont, Index: trunk/sysemu.h =================================================================== --- trunk.orig/sysemu.h 2008-12-20 15:21:44.000000000 +0100 +++ trunk/sysemu.h 2008-12-20 16:48:39.000000000 +0100 @@ -6,7 +6,13 @@ extern const char *bios_name; extern const char *bios_dir; +#if defined(CONFIG_USER_ONLY) +# define vm_singlestep 0 +#else extern int vm_running; +extern int vm_singlestep; +#endif + extern const char *qemu_name; extern uint8_t qemu_uuid[]; #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" Index: trunk/target-i386/translate.c =================================================================== --- trunk.orig/target-i386/translate.c 2008-12-20 15:21:44.000000000 +0100 +++ trunk/target-i386/translate.c 2008-12-20 15:22:49.000000000 +0100 @@ -17,17 +17,14 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include -#include + #include +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" #include "helper.h" @@ -7661,6 +7658,11 @@ gen_eob(dc); break; } + if (vm_singlestep) { + gen_jmp_im(pc_ptr - dc->cs_base); + gen_eob(dc); + break; + } } if (tb->cflags & CF_LAST_IO) gen_io_end(); Index: trunk/target-arm/translate.c =================================================================== --- trunk.orig/target-arm/translate.c 2008-12-20 15:23:04.000000000 +0100 +++ trunk/target-arm/translate.c 2008-12-20 16:21:54.000000000 +0100 @@ -19,15 +19,12 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" #include "qemu-log.h" @@ -8788,7 +8785,7 @@ * ensures prefetch aborts occur at the right place. */ num_insns ++; } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !env->singlestep_enabled && !vm_singlestep && dc->pc < next_page_start && num_insns < max_insns); Index: trunk/target-m68k/translate.c =================================================================== --- trunk.orig/target-m68k/translate.c 2008-12-20 15:23:13.000000000 +0100 +++ trunk/target-m68k/translate.c 2008-12-20 16:24:30.000000000 +0100 @@ -18,17 +18,15 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include + #include +#include "qemu-common.h" #include "config.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" +#include "sysemu.h" #include "tcg-op.h" #include "qemu-log.h" @@ -3028,7 +3026,7 @@ disas_m68k_insn(env, dc); num_insns++; } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !env->singlestep_enabled && !vm_singlestep && (pc_offset) < (TARGET_PAGE_SIZE - 32) && num_insns < max_insns); Index: trunk/target-sparc/translate.c =================================================================== --- trunk.orig/target-sparc/translate.c 2008-12-20 15:23:28.000000000 +0100 +++ trunk/target-sparc/translate.c 2008-12-20 16:38:07.000000000 +0100 @@ -19,16 +19,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include -#include - +#include "qemu-common.h" #include "cpu.h" #include "exec-all.h" #include "disas.h" #include "helper.h" +#include "sysemu.h" #include "tcg-op.h" #define GEN_HELPER 1 @@ -4859,7 +4855,7 @@ break; /* if single step mode, we generate only one instruction and generate an exception */ - if (env->singlestep_enabled) { + if (env->singlestep_enabled || vm_singlestep) { tcg_gen_movi_tl(cpu_pc, dc->pc); tcg_gen_exit_tb(0); break; Index: trunk/qemu-doc.texi =================================================================== --- trunk.orig/qemu-doc.texi 2008-12-20 15:24:53.000000000 +0100 +++ trunk/qemu-doc.texi 2008-12-20 16:13:57.000000000 +0100 @@ -1027,6 +1027,8 @@ to specify a TCP port, or a host device (same devices as the serial port). @item -S Do not start CPU at startup (you must type 'c' in the monitor). +@item -singlestep +Run the emulation in single step mode. @item -d Output log in /tmp/qemu.log @item -hdachs @var{c},@var{h},@var{s},[,@var{t}] @@ -1306,6 +1308,10 @@ @item delvm @var{tag}|@var{id} Delete the snapshot identified by @var{tag} or @var{id}. +@item singlestep [off] +Run the emulation in single step mode. +If called with option off, the emulation returns to normal mode. + @item stop Stop emulation.