]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2002-04-24 Michael Snyder <msnyder@redhat.com>
authorMichael Snyder <msnyder@vmware.com>
Wed, 24 Apr 2002 21:22:06 +0000 (21:22 +0000)
committerMichael Snyder <msnyder@vmware.com>
Wed, 24 Apr 2002 21:22:06 +0000 (21:22 +0000)
        * arm-tdep.c (arm_scan_prologue): Move "mov ip, sp" into the
        loop.  Add handling for "str lr, [sp, #-4]!" and for saves
        of argument regs ("str r(0123), [r11, #-nn"]).
        (arm_skip_prologue): Better handling for frameless functions.
        Treat "mov ip, sp" as optional.  Recognize "str lr, [sp, #-4]".
        (arm_skip_prologue): Recognize str r(0123), [r11, #-nn].

gdb/ChangeLog
gdb/arm-tdep.c

index f8cc9551c541a0f989834d9b89bc548c094f0bfc..e7d73252bc126e8fb142d6cc0efd1bc3eaae30f9 100644 (file)
@@ -1,3 +1,12 @@
+2002-04-24  Michael Snyder  <msnyder@redhat.com>
+
+       * arm-tdep.c (arm_scan_prologue): Move "mov ip, sp" into the 
+       loop.  Add handling for "str lr, [sp, #-4]!" and for saves
+       of argument regs ("str r(0123), [r11, #-nn"]).
+       (arm_skip_prologue): Better handling for frameless functions.  
+       Treat "mov ip, sp" as optional.  Recognize "str lr, [sp, #-4]".
+       (arm_skip_prologue): Recognize str r(0123), [r11, #-nn].
+
 Wed Apr 24 14:22:21 2002  Andrew Cagney  <cagney@redhat.com>
 
        * arm-tdep.c (arm_gdbarch_init): Add comment that NUM_REGS nor
@@ -58,6 +67,7 @@ Wed Apr 24 14:22:21 2002  Andrew Cagney  <cagney@redhat.com>
        REGISTER_RAW_SIZE of SP_REGNUM not CORE_ADDR.
        (vx_write_register): Likewise.
 
+>>>>>>> 1.2500
 2002-04-23  J. Brobecker  <brobecker@gnat.com>
 
        * source.c (is_regular_file): New function.
index f05ff6b14ebce655c4d40fbb94c9d931d630b4cf..a5643a74d796dfdb95e92fe36f41b12e73bef78a 100644 (file)
@@ -446,22 +446,33 @@ arm_skip_prologue (CORE_ADDR pc)
      by disassembling the instructions. */
   skip_pc = pc;
   inst = read_memory_integer (skip_pc, 4);
-  if (inst != 0xe1a0c00d)      /* mov ip, sp */
-    return pc;
-
-  skip_pc += 4;
-  inst = read_memory_integer (skip_pc, 4);
-  if ((inst & 0xfffffff0) == 0xe92d0000)       /* stmfd sp!,{a1,a2,a3,a4}  */
+  /* "mov ip, sp" is no longer a required part of the prologue.  */
+  if (inst == 0xe1a0c00d)       /* mov ip, sp */
     {
       skip_pc += 4;
       inst = read_memory_integer (skip_pc, 4);
     }
 
-  if ((inst & 0xfffff800) != 0xe92dd800)       /* stmfd sp!,{...,fp,ip,lr,pc} */
-    return pc;
+  /* Some prologues begin with "str lr, [sp, #-4]!".  */
+  if (inst == 0xe52de004)                       /* str lr, [sp, #-4]! */
+    {
+      skip_pc += 4;
+      inst = read_memory_integer (skip_pc, 4);
+    }
 
   skip_pc += 4;
   inst = read_memory_integer (skip_pc, 4);
+  if ((inst & 0xfffffff0) == 0xe92d0000)       /* stmfd sp!,{a1,a2,a3,a4} */
+    {
+      skip_pc += 4;
+      inst = read_memory_integer (skip_pc, 4);
+    }
+
+  if ((inst & 0xfffff800) == 0xe92dd800)       /* stmfd sp!,{fp,ip,lr,pc} */
+    {
+      skip_pc += 4;
+      inst = read_memory_integer (skip_pc, 4);
+    }
 
   /* Any insns after this point may float into the code, if it makes
      for better instruction scheduling, so we skip them only if we
@@ -477,7 +488,7 @@ arm_skip_prologue (CORE_ADDR pc)
     }
   else
     {
-      while ((inst & 0xffff8fff) == 0xed6d0103)                /* stfe fn, [sp, #-12]! */
+      while ((inst & 0xffff8fff) == 0xed6d0103)        /* stfe fn, [sp, #-12]! */
        {
          skip_pc += 4;
          inst = read_memory_integer (skip_pc, 4);
@@ -490,8 +501,17 @@ arm_skip_prologue (CORE_ADDR pc)
       inst = read_memory_integer (skip_pc, 4);
     }
 
-  if ((inst & 0xfffff000) == 0xe24dd000)                /* sub sp, sp, #nn */
-    skip_pc += 4;
+  if ((inst & 0xfffff000) == 0xe24dd000)       /* sub sp, sp, #nn */
+    {
+      skip_pc += 4;
+      inst = read_memory_integer (skip_pc, 4);
+    }
+
+  while ((inst & 0xffffcfc0) == 0xe50b0000)     /* str r(0123), [r11, #-nn] */
+    {
+      skip_pc += 4;
+      inst = read_memory_integer (skip_pc, 4);
+    }
 
   return skip_pc;
 }
