[PATCH 1/2] [WineDbg]: added CPU method for identifying a jmp insn, and implement it for i386

Eric Pouech eric.pouech at orange.fr
Sat Jan 8 07:08:56 CST 2011




A+
---

 programs/winedbg/be_alpha.c  |    6 ++++++
 programs/winedbg/be_arm.c    |    6 ++++++
 programs/winedbg/be_cpu.h    |    2 ++
 programs/winedbg/be_i386.c   |   39 +++++++++++++++++++++++++++++++++++++++
 programs/winedbg/be_ppc.c    |    7 +++++++
 programs/winedbg/be_sparc.c  |    6 ++++++
 programs/winedbg/be_x86_64.c |    6 ++++++
 7 files changed, 72 insertions(+), 0 deletions(-)


diff --git a/programs/winedbg/be_alpha.c b/programs/winedbg/be_alpha.c
index 76cddb5..f16952c 100644
--- a/programs/winedbg/be_alpha.c
+++ b/programs/winedbg/be_alpha.c
@@ -77,6 +77,11 @@ static unsigned be_alpha_is_func_call(const void* insn, ADDRESS64* callee)
     return FALSE;
 }
 
+static unsigned be_alpha_is_jump(const void* insn, ADDRESS64* jumpee)
+{
+    return FALSE;
+}
+
 static void be_alpha_disasm_one_insn(ADDRESS64* addr, int display)
 {
     dbg_printf("Disasm NIY\n");
@@ -159,6 +164,7 @@ struct backend_cpu be_alpha =
     be_alpha_is_function_return,
     be_alpha_is_break_insn,
     be_alpha_is_func_call,
+    be_alpha_is_jump,
     be_alpha_disasm_one_insn,
     be_alpha_insert_Xpoint,
     be_alpha_remove_Xpoint,
diff --git a/programs/winedbg/be_arm.c b/programs/winedbg/be_arm.c
index 709ce26..99336e2 100644
--- a/programs/winedbg/be_arm.c
+++ b/programs/winedbg/be_arm.c
@@ -87,6 +87,11 @@ static unsigned be_arm_is_func_call(const void* insn, ADDRESS64* callee)
     return FALSE;
 }
 
+static unsigned be_arm_is_jump(const void* insn, ADDRESS64* jumpee)
+{
+    return FALSE;
+}
+
 static void be_arm_disasm_one_insn(ADDRESS64* addr, int display)
 {
     dbg_printf("Disasm NIY\n");
@@ -181,6 +186,7 @@ struct backend_cpu be_arm =
     be_arm_is_function_return,
     be_arm_is_break_insn,
     be_arm_is_func_call,
+    be_arm_is_jump,
     be_arm_disasm_one_insn,
     be_arm_insert_Xpoint,
     be_arm_remove_Xpoint,
diff --git a/programs/winedbg/be_cpu.h b/programs/winedbg/be_cpu.h
index 005494d..ce9c32f 100644
--- a/programs/winedbg/be_cpu.h
+++ b/programs/winedbg/be_cpu.h
@@ -78,6 +78,8 @@ struct backend_cpu
     unsigned            (*is_break_insn)(const void*);
     /* Check whether instruction at 'addr' is a function call */
     unsigned            (*is_function_call)(const void* insn, ADDRESS64* callee);
+    /* Check whether instruction at 'addr' is a jump */
+    unsigned            (*is_jump)(const void* insn, ADDRESS64* jumpee);
     /* Ask for disassembling one instruction. If display is true, assembly code
      * will be printed. In all cases, 'addr' is advanced at next instruction
      */
diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c
index d6111bd..a986bf9 100644
--- a/programs/winedbg/be_i386.c
+++ b/programs/winedbg/be_i386.c
@@ -539,6 +539,44 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS64* callee)
     }
 }
 
