From e11481da798a311f8d87ca44ae69203b8b6daa5d Mon Sep 17 00:00:00 2001 From: Pierre Muller Date: Fri, 25 Jan 2008 17:24:49 +0000 Subject: * i386-tdep.c (i386_skip_noop): New function. (i386_analyze_prologue): Call i386_skip_noop function. --- gdb/ChangeLog | 5 +++++ gdb/i386-tdep.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cabbc74..f711c00 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2008-01-25 Pierre Muller + + * i386-tdep.c (i386_skip_noop): New function. + (i386_analyze_prologue): Call i386_skip_noop function. + 2008-01-24 Michael Snyder * procfs.c (procfs_xfer_partial): Comment, cut/paste error. diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index c88fb25..83ae9d1 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -632,6 +632,51 @@ struct i386_insn i386_frame_setup_skip_insns[] = { 0 } }; + +/* Check whether PC points to a no-op instruction. */ +static CORE_ADDR +i386_skip_noop (CORE_ADDR pc) +{ + gdb_byte op; + int check = 1; + + read_memory_nobpt (pc, &op, 1); + + while (check) + { + check = 0; + /* Ignore `nop' instruction. */ + if (op == 0x90) + { + pc += 1; + read_memory_nobpt (pc, &op, 1); + check = 1; + } + /* Ignore no-op instruction `mov %edi, %edi'. + Microsoft system dlls often start with + a `mov %edi,%edi' instruction. + The 5 bytes before the function start are + filled with `nop' instructions. + This pattern can be used for hot-patching: + The `mov %edi, %edi' instruction can be replaced by a + near jump to the location of the 5 `nop' instructions + which can be replaced by a 32-bit jump to anywhere + in the 32-bit address space. */ + + else if (op == 0x8b) + { + read_memory_nobpt (pc + 1, &op, 1); + if (op == 0xff) + { + pc += 2; + read_memory_nobpt (pc, &op, 1); + check = 1; + } + } + } + return pc; +} + /* Check whether PC points at a code that sets up a new stack frame. If so, it updates CACHE and returns the address of the first instruction after the sequence that sets up the frame or LIMIT, @@ -817,6 +862,7 @@ static CORE_ADDR i386_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, struct i386_frame_cache *cache) { + pc = i386_skip_noop (pc); pc = i386_follow_jump (pc); pc = i386_analyze_struct_return (pc, current_pc, cache); pc = i386_skip_probe (pc); -- cgit v1.1