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