gdb:
authorYao Qi <yao@codesourcery.com>
Fri, 9 Nov 2012 10:11:21 +0000 (10:11 +0000)
committerYao Qi <yao@codesourcery.com>
Fri, 9 Nov 2012 10:11:21 +0000 (10:11 +0000)
* i386-tdep.c (i386_analyze_frame_setup): Handle opcode
0x8d (lea).

gdb/ChangeLog
gdb/i386-tdep.c

index 54782fbed965291121033c4cebd6bd1e019ac4a9..9a7148d809e759421b09a0b3fe1007f49fb0cf9b 100644 (file)
@@ -1,3 +1,8 @@
+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.
index df29b71532ea26fcac4d6f4fb6efbd37112e3325..b6879b959fe0354b342b93b8c338a37319d80c6a 100644 (file)
@@ -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;
        }
     }