Commit 34865134335df669132f9c2ed12d1e0be361f30f

Authored by bellard
1 parent 0806e3f6

log activation from gdb - gdb single step support for x86 - stop timer when cpu is being debugged


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@402 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
... ... @@ -377,6 +377,10 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
377 377 int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
378 378 void cpu_single_step(CPUState *env, int enabled);
379 379  
  380 +#define CPU_LOG_ALL 1
  381 +void cpu_set_log(int log_flags);
  382 +void cpu_set_log_filename(const char *filename);
  383 +
380 384 /* memory API */
381 385  
382 386 typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
... ...
... ... @@ -78,6 +78,11 @@ CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
78 78 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
79 79 static int io_mem_nb;
80 80  
  81 +/* log support */
  82 +char *logfilename = "/tmp/qemu.log";
  83 +FILE *logfile;
  84 +int loglevel;
  85 +
81 86 static void page_init(void)
82 87 {
83 88 /* NOTE: we can always suppose that host_page_size >=
... ... @@ -676,6 +681,24 @@ void cpu_single_step(CPUState *env, int enabled)
676 681 #endif
677 682 }
678 683  
  684 +/* enable or disable low levels log */
  685 +void cpu_set_log(int log_flags)
  686 +{
  687 + loglevel = log_flags;
  688 + if (loglevel && !logfile) {
  689 + logfile = fopen(logfilename, "w");
  690 + if (!logfile) {
  691 + perror(logfilename);
  692 + _exit(1);
  693 + }
  694 + setvbuf(logfile, NULL, _IOLBF, 0);
  695 + }
  696 +}
  697 +
  698 +void cpu_set_log_filename(const char *filename)
  699 +{
  700 + logfilename = strdup(filename);
  701 +}
679 702  
680 703 /* mask must never be zero */
681 704 void cpu_interrupt(CPUState *env, int mask)
... ...
gdbstub.c
... ... @@ -437,7 +437,24 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
437 437 goto breakpoint_error;
438 438 }
439 439 break;
  440 + case 'Q':
  441 + if (!strncmp(p, "Tinit", 5)) {
  442 + /* init traces */
  443 + put_packet("OK");
  444 + } else if (!strncmp(p, "TStart", 6)) {
  445 + /* start log (gdb 'tstart' command) */
  446 + cpu_set_log(CPU_LOG_ALL);
  447 + put_packet("OK");
  448 + } else if (!strncmp(p, "TStop", 5)) {
  449 + /* stop log (gdb 'tstop' command) */
  450 + cpu_set_log(0);
  451 + put_packet("OK");
  452 + } else {
  453 + goto unknown_command;
  454 + }
  455 + break;
440 456 default:
  457 + unknown_command:
