- qemu CVS, without using the kqemu module

- Solaris x86 guest

- I'm trying to debug a user program inside the Solaris x86 guest:

  $ mdb /bin/date
  > main:b
  > :r

  (note: mdb uses a breakpoint inside the target's dynamic linker
  ld.so.1 and single steps over that breakpoint during target
  program startup)




When kqemu isn't available, single stepping a user programm in the
/bin/mdb debugger in a Solaris x86 guest doesn't work.

The Solaris x86 kernel verifies that the "BS (single step) flag (bit
14)" in the DR6 debug status register is set when a user
program gets an exception #1 (EXCP01_SSTP).

qemu currently doesn't set this bit for exception #1 (EXCP01_SSTP).

The Solaris x86 kernel complains with the message:
    Unexpected INT 1 in user mode, dr6=0

At this point the Solaris x86 guest kernel is stuck in an endless
loop with "Unexpected INT 1 in user mode, dr6=0" messages.


Workaround:
===========

For the x86 platform only: use the kqemu module.


Suggested fix:
==============

Set the 0x4000 bit in DR6 when single stepping.

See the attached patch.  With this patch applied, debugging a user
program works.
diff -ru /tmp/qemu-cvs/target-i386/exec.h qemu-cvs/target-i386/exec.h
--- /tmp/qemu-cvs/target-i386/exec.h    2006-09-25 09:52:23.000000000 +0200
+++ qemu-cvs/target-i386/exec.h 2007-03-10 21:20:22.804313251 +0100
@@ -191,6 +191,7 @@
 void helper_idivq_EAX_T0(void);
 void helper_bswapq_T0(void);
 void helper_cmpxchg8b(void);
+void helper_single_step(void);
 void helper_cpuid(void);
 void helper_enter_level(int level, int data32);
 void helper_enter64_level(int level, int data64);
diff -ru /tmp/qemu-cvs/target-i386/helper.c qemu-cvs/target-i386/helper.c
--- /tmp/qemu-cvs/target-i386/helper.c  2007-02-09 22:10:08.000000000 +0100
+++ qemu-cvs/target-i386/helper.c       2007-03-10 21:13:09.708272230 +0100
@@ -1591,6 +1591,12 @@
     CC_SRC = eflags;
 }
 
+void helper_single_step()
+{
+    env->dr[6] |= 0x4000;
+    raise_exception(EXCP01_SSTP);
+}
+
 void helper_cpuid(void)
 {
     uint32_t index;
diff -ru /tmp/qemu-cvs/target-i386/op.c qemu-cvs/target-i386/op.c
--- /tmp/qemu-cvs/target-i386/op.c      2007-02-09 22:10:08.000000000 +0100
+++ qemu-cvs/target-i386/op.c   2007-03-10 21:20:53.276293877 +0100
@@ -730,6 +730,11 @@
     helper_cmpxchg8b();
 }
 
+void OPPROTO op_single_step(void)
+{
+    helper_single_step();
+}
+
 void OPPROTO op_movl_T0_0(void)
 {
     T0 = 0;
diff -ru /tmp/qemu-cvs/target-i386/translate.c qemu-cvs/target-i386/translate.c
--- /tmp/qemu-cvs/target-i386/translate.c       2007-01-24 10:07:52.000000000 
+0100
+++ qemu-cvs/target-i386/translate.c    2007-03-10 21:49:06.287293924 +0100
@@ -2277,7 +2277,7 @@
     if (s->singlestep_enabled) {
         gen_op_debug();
     } else if (s->tf) {
-        gen_op_raise_exception(EXCP01_SSTP);
+       gen_op_single_step();
     } else {
         gen_op_movl_T0_0();
         gen_op_exit_tb();
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to