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
This commit is contained in:
aurel32 2009-04-05 20:08:59 +00:00
parent 79d342dc6b
commit 1b530a6dfc
17 changed files with 79 additions and 19 deletions

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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;

4
vl.c
View File

@ -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;