+static unsigned be_i386_is_jump(const void* insn, ADDRESS64* jumpee)
+{
+    BYTE                ch;
+    int                 delta;
+    short               segment;
+    unsigned            dst = 0;
+    unsigned            operand_size;
+    ADDRESS_MODE        cs_addr_mode;
+
+    cs_addr_mode = get_selector_type(dbg_curr_thread->handle, &dbg_context,
+                                     dbg_context.SegCs);
+    operand_size = get_size(cs_addr_mode);
+
+    /* get operand_size (also getting rid of the various prefixes */
+    do
+    {
+        if (!dbg_read_memory(insn, &ch, sizeof(ch))) return FALSE;
+        if (ch == 0x66)
+        {
+            operand_size = 48 - operand_size; /* 16 => 32, 32 => 16 */
+            insn = (const char*)insn + 1;
+        }
+    } while (ch == 0x66 || ch == 0x67);
+
+    switch (ch)
+    {
+    case 0xe9: /* jmp near */
+        jumpee->Mode = cs_addr_mode;
+        if (!fetch_value((const char*)insn + 1, operand_size, &delta))
+            return FALSE;
+        jumpee->Segment = dbg_context.SegCs;
+        jumpee->Offset = (DWORD)insn + 1 + (operand_size / 8) + delta;
+        return TRUE;
+    default: WINE_FIXME("unknown %x\n", ch); return FALSE;
+    }
+    return FALSE;
+}
+
 #define DR7_CONTROL_SHIFT	16
 #define DR7_CONTROL_SIZE 	4
 
@@ -751,6 +789,7 @@ struct backend_cpu be_i386 =
     be_i386_is_function_return,
     be_i386_is_break_insn,
     be_i386_is_func_call,
+    be_i386_is_jump,
     be_i386_disasm_one_insn,
     be_i386_insert_Xpoint,
     be_i386_remove_Xpoint,
diff --git a/programs/winedbg/be_ppc.c b/programs/winedbg/be_ppc.c
index 2377648..0d076bc 100644
--- a/programs/winedbg/be_ppc.c
+++ b/programs/winedbg/be_ppc.c
@@ -90,7 +90,13 @@ static unsigned be_ppc_is_func_call(const void* insn, ADDRESS64* callee)
     return FALSE;
 }
 
+static unsigned be_ppc_is_jump(const void* insn, ADDRESS64* jumpee)
+{
+    return FALSE;
+}
+
 static void be_ppc_disasm_one_insn(ADDRESS64* addr, int display)
+
 {
     dbg_printf("Disasm NIY\n");
 }
@@ -183,6 +189,7 @@ struct backend_cpu be_ppc =
     be_ppc_is_function_return,
     be_ppc_is_break_insn,
     be_ppc_is_func_call,
+    be_ppc_is_jump,
     be_ppc_disasm_one_insn,
     be_ppc_insert_Xpoint,
     be_ppc_remove_Xpoint,
diff --git a/programs/winedbg/be_sparc.c b/programs/winedbg/be_sparc.c
index 45ba44e..c9afc95 100644
--- a/programs/winedbg/be_sparc.c
+++ b/programs/winedbg/be_sparc.c
@@ -78,6 +78,11 @@ static unsigned be_sparc_is_func_call(const void* insn, ADDRESS64* callee)
     return FALSE;
 }
 
+static unsigned be_sparc_is_jump(const void* insn, ADDRESS64* jumpee)
+{
+    return FALSE;
+}
+
 static void be_sparc_disasm_one_insn(ADDRESS64* addr, int display)
 {
     dbg_printf("not done for Sparc\n");
@@ -146,6 +151,7 @@ struct backend_cpu be_sparc =
     be_sparc_is_function_return,
     be_sparc_is_break_insn,
     be_sparc_is_func_call,
+    be_sparc_is_jump,
     be_sparc_disasm_one_insn,
     be_sparc_insert_Xpoint,
     be_sparc_remove_Xpoint,
diff --git a/programs/winedbg/be_x86_64.c b/programs/winedbg/be_x86_64.c
index 6099a78..bd7a00a 100644
--- a/programs/winedbg/be_x86_64.c
+++ b/programs/winedbg/be_x86_64.c
@@ -343,6 +343,11 @@ static unsigned be_x86_64_is_func_call(const void* insn, ADDRESS64* callee)
     }
 }
 
+static unsigned be_x86_64_is_jump(const void* insn, ADDRESS64* jumpee)
+{
+    return FALSE;
+}
+
 extern void be_x86_64_disasm_one_insn(ADDRESS64* addr, int display);
 
 #define DR7_CONTROL_SHIFT	16
@@ -560,6 +565,7 @@ struct backend_cpu be_x86_64 =
     be_x86_64_is_function_return,
     be_x86_64_is_break_insn,
     be_x86_64_is_func_call,
+    be_x86_64_is_jump,
     be_x86_64_disasm_one_insn,
     be_x86_64_insert_Xpoint,
     be_x86_64_remove_Xpoint,




More information about the wine-patches mailing list