[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