aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-05 20:08:59 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-05 20:08:59 +0000
commit1b530a6dfcfe4510f66cb90a1717698063ac7a4f (patch)
tree43c8336cbbd0c165cbde16898c76e9cb078a9b60
parent79d342dc6bc04c3bc4c1141760ad6e241059b139 (diff)
downloadqemu-1b530a6dfcfe4510f66cb90a1717698063ac7a4f.zip
qemu-1b530a6dfcfe4510f66cb90a1717698063ac7a4f.tar.gz
qemu-1b530a6dfcfe4510f66cb90a1717698063ac7a4f.tar.bz2
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
-rw-r--r--bsd-user/main.c5
-rw-r--r--darwin-user/main.c5
-rw-r--r--exec-all.h4
-rw-r--r--linux-user/main.c5
-rw-r--r--monitor.c23
-rw-r--r--qemu-doc.texi10
-rw-r--r--qemu-options.hx7
-rw-r--r--target-alpha/translate.c8
-rw-r--r--target-arm/translate.c1
-rw-r--r--target-cris/translate.c1
-rw-r--r--target-i386/translate.c5
-rw-r--r--target-m68k/translate.c1
-rw-r--r--target-mips/translate.c7
-rw-r--r--target-ppc/translate.c5
-rw-r--r--target-sh4/translate.c5
-rw-r--r--target-sparc/translate.c2
-rw-r--r--vl.c4
17 files changed, 79 insertions, 19 deletions
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0dc9b99..34a6b07 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -33,6 +33,8 @@
#define DEBUG_LOGFILE "/tmp/qemu.log"
+int singlestep;
+
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
extern char **environ;
@@ -378,6 +380,7 @@ static void usage(void)
"Debug options:\n"
"-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n"
+ "-singlestep always run in singlestep mode\n"
"-strace log system calls\n"
"\n"
"Environment variables:\n"
@@ -500,6 +503,8 @@ int main(int argc, char **argv)
usage();
}
optind++;
+ } else if (!strcmp(r, "singlestep")) {
+ singlestep = 1;
} else if (!strcmp(r, "strace")) {
do_strace = 1;
} else
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 9b8a3dc..51c6aa0 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -41,6 +41,8 @@
#include <mach/mach_init.h>
#include <mach/vm_map.h>
+int singlestep;
+
const char *interp_prefix = "";
asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
@@ -751,6 +753,7 @@ void usage(void)
"-d options activate log (logfile='%s')\n"
"-g wait for gdb on port 1234\n"
"-p pagesize set the host page size to 'pagesize'\n",
+ "-singlestep always run in singlestep mode\n"
TARGET_ARCH,
TARGET_ARCH,
interp_prefix,
@@ -842,6 +845,8 @@ int main(int argc, char **argv)
#endif
exit(1);
}
+ } else if (!strcmp(r, "singlestep")) {
+ singlestep = 1;
} else
{
usage();
diff --git a/exec-all.h b/exec-all.h
index 143aca1..33ccb7b 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -384,4 +384,8 @@ static inline int kqemu_is_ok(CPUState *env)
typedef void (CPUDebugExcpHandler)(CPUState *env);
CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
+
+/* vl.c */
+extern int singlestep;
+
#endif
diff --git a/linux-user/main.c b/linux-user/main.c
index feb3036..3b9dfc7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -39,6 +39,8 @@
char *exec_path;
+int singlestep;
+
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
@@ -2217,6 +2219,7 @@ static void usage(void)
"Debug options:\n"
"-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n"
+ "-singlestep always run in singlestep mode\n"
"-strace log system calls\n"
"\n"
"Environment variables:\n"
@@ -2359,6 +2362,8 @@ int main(int argc, char **argv, char **envp)
}
} else if (!strcmp(r, "drop-ld-preload")) {
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
+ } else if (!strcmp(r, "singlestep")) {
+ singlestep = 1;
} else if (!strcmp(r, "strace")) {
do_strace = 1;
} else
diff --git a/monitor.c b/monitor.c
index 75c8663..ca1c11c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -527,6 +527,17 @@ static void do_log(Monitor *mon, const char *items)
cpu_set_log(mask);
}
+static void do_singlestep(Monitor *mon, const char *option)
+{
+ if (!option || !strcmp(option, "on")) {
+ singlestep = 1;
+ } else if (!strcmp(option, "off")) {
+ singlestep = 0;
+ } else {
+ monitor_printf(mon, "unexpected option %s\n", option);
+ }
+}
+
static void do_stop(Monitor *mon)
{
vm_stop(EXCP_INTERRUPT);
@@ -1511,9 +1522,13 @@ static void do_inject_nmi(Monitor *mon, int cpu_index)
static void do_info_status(Monitor *mon)
{
- if (vm_running)
- monitor_printf(mon, "VM status: running\n");
- else
+ if (vm_running) {
+ if (singlestep) {
+ monitor_printf(mon, "VM status: running (single step mode)\n");
+ } else {
+ monitor_printf(mon, "VM status: running\n");
+ }
+ } else
monitor_printf(mon, "VM status: paused\n");
}
@@ -1644,6 +1659,8 @@ static const mon_cmd_t mon_cmds[] = {
"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,
+ "[on|off]", "run emulation in singlestep mode or switch to normal mode", },
{ "stop", "", do_stop,
"", "stop emulation", },
{ "c|cont", "", do_cont,
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 61a08ee..3742b45 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -490,6 +490,10 @@ Set the whole virtual machine to the snapshot identified by the tag
@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.
@@ -2370,6 +2374,8 @@ Activate log (logfile=/tmp/qemu.log)
Act as if the host page size was 'pagesize' bytes
@item -g port
Wait gdb connection to port
+@item -singlestep
+Run the emulation in single step mode.
@end table
Environment variables:
@@ -2488,6 +2494,8 @@ Debug options:
Activate log (logfile=/tmp/qemu.log)
@item -p pagesize
Act as if the host page size was 'pagesize' bytes
+@item -singlestep
+Run the emulation in single step mode.
@end table
@node BSD User space emulator
@@ -2550,6 +2558,8 @@ Debug options:
Activate log (logfile=/tmp/qemu.log)
@item -p pagesize
Act as if the host page size was 'pagesize' bytes
+@item -singlestep
+Run the emulation in single step mode.
@end table
@node compilation
diff --git a/qemu-options.hx b/qemu-options.hx
index 51593a3..4c7012e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1209,6 +1209,13 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
from a script.
ETEXI
+DEF("singlestep", 0, QEMU_OPTION_singlestep, \
+ "-singlestep always run in singlestep mode\n")
+STEXI
+@item -singlestep
+Run the emulation in single step mode.
+ETEXI
+
DEF("S", 0, QEMU_OPTION_S, \
"-S freeze CPU at startup (use 'c' to start execution)\n")
STEXI
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 6156fb5..1e1da54 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2412,11 +2412,11 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
if (env->singlestep_enabled) {
gen_excp(&ctx, EXCP_DEBUG, 0);
break;
- }
+ }
-#if defined (DO_SINGLE_STEP)
- break;
-#endif
+ if (singlestep) {
+ break;
+ }
}
if (ret != 1 && ret != 3) {
tcg_gen_movi_i64(cpu_pc, ctx.pc);
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f7f2a8d..9aff619 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8791,6 +8791,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
num_insns ++;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled &&
+ !singlestep &&
dc->pc < next_page_start &&
num_insns < max_insns);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index d5fcb9e..d9256ca 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3272,6 +3272,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
break;
} while (!dc->is_jmp && !dc->cpustate_changed
&& gen_opc_ptr < gen_opc_end
+ && !singlestep
&& (dc->pc < next_page_start)
&& num_insns < max_insns);
diff --git a/target-i386/translate.c b/target-i386/translate.c
index cd2e326..8df3ea4 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7733,6 +7733,11 @@ static inline void gen_intermediate_code_internal(CPUState *env,
gen_eob(dc);
break;
}
+ if (singlestep) {
+ gen_jmp_im(pc_ptr - dc->cs_base);
+ gen_eob(dc);
+ break;
+ }
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 4e3cf4a..f9b36c9 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3031,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
num_insns++;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled &&
+ !singlestep &&
(pc_offset) < (TARGET_PAGE_SIZE - 32) &&
num_insns < max_insns);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 8adc89c..47a3062 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -38,7 +38,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))
@@ -8140,9 +8139,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
if (num_insns >= max_insns)
break;
-#if defined (MIPS_SINGLE_STEP)
- break;
-#endif
+
+ if (singlestep)
+ break;
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 870aec5..9ba4937 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -39,7 +39,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
@@ -8288,15 +8287,13 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
gen_exception(ctxp, POWERPC_EXCP_TRACE);
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
(env->singlestep_enabled) ||
+ singlestep ||
num_insns >= max_insns)) {
/* if we reach a page boundary or are single stepping, stop
* generation
*/
break;
}
-#if defined (DO_SINGLE_STEP)
- break;
-#endif
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 4ced176..aa3b9d4 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1967,9 +1967,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
break;
if (num_insns >= max_insns)
break;
-#ifdef SH4_SINGLE_STEP
- break;
-#endif
+ if (singlestep)
+ break;
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d059408..86319a7 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4838,7 +4838,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
break;
/* if single step mode, we generate only one instruction and
generate an exception */
- if (env->singlestep_enabled) {
+ if (env->singlestep_enabled || singlestep) {
tcg_gen_movi_tl(cpu_pc, dc->pc);
tcg_gen_exit_tb(0);
break;
diff --git a/vl.c b/vl.c
index b294380..4bd173f 100644
--- a/vl.c
+++ b/vl.c
@@ -236,6 +236,7 @@ int win2k_install_hack = 0;
int rtc_td_hack = 0;
#endif
int usb_enabled = 0;
+int singlestep = 0;
int smp_cpus = 1;
const char *vnc_display;
int acpi_enabled = 1;
@@ -4660,6 +4661,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_bios:
bios_name = optarg;
break;
+ case QEMU_OPTION_singlestep:
+ singlestep = 1;
+ break;
case QEMU_OPTION_S:
autostart = 0;
break;