提交 1b530a6d 编写于 作者: A aurel32

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: NStefan Weil <weil@mail.berlios.de>
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7004 c046a42c-6fe2-441c-8c8c-71466251a162
上级 79d342dc
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define DEBUG_LOGFILE "/tmp/qemu.log" #define DEBUG_LOGFILE "/tmp/qemu.log"
int singlestep;
static const char *interp_prefix = CONFIG_QEMU_PREFIX; static const char *interp_prefix = CONFIG_QEMU_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE; const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
extern char **environ; extern char **environ;
...@@ -378,6 +380,7 @@ static void usage(void) ...@@ -378,6 +380,7 @@ static void usage(void)
"Debug options:\n" "Debug options:\n"
"-d options activate log (logfile=%s)\n" "-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n" "-p pagesize set the host page size to 'pagesize'\n"
"-singlestep always run in singlestep mode\n"
"-strace log system calls\n" "-strace log system calls\n"
"\n" "\n"
"Environment variables:\n" "Environment variables:\n"
...@@ -500,6 +503,8 @@ int main(int argc, char **argv) ...@@ -500,6 +503,8 @@ int main(int argc, char **argv)
usage(); usage();
} }
optind++; optind++;
} else if (!strcmp(r, "singlestep")) {
singlestep = 1;
} else if (!strcmp(r, "strace")) { } else if (!strcmp(r, "strace")) {
do_strace = 1; do_strace = 1;
} else } else
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include <mach/mach_init.h> #include <mach/mach_init.h>
#include <mach/vm_map.h> #include <mach/vm_map.h>
int singlestep;
const char *interp_prefix = ""; const char *interp_prefix = "";
asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000"); 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)
"-d options activate log (logfile='%s')\n" "-d options activate log (logfile='%s')\n"
"-g wait for gdb on port 1234\n" "-g wait for gdb on port 1234\n"
"-p pagesize set the host page size to 'pagesize'\n", "-p pagesize set the host page size to 'pagesize'\n",
"-singlestep always run in singlestep mode\n"
TARGET_ARCH, TARGET_ARCH,
TARGET_ARCH, TARGET_ARCH,
interp_prefix, interp_prefix,
...@@ -842,6 +845,8 @@ int main(int argc, char **argv) ...@@ -842,6 +845,8 @@ int main(int argc, char **argv)
#endif #endif
exit(1); exit(1);
} }
} else if (!strcmp(r, "singlestep")) {
singlestep = 1;
} else } else
{ {
usage(); usage();
......
...@@ -384,4 +384,8 @@ static inline int kqemu_is_ok(CPUState *env) ...@@ -384,4 +384,8 @@ static inline int kqemu_is_ok(CPUState *env)
typedef void (CPUDebugExcpHandler)(CPUState *env); typedef void (CPUDebugExcpHandler)(CPUState *env);
CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
/* vl.c */
extern int singlestep;
#endif #endif
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
char *exec_path; char *exec_path;
int singlestep;
static const char *interp_prefix = CONFIG_QEMU_PREFIX; static const char *interp_prefix = CONFIG_QEMU_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE; const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
...@@ -2217,6 +2219,7 @@ static void usage(void) ...@@ -2217,6 +2219,7 @@ static void usage(void)
"Debug options:\n" "Debug options:\n"
"-d options activate log (logfile=%s)\n" "-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n" "-p pagesize set the host page size to 'pagesize'\n"
"-singlestep always run in singlestep mode\n"
"-strace log system calls\n" "-strace log system calls\n"
"\n" "\n"
"Environment variables:\n" "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)
} }
} else if (!strcmp(r, "drop-ld-preload")) { } else if (!strcmp(r, "drop-ld-preload")) {
(void) envlist_unsetenv(envlist, "LD_PRELOAD"); (void) envlist_unsetenv(envlist, "LD_PRELOAD");
} else if (!strcmp(r, "singlestep")) {
singlestep = 1;
} else if (!strcmp(r, "strace")) { } else if (!strcmp(r, "strace")) {
do_strace = 1; do_strace = 1;
} else } else
......
...@@ -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)
cpu_set_log(mask); 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) static void do_stop(Monitor *mon)
{ {
vm_stop(EXCP_INTERRUPT); 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)
static void do_info_status(Monitor *mon) static void do_info_status(Monitor *mon)
{ {
if (vm_running) if (vm_running) {
monitor_printf(mon, "VM status: running\n"); if (singlestep) {
else 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"); monitor_printf(mon, "VM status: paused\n");
} }
...@@ -1644,6 +1659,8 @@ static const mon_cmd_t mon_cmds[] = { ...@@ -1644,6 +1659,8 @@ static const mon_cmd_t mon_cmds[] = {
"tag|id", "restore a VM snapshot from its tag or id" }, "tag|id", "restore a VM snapshot from its tag or id" },
{ "delvm", "s", do_delvm, { "delvm", "s", do_delvm,
"tag|id", "delete a VM snapshot from its tag or id" }, "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", "", do_stop,
"", "stop emulation", }, "", "stop emulation", },
{ "c|cont", "", do_cont, { "c|cont", "", do_cont,
......
...@@ -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
@item delvm @var{tag}|@var{id} @item delvm @var{tag}|@var{id}
Delete the snapshot identified by @var{tag} or @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 @item stop
Stop emulation. Stop emulation.
...@@ -2370,6 +2374,8 @@ Activate log (logfile=/tmp/qemu.log) ...@@ -2370,6 +2374,8 @@ Activate log (logfile=/tmp/qemu.log)
Act as if the host page size was 'pagesize' bytes Act as if the host page size was 'pagesize' bytes
@item -g port @item -g port
Wait gdb connection to port Wait gdb connection to port
@item -singlestep
Run the emulation in single step mode.
@end table @end table
Environment variables: Environment variables:
...@@ -2488,6 +2494,8 @@ Debug options: ...@@ -2488,6 +2494,8 @@ Debug options:
Activate log (logfile=/tmp/qemu.log) Activate log (logfile=/tmp/qemu.log)
@item -p pagesize @item -p pagesize
Act as if the host page size was 'pagesize' bytes Act as if the host page size was 'pagesize' bytes
@item -singlestep
Run the emulation in single step mode.
@end table @end table
@node BSD User space emulator @node BSD User space emulator
...@@ -2550,6 +2558,8 @@ Debug options: ...@@ -2550,6 +2558,8 @@ Debug options:
Activate log (logfile=/tmp/qemu.log) Activate log (logfile=/tmp/qemu.log)
@item -p pagesize @item -p pagesize
Act as if the host page size was 'pagesize' bytes Act as if the host page size was 'pagesize' bytes
@item -singlestep
Run the emulation in single step mode.
@end table @end table
@node compilation @node compilation
......
...@@ -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
from a script. from a script.
ETEXI 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, \ DEF("S", 0, QEMU_OPTION_S, \
"-S freeze CPU at startup (use 'c' to start execution)\n") "-S freeze CPU at startup (use 'c' to start execution)\n")
STEXI STEXI
......
...@@ -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,
if (env->singlestep_enabled) { if (env->singlestep_enabled) {
gen_excp(&ctx, EXCP_DEBUG, 0); gen_excp(&ctx, EXCP_DEBUG, 0);
break; break;
} }
#if defined (DO_SINGLE_STEP) if (singlestep) {
break; break;
#endif }
} }
if (ret != 1 && ret != 3) { if (ret != 1 && ret != 3) {
tcg_gen_movi_i64(cpu_pc, ctx.pc); tcg_gen_movi_i64(cpu_pc, ctx.pc);
......
...@@ -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,
num_insns ++; num_insns ++;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled && !env->singlestep_enabled &&
!singlestep &&
dc->pc < next_page_start && dc->pc < next_page_start &&
num_insns < max_insns); num_insns < max_insns);
......
...@@ -3272,6 +3272,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, ...@@ -3272,6 +3272,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
break; break;
} while (!dc->is_jmp && !dc->cpustate_changed } while (!dc->is_jmp && !dc->cpustate_changed
&& gen_opc_ptr < gen_opc_end && gen_opc_ptr < gen_opc_end
&& !singlestep
&& (dc->pc < next_page_start) && (dc->pc < next_page_start)
&& num_insns < max_insns); && num_insns < max_insns);
......
...@@ -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,
gen_eob(dc); gen_eob(dc);
break; break;
} }
if (singlestep) {
gen_jmp_im(pc_ptr - dc->cs_base);
gen_eob(dc);
break;
}
} }
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO)
gen_io_end(); gen_io_end();
......
...@@ -3031,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, ...@@ -3031,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
num_insns++; num_insns++;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled && !env->singlestep_enabled &&
!singlestep &&
(pc_offset) < (TARGET_PAGE_SIZE - 32) && (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
num_insns < max_insns); num_insns < max_insns);
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
//#define MIPS_DEBUG_DISAS //#define MIPS_DEBUG_DISAS
//#define MIPS_DEBUG_SIGN_EXTENSIONS //#define MIPS_DEBUG_SIGN_EXTENSIONS
//#define MIPS_SINGLE_STEP
/* MIPS major opcodes */ /* MIPS major opcodes */
#define MASK_OP_MAJOR(op) (op & (0x3F << 26)) #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,
if (num_insns >= max_insns) if (num_insns >= max_insns)
break; break;
#if defined (MIPS_SINGLE_STEP)
break; if (singlestep)
#endif break;
} }
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO)
gen_io_end(); gen_io_end();
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#define GDBSTUB_SINGLE_STEP 0x4 #define GDBSTUB_SINGLE_STEP 0x4
/* Include definitions for instructions classes and implementations flags */ /* Include definitions for instructions classes and implementations flags */
//#define DO_SINGLE_STEP
//#define PPC_DEBUG_DISAS //#define PPC_DEBUG_DISAS
//#define DO_PPC_STATISTICS //#define DO_PPC_STATISTICS
...@@ -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,
gen_exception(ctxp, POWERPC_EXCP_TRACE); gen_exception(ctxp, POWERPC_EXCP_TRACE);
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
(env->singlestep_enabled) || (env->singlestep_enabled) ||
singlestep ||
num_insns >= max_insns)) { num_insns >= max_insns)) {
/* if we reach a page boundary or are single stepping, stop /* if we reach a page boundary or are single stepping, stop
* generation * generation
*/ */
break; break;
} }
#if defined (DO_SINGLE_STEP)
break;
#endif
} }
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO)
gen_io_end(); gen_io_end();
......
...@@ -1967,9 +1967,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ...@@ -1967,9 +1967,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
break; break;
if (num_insns >= max_insns) if (num_insns >= max_insns)
break; break;
#ifdef SH4_SINGLE_STEP if (singlestep)
break; break;
#endif
} }
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO)
gen_io_end(); gen_io_end();
......
...@@ -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,
break; break;
/* if single step mode, we generate only one instruction and /* if single step mode, we generate only one instruction and
generate an exception */ generate an exception */
if (env->singlestep_enabled) { if (env->singlestep_enabled || singlestep) {
tcg_gen_movi_tl(cpu_pc, dc->pc); tcg_gen_movi_tl(cpu_pc, dc->pc);
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
break; break;
......
...@@ -236,6 +236,7 @@ int win2k_install_hack = 0; ...@@ -236,6 +236,7 @@ int win2k_install_hack = 0;
int rtc_td_hack = 0; int rtc_td_hack = 0;
#endif #endif
int usb_enabled = 0; int usb_enabled = 0;
int singlestep = 0;
int smp_cpus = 1; int smp_cpus = 1;
const char *vnc_display; const char *vnc_display;
int acpi_enabled = 1; 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)
case QEMU_OPTION_bios: case QEMU_OPTION_bios:
bios_name = optarg; bios_name = optarg;
break; break;
case QEMU_OPTION_singlestep:
singlestep = 1;
break;
case QEMU_OPTION_S: case QEMU_OPTION_S:
autostart = 0; autostart = 0;
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册