Commit 1b530a6dfcfe4510f66cb90a1717698063ac7a4f
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
Showing
17 changed files
with
79 additions
and
19 deletions
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; | ... | ... |
vl.c
... | ... | @@ -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; | ... | ... |