441 458 /* put empty packet */
442 459 buf[0] = '\0';
443 460 put_packet(buf);
... ...
target-i386/translate.c
... ... @@ -60,6 +60,7 @@ typedef struct DisasContext {
60 60 int cpl;
61 61 int iopl;
62 62 int tf; /* TF cpu flag */
  63 + int singlestep_enabled; /* "hardware" single step enabled */
63 64 int jmp_opt; /* use direct block chaining for direct jumps */
64 65 int mem_index; /* select memory access functions */
65 66 struct TranslationBlock *tb;
... ... @@ -1712,7 +1713,9 @@ static void gen_eob(DisasContext *s)
1712 1713 {
1713 1714 if (s->cc_op != CC_OP_DYNAMIC)
1714 1715 gen_op_set_cc_op(s->cc_op);
1715   - if (s->tf) {
  1716 + if (s->singlestep_enabled) {
  1717 + gen_op_debug();
  1718 + } else if (s->tf) {
1716 1719 gen_op_raise_exception(EXCP01_SSTP);
1717 1720 } else {
1718 1721 gen_op_movl_T0_0();
... ... @@ -4368,6 +4371,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4368 4371 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
4369 4372 dc->iopl = (flags >> IOPL_SHIFT) & 3;
4370 4373 dc->tf = (flags >> TF_SHIFT) & 1;
  4374 + dc->singlestep_enabled = env->singlestep_enabled;
4371 4375 dc->cc_op = CC_OP_DYNAMIC;
4372 4376 dc->cs_base = cs_base;
4373 4377 dc->tb = tb;
... ... @@ -4425,7 +4429,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4425 4429 break;
4426 4430 /* if single step mode, we generate only one instruction and
4427 4431 generate an exception */
4428   - if (dc->tf) {
  4432 + if (dc->tf || dc->singlestep_enabled) {
4429 4433 gen_op_jmp_im(pc_ptr - dc->cs_base);
4430 4434 gen_eob(dc);
4431 4435 break;
... ...
... ... @@ -50,7 +50,6 @@
50 50  
51 51 #include "vl.h"
52 52  
53   -#define DEBUG_LOGFILE "/tmp/vl.log"
54 53 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
55 54 #define BIOS_FILENAME "bios.bin"
56 55 #define VGABIOS_FILENAME "vgabios.bin"
... ... @@ -209,8 +208,6 @@ static const char *bios_dir = CONFIG_QEMU_SHAREDIR;
209 208 char phys_ram_file[1024];
210 209 CPUX86State *global_env;
211 210 CPUX86State *cpu_single_env;
212   -FILE *logfile = NULL;
213   -int loglevel;
214 211 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
215 212 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
216 213 BlockDriverState *bs_table[MAX_DISKS];
... ... @@ -832,20 +829,76 @@ int speaker_data_on;
832 829 int dummy_refresh_clock;
833 830 int pit_min_timer_count = 0;
834 831  
835   -int64_t get_clock(void)
  832 +
  833 +#if defined(__powerpc__)
  834 +
  835 +static inline uint32_t get_tbl(void)
836 836 {
837   - struct timeval tv;
838   - gettimeofday(&tv, NULL);
839   - return tv.tv_sec * 1000000LL + tv.tv_usec;
  837 + uint32_t tbl;
  838 + asm volatile("mftb %0" : "=r" (tbl));
  839 + return tbl;
840 840 }
841 841  
842   -int64_t cpu_get_ticks(void)
  842 +static inline uint32_t get_tbu(void)
  843 +{
  844 + uint32_t tbl;
  845 + asm volatile("mftbu %0" : "=r" (tbl));
  846 + return tbl;
  847 +}
  848 +
  849 +int64_t cpu_get_real_ticks(void)
  850 +{
  851 + uint32_t l, h, h1;
  852 + /* NOTE: we test if wrapping has occurred */
  853 + do {
  854 + h = get_tbu();
  855 + l = get_tbl();
  856 + h1 = get_tbu();
  857 + } while (h != h1);
  858 + return ((int64_t)h << 32) | l;
  859 +}
  860 +
  861 +#elif defined(__i386__)
  862 +
  863 +int64_t cpu_get_real_ticks(void)
843 864 {
844 865 int64_t val;
845 866 asm("rdtsc" : "=A" (val));
846 867 return val;
847 868 }
848 869  
  870 +#else
  871 +#error unsupported CPU
  872 +#endif
  873 +
  874 +static int64_t cpu_ticks_offset;
  875 +static int64_t cpu_ticks_last;
  876 +
  877 +int64_t cpu_get_ticks(void)
  878 +{
  879 + return cpu_get_real_ticks() + cpu_ticks_offset;
  880 +}
  881 +
  882 +/* enable cpu_get_ticks() */
  883 +void cpu_enable_ticks(void)
  884 +{
  885 + cpu_ticks_offset = cpu_ticks_last - cpu_get_real_ticks();
  886 +}
  887 +
  888 +/* disable cpu_get_ticks() : the clock is stopped. You must not call
  889 + cpu_get_ticks() after that. */
  890 +void cpu_disable_ticks(void)
  891 +{
  892 + cpu_ticks_last = cpu_get_ticks();
  893 +}
  894 +
  895 +int64_t get_clock(void)
  896 +{
  897 + struct timeval tv;
  898 + gettimeofday(&tv, NULL);
  899 + return tv.tv_sec * 1000000LL + tv.tv_usec;
  900 +}
  901 +
849 902 void cpu_calibrate_ticks(void)
850 903 {
851 904 int64_t usec, ticks;
... ... @@ -3297,12 +3350,17 @@ int main_loop(void *opaque)
3297 3350 }
3298 3351  
3299 3352 serial_ok = 1;
  3353 + cpu_enable_ticks();
3300 3354 for(;;) {
3301 3355 ret = cpu_x86_exec(env);
3302   - if (reset_requested)
  3356 + if (reset_requested) {
  3357 + ret = EXCP_INTERRUPT;
3303 3358 break;
3304   - if (ret == EXCP_DEBUG)
3305   - return EXCP_DEBUG;
  3359 + }
  3360 + if (ret == EXCP_DEBUG) {
  3361 + ret = EXCP_DEBUG;
  3362 + break;
  3363 + }
3306 3364 /* if hlt instruction, we wait until the next IRQ */
3307 3365 if (ret == EXCP_HLT)
3308 3366 timeout = 10;
... ... @@ -3359,8 +3417,10 @@ int main_loop(void *opaque)
3359 3417 uint8_t buf[1];
3360 3418 /* stop emulation if requested by gdb */
3361 3419 n = read(gdbstub_fd, buf, 1);
3362   - if (n == 1)
  3420 + if (n == 1) {
  3421 + ret = EXCP_INTERRUPT;
3363 3422 break;
  3423 + }
3364 3424 }
3365 3425 }
3366 3426  
... ... @@ -3377,7 +3437,8 @@ int main_loop(void *opaque)
3377 3437 gui_refresh_pending = 0;
3378 3438 }
3379 3439 }
3380   - return EXCP_INTERRUPT;
  3440 + cpu_disable_ticks();
  3441 + return ret;
3381 3442 }
3382 3443  
3383 3444 void help(void)
... ... @@ -3535,7 +3596,7 @@ int main(int argc, char **argv)
3535 3596 }
3536 3597 break;
3537 3598 case 'd':
3538   - loglevel = 1;
  3599 + cpu_set_log(CPU_LOG_ALL);
3539 3600 break;
3540 3601 case 'n':
3541 3602 pstrcpy(network_script, sizeof(network_script), optarg);
... ... @@ -3563,14 +3624,6 @@ int main(int argc, char **argv)
3563 3624  
3564 3625 /* init debug */
3565 3626 setvbuf(stdout, NULL, _IOLBF, 0);
3566   - if (loglevel) {
3567   - logfile = fopen(DEBUG_LOGFILE, "w");
3568   - if (!logfile) {
3569   - perror(DEBUG_LOGFILE);
3570   - _exit(1);
3571   - }
3572   - setvbuf(logfile, NULL, _IOLBF, 0);
3573   - }
3574 3627  
3575 3628 /* init network tun interface */
3576 3629 if (net_fd < 0)
... ...