aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorYao Qi <yao@codesourcery.com>2012-11-09 10:11:21 +0000
committerYao Qi <yao@codesourcery.com>2012-11-09 10:11:21 +0000
commit30f8135b5ca8edc8020e79061528cab41709be41 (patch)
treecde392ac74c6c9f45bb2bfd83746385c141b84e5 /gdb
parent5bb3703f01dd574faebbd3a69f4c64dbfee6a701 (diff)
downloadgdb-30f8135b5ca8edc8020e79061528cab41709be41.zip
gdb-30f8135b5ca8edc8020e79061528cab41709be41.tar.gz
gdb-30f8135b5ca8edc8020e79061528cab41709be41.tar.bz2
gdb:
* i386-tdep.c (i386_analyze_frame_setup): Handle opcode 0x8d (lea).
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/i386-tdep.c38
2 files changed, 40 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 54782fb..9a7148d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2012-11-09 Yao Qi <yao@codesourcery.com>
+ * i386-tdep.c (i386_analyze_frame_setup): Handle opcode
+ 0x8d (lea).
+
+2012-11-09 Yao Qi <yao@codesourcery.com>
+
* breakpoint.c: Declare set_tracepoint_count.
(install_breakpoint): Call set_tracepoint_count if B is a
tracepoint.
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index df29b71..b6879b9 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -1388,18 +1388,40 @@ i386_analyze_frame_setup (struct gdbarch *gdbarch,
if (target_read_memory (pc + skip, &op, 1))
return pc + skip;
- /* Check for `movl %esp, %ebp' -- can be written in two ways. */
+ /* The i386 prologue looks like
+
+ push %ebp
+ mov %esp,%ebp
+ sub $0x10,%esp
+
+ and a different prologue can be generated for atom.
+
+ push %ebp
+ lea (%esp),%ebp
+ lea -0x10(%esp),%esp
+
+ We handle both of them here. */
+
switch (op)
{
+ /* Check for `movl %esp, %ebp' -- can be written in two ways. */
case 0x8b:
if (read_memory_unsigned_integer (pc + skip + 1, 1, byte_order)
!= 0xec)
return pc;
+ pc += (skip + 2);
break;
case 0x89:
if (read_memory_unsigned_integer (pc + skip + 1, 1, byte_order)
!= 0xe5)
return pc;
+ pc += (skip + 2);
+ break;
+ case 0x8d: /* Check for 'lea (%ebp), %ebp'. */
+ if (read_memory_unsigned_integer (pc + skip + 1, 2, byte_order)
+ != 0x242c)
+ return pc;
+ pc += (skip + 3);
break;
default:
return pc;
@@ -1410,7 +1432,6 @@ i386_analyze_frame_setup (struct gdbarch *gdbarch,
necessary. We also now commit to skipping the special
instructions mentioned before. */
cache->locals = 0;
- pc += (skip + 2);
/* If that's all, return now. */
if (limit <= pc)
@@ -1419,6 +1440,8 @@ i386_analyze_frame_setup (struct gdbarch *gdbarch,
/* Check for stack adjustment
subl $XXX, %esp
+ or
+ lea -XXX(%esp),%esp
NOTE: You can't subtract a 16-bit immediate from a 32-bit
reg, so we don't have to worry about a data16 prefix. */
@@ -1447,9 +1470,18 @@ i386_analyze_frame_setup (struct gdbarch *gdbarch,
cache->locals = read_memory_integer (pc + 2, 4, byte_order);
return pc + 6;
}
+ else if (op == 0x8d)
+ {
+ /* The ModR/M byte is 0x64. */
+ if (read_memory_unsigned_integer (pc + 1, 1, byte_order) != 0x64)
+ return pc;
+ /* 'lea' with 8-bit displacement. */
+ cache->locals = -1 * read_memory_integer (pc + 3, 1, byte_order);
+ return pc + 4;
+ }
else
{
- /* Some instruction other than `subl'. */
+ /* Some instruction other than `subl' nor 'lea'. */
return pc;
}
}