aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Muller <muller@sourceware.org>2008-01-25 17:24:49 +0000
committerPierre Muller <muller@sourceware.org>2008-01-25 17:24:49 +0000
commite11481da798a311f8d87ca44ae69203b8b6daa5d (patch)
tree3419981a4daa998cda135133f58864411410b80b
parent6e3d6dc1ed34b1a58ed922ce31a5cf63502f4bce (diff)
downloadgdb-e11481da798a311f8d87ca44ae69203b8b6daa5d.zip
gdb-e11481da798a311f8d87ca44ae69203b8b6daa5d.tar.gz
gdb-e11481da798a311f8d87ca44ae69203b8b6daa5d.tar.bz2
* i386-tdep.c (i386_skip_noop): New function.
(i386_analyze_prologue): Call i386_skip_noop function.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/i386-tdep.c46
2 files changed, 51 insertions, 0 deletions
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 <muller@ics.u-strasbg.fr>
+
+ * i386-tdep.c (i386_skip_noop): New function.
+ (i386_analyze_prologue): Call i386_skip_noop function.
+
2008-01-24 Michael Snyder <msnyder@specifix.com>
* 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);