@@ -843,23 +863,34 @@ arm_scan_prologue (struct frame_info *fi)
      traceback.
 
      In the APCS, the prologue should start with  "mov ip, sp" so
-     if we don't see this as the first insn, we will stop.  [Note:
-     This doesn't seem to be true any longer, so it's now an optional
-     part of the prologue.  - Kevin Buettner, 2001-11-20]  */
+     if we don't see this as the first insn, we will stop.  
 
-  sp_offset = fp_offset = 0;
+     [Note: This doesn't seem to be true any longer, so it's now an
+     optional part of the prologue.  - Kevin Buettner, 2001-11-20]
 
-  if (read_memory_unsigned_integer (prologue_start, 4)
-      == 0xe1a0c00d)           /* mov ip, sp */
-    current_pc = prologue_start + 4;
-  else
-    current_pc = prologue_start;
+     [Note further: The "mov ip,sp" only seems to be missing in
+     frameless functions at optimization level "-O2" or above,
+     in which case it is often (but not always) replaced by
+     "str lr, [sp, #-4]!".  - Michael Snyder, 2002-04-23]   */
 
-  for (; current_pc < prologue_end; current_pc += 4)
+  sp_offset = fp_offset = 0;
+
+  for (current_pc = prologue_start; 
+       current_pc < prologue_end; 
+       current_pc += 4)
     {
       unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
 
-      if ((insn & 0xffff0000) == 0xe92d0000)
+      if (insn == 0xe1a0c00d)           /* mov ip, sp */
+       {
+         continue;
+       }
+      else if (insn == 0xe52de004)      /* str lr, [sp, #-4]! */
+       {
+         /* Function is frameless: extra_info defaults OK?  */
+         continue;
+       }
+      else if ((insn & 0xffff0000) == 0xe92d0000)
        /* stmfd sp!, {..., fp, ip, lr, pc}
           or
           stmfd sp!, {a1, a2, a3, a4}  */
@@ -874,6 +905,11 @@ arm_scan_prologue (struct frame_info *fi)
                fi->saved_regs[regno] = sp_offset;
              }
        }
+      else if ((insn & 0xffffcfc0) == 0xe50b0000)       /* str rx, [r11, -n] */
+       {
+         /* No need to add this to saved_regs -- it's just an arg reg.  */
+         continue;
+       }
       else if ((insn & 0xfffff000) == 0xe24cb000)      /* sub fp, ip #n */
        {
          unsigned imm = insn & 0xff;   /* immediate value */