* arm-tdep.c (arm_skip_prologue): Handle "sub ip, sp #n" and
authorJerome Guitton <guitton@adacore.com>
Thu, 25 Sep 2003 14:21:00 +0000 (14:21 +0000)
committerJerome Guitton <guitton@adacore.com>
Thu, 25 Sep 2003 14:21:00 +0000 (14:21 +0000)
"add ip, sp #n" in the prologue.
(arm_scan_prologue): Ditto.

gdb/ChangeLog
gdb/arm-tdep.c

index 3d52955a8f4617bd7bae31f0c5ac456fa92bd973..216635b1f1dba24e5316458ba10541c236316632 100644 (file)
@@ -1,3 +1,9 @@
+2003-09-25  Jerome Guitton  <guitton@act-europe.fr>
+
+       * arm-tdep.c (arm_skip_prologue): Handle "sub ip, sp #n" and
+       "add ip, sp #n" in the prologue.
+       (arm_scan_prologue): Ditto.
+
 2003-09-25  Jerome Guitton  <guitton@act-europe.fr>
 
        * MAINTAINERS (write after approval): Add myself.
index 3ba072d1ff8620a3a7716322c580881251d36d90..85e8258e6dd5f2ee0351e0f94855feb68cc0e77f 100644 (file)
@@ -455,6 +455,12 @@ arm_skip_prologue (CORE_ADDR pc)
       if (inst == 0xe1a0c00d)                  /* mov ip, sp */
        continue;
 
+      if ((inst & 0xfffff000) == 0xe28dc000)    /* add ip, sp #n */
+       continue;
+
+      if ((inst & 0xfffff000) == 0xe24dc000)    /* sub ip, sp #n */
+       continue;
+
       /* Some prologues begin with "str lr, [sp, #-4]!".  */
       if (inst == 0xe52de004)                  /* str lr, [sp, #-4]! */
        continue;
@@ -707,7 +713,7 @@ thumb_scan_prologue (CORE_ADDR prev_pc, struct arm_prologue_cache *cache)
 static void
 arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cache)
 {
-  int regno, sp_offset, fp_offset;
+  int regno, sp_offset, fp_offset, ip_offset;
   CORE_ADDR prologue_start, prologue_end, current_pc;
   CORE_ADDR prev_pc = frame_pc_unwind (next_frame);
 
@@ -808,7 +814,7 @@ arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cac
      in which case it is often (but not always) replaced by
      "str lr, [sp, #-4]!".  - Michael Snyder, 2002-04-23]  */
 
-  sp_offset = fp_offset = 0;
+  sp_offset = fp_offset = ip_offset = 0;
 
   for (current_pc = prologue_start;
        current_pc < prologue_end;
@@ -818,6 +824,23 @@ arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cac
 
       if (insn == 0xe1a0c00d)          /* mov ip, sp */
        {
+         ip_offset = 0;
+         continue;
+       }
+      else if ((insn & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */
+       {
+         unsigned imm = insn & 0xff;                   /* immediate value */
+         unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
+         imm = (imm >> rot) | (imm << (32 - rot));
+         ip_offset = imm;
+         continue;
+       }
+      else if ((insn & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */
+       {
+         unsigned imm = insn & 0xff;                   /* immediate value */
+         unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
+         imm = (imm >> rot) | (imm << (32 - rot));
+         ip_offset = -imm;
          continue;
        }
       else if (insn == 0xe52de004)     /* str lr, [sp, #-4]! */
@@ -859,7 +882,7 @@ arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cac
          unsigned imm = insn & 0xff;                   /* immediate value */
          unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
          imm = (imm >> rot) | (imm << (32 - rot));
-         fp_offset = -imm;
+         fp_offset = -imm + ip_offset;
          cache->framereg = ARM_FP_REGNUM;
        }
       else if ((insn & 0xfffff000) == 0xe24dd000)      /* sub sp, sp #n */