From ae9f86042e7e11f4ff443392f462ef535e81c592 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Sat, 8 Jan 2011 14:08:56 +0100 Subject: [PATCH] winedbg: Added CPU method for identifying a jmp insn, and implement it for i386. --- programs/winedbg/be_alpha.c | 6 ++++++ programs/winedbg/be_arm.c | 6 ++++++ programs/winedbg/be_cpu.h | 2 ++ programs/winedbg/be_i386.c | 37 ++++++++++++++++++++++++++++++++++++ programs/winedbg/be_ppc.c | 7 +++++++ programs/winedbg/be_sparc.c | 6 ++++++ programs/winedbg/be_x86_64.c | 6 ++++++ 7 files changed, 70 insertions(+) diff --git a/programs/winedbg/be_alpha.c b/programs/winedbg/be_alpha.c index 76cddb52d56..f16952cadd0 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 709ce26b0ee..99336e2b7c4 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 005494d9dbe..ce9c32feaaa 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 d6111bdab1d..6f07e060a75 100644 --- a/programs/winedbg/be_i386.c +++ b/programs/winedbg/be_i386.c @@ -539,6 +539,42 @@ 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; + 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 +787,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 23776488fc1..0d076bc3c2f 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 45ba44e406a..c9afc9502ce 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 6099a784ba6..bd7a00a71dd 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,