[PATCH] x86emu: improve single-step debugging

Kees Cook kees at outflux.net
Thu Oct 6 15:36:09 PDT 2011


This allows for other consumers to do single-step decoding/emulation
when using x86emu. Additionally adds a stand-alone Makefile for building
out of tree, which is very handy for doing emulation debugging.

Signed-off-by: Kees Cook <kees at outflux.net>
---
forwarded from https://bugs.freedesktop.org/show_bug.cgi?id=17612

 hw/xfree86/x86emu/debug.c             |    7 ++++++
 hw/xfree86/x86emu/decode.c            |   34 +++++++++++++++++++++-----------
 hw/xfree86/x86emu/makefile.standalone |   13 ++++++++++++
 hw/xfree86/x86emu/x86emu.h            |    1 +
 hw/xfree86/x86emu/x86emu/debug.h      |    3 +-
 hw/xfree86/x86emu/x86emu/regs.h       |    1 +
 6 files changed, 46 insertions(+), 13 deletions(-)
 create mode 100644 hw/xfree86/x86emu/makefile.standalone

diff --git a/hw/xfree86/x86emu/debug.c b/hw/xfree86/x86emu/debug.c
index 5eda908..0c5c784 100644
--- a/hw/xfree86/x86emu/debug.c
+++ b/hw/xfree86/x86emu/debug.c
@@ -177,8 +177,15 @@ void x86emu_decode_printf2 (char *x, int y)
 	M.x86.enc_str_pos += strlen(temp);
 }
 
+void x86emu_start_instr (void)
+{
+	M.x86.inst_len = 0;
+	M.x86.decoded_buf[0]='\0';
+}
+
 void x86emu_end_instr (void)
 {
+	M.x86.inst_len = M.x86.enc_pos;
 	M.x86.enc_str_pos = 0;
 	M.x86.enc_pos = 0;
 }
diff --git a/hw/xfree86/x86emu/decode.c b/hw/xfree86/x86emu/decode.c
index 9339f4c..22a5350 100644
--- a/hw/xfree86/x86emu/decode.c
+++ b/hw/xfree86/x86emu/decode.c
@@ -83,19 +83,13 @@ void x86emu_intr_raise(
 }
 
 /****************************************************************************
-REMARKS:
-Main execution loop for the emulator. We return from here when the system
-halts, which is normally caused by a stack fault when we return from the
-original real mode call.
+perform single instruction step
+returns true/false value to indicate if the system should remain running
 ****************************************************************************/
-void X86EMU_exec(void)
+inline int X86EMU_single_step(void)
 {
 	u8 op1;
 
-	M.x86.intr = 0;
-	DB(x86emu_end_instr();)
-
-    for (;;) {
 DB(		if (CHECK_IP_FETCH())
 		  x86emu_check_ip_access();)
 		/* If debugging, save the IP and CS values. */
@@ -111,7 +105,7 @@ DB(             if (M.x86.R_SP != 0) {
                     if (M.x86.debug)
                         printk("Service completed successfully\n");
                     })
-				return;
+				return 0;
             }
 			if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
 				!ACCESS_FLAG(F_IF)) {
@@ -122,9 +116,25 @@ DB(             if (M.x86.R_SP != 0) {
 		(*x86emu_optab[op1])(op1);
         if (M.x86.debug & DEBUG_EXIT) {
             M.x86.debug &= ~DEBUG_EXIT;
-            return;
+            return 0;
         }
-    }
+
+		return 1;
+}
+
+/****************************************************************************
+REMARKS:
+Main execution loop for the emulator. We return from here when the system
+halts, which is normally caused by a stack fault when we return from the
+original real mode call.
+****************************************************************************/
+void X86EMU_exec(void)
+{
+	M.x86.intr = 0;
+	DB(x86emu_end_instr();)
+
+	do {
+	} while (X86EMU_single_step());
 }
 
 /****************************************************************************
diff --git a/hw/xfree86/x86emu/makefile.standalone b/hw/xfree86/x86emu/makefile.standalone
new file mode 100644
index 0000000..6b594aa
--- /dev/null
+++ b/hw/xfree86/x86emu/makefile.standalone
@@ -0,0 +1,13 @@
+CC=gcc
+CFLAGS=-Wall -I. -DDEBUG
+
+TARGETS = debug.o decode.o fpu.o ops2.o ops.o prim_ops.o sys.o
+
+all: libx86emu.a
+
+libx86emu.a: $(TARGETS)
+	ar -r $@ $(TARGETS)
+
+clean:
+	rm -f $(TARGETS) libx86emu.a
+	
diff --git a/hw/xfree86/x86emu/x86emu.h b/hw/xfree86/x86emu/x86emu.h
index 795e2d6..f16e8ab 100644
--- a/hw/xfree86/x86emu/x86emu.h
+++ b/hw/xfree86/x86emu/x86emu.h
@@ -153,6 +153,7 @@ void 	X86EMU_prepareForInt(int num);
 
 /* decode.c */
 
+inline int X86EMU_single_step(void);
 void 	X86EMU_exec(void);
 void 	X86EMU_halt_sys(void);
 
diff --git a/hw/xfree86/x86emu/x86emu/debug.h b/hw/xfree86/x86emu/x86emu/debug.h
index 47aacb6..6a08b39 100644
--- a/hw/xfree86/x86emu/x86emu/debug.h
+++ b/hw/xfree86/x86emu/x86emu/debug.h
@@ -151,7 +151,7 @@
 	SINGLE_STEP()
 
 #ifdef DEBUG
-# define START_OF_INSTR()
+# define START_OF_INSTR()	x86emu_start_instr();
 # define END_OF_INSTR()		EndOfTheInstructionProcedure: x86emu_end_instr();
 # define END_OF_INSTR_NO_TRACE()	x86emu_end_instr();
 #else
@@ -193,6 +193,7 @@ extern void x86emu_decode_printf (char *x);
 extern void x86emu_decode_printf2 (char *x, int y);
 extern void x86emu_just_disassemble (void);
 extern void x86emu_single_step (void);
+extern void x86emu_start_instr (void);
 extern void x86emu_end_instr (void);
 extern void x86emu_dump_regs (void);
 extern void x86emu_dump_xregs (void);
diff --git a/hw/xfree86/x86emu/x86emu/regs.h b/hw/xfree86/x86emu/x86emu/regs.h
index 52cf8e4..d461804 100644
--- a/hw/xfree86/x86emu/x86emu/regs.h
+++ b/hw/xfree86/x86emu/x86emu/regs.h
@@ -281,6 +281,7 @@ typedef struct {
     u16                         saved_ip;
     u16                         saved_cs;
     int                         enc_pos;
+    int                         inst_len; /* prior instruction length */
     int                         enc_str_pos;
     char                        decode_buf[32]; /* encoded byte stream  */
     char                        decoded_buf[256]; /* disassembled strings */
-- 
1.7.5.4

-- 
Kees Cook                                            @outflux.net


More information about the xorg-devel mailing list