Fix Nios II prologue analyzer to handle multiple stack adjustments.
authorSandra Loosemore <sandra@codesourcery.com>
Wed, 26 Nov 2014 02:40:28 +0000 (18:40 -0800)
committerSandra Loosemore <sandra@codesourcery.com>
Wed, 26 Nov 2014 02:40:28 +0000 (18:40 -0800)
2014-11-25  Sandra Loosemore  <sandra@codesourcery.com>

gdb/
* nios2-tdep.c (nios2_analyze_prologue): Replace restriction
that there can be only one stack adjustment in the prologue
with tests to detect specific disallowed stack adjustments.

gdb/ChangeLog
gdb/nios2-tdep.c

index d7f756357d60746cec6e4b469419a7614681239e..de98b3cb1515ed40f62c2e3e29b6e8a572b75ac4 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-25  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * nios2-tdep.c (nios2_analyze_prologue): Replace restriction
+       that there can be only one stack adjustment in the prologue
+       with tests to detect specific disallowed stack adjustments.
+
 2014-11-25  Sandra Loosemore  <sandra@codesourcery.com>
 
        * nios2-tdep.c (nios2_in_epilogue_p): Handle multiple stack
index 27580128dc300e99370842f6d6534d887133f93a..13aa407eacb2defc91888eac491a0831a530eae7 100644 (file)
@@ -842,6 +842,11 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
              cache->reg_saved[NIOS2_SP_REGNUM].addr = -4;
            }
 
+         else if (rc == NIOS2_SP_REGNUM && ra == NIOS2_FP_REGNUM)
+           /* This is setting SP from FP.  This only happens in the
+              function epilogue.  */
+           break;
+
          else if (rc != 0)
            {
              if (value[rb].reg == 0)
@@ -853,13 +858,21 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
              value[rc].offset = value[ra].offset + value[rb].offset;
            }
 
-         prologue_end = pc;
+         /* The add/move is only considered a prologue instruction
+            if the destination is SP or FP.  */
+         if (rc == NIOS2_SP_REGNUM || rc == NIOS2_FP_REGNUM)
+           prologue_end = pc;
        }
       
       else if (nios2_match_sub (insn, op, mach, &ra, &rb, &rc))
        {
          /* SUB   rc, ra, rb */
-         if (rc != 0)
+         if (rc == NIOS2_SP_REGNUM && rb == NIOS2_SP_REGNUM
+             && value[rc].reg != 0)
+           /* If we are decrementing the SP by a non-constant amount,
+              this is alloca, not part of the prologue.  */
+           break;
+         else if (rc != 0)
            {
              if (value[rb].reg == 0)
                value[rc].reg = value[ra].reg;
@@ -873,12 +886,13 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
        {
          /* ADDI    rb, ra, imm */
 
-         /* The first stack adjustment is part of the prologue.
-            Any subsequent stack adjustments are either down to
-            alloca or the epilogue so stop analysing when we hit
-            them.  */
+         /* A positive stack adjustment has to be part of the epilogue.  */
          if (rb == NIOS2_SP_REGNUM
-             && (value[rb].offset != 0 || value[ra].reg != NIOS2_SP_REGNUM))
+             && (imm > 0 || value[ra].reg != NIOS2_SP_REGNUM))
+           break;
+
+         /* Likewise restoring SP from FP.  */
+         else if (rb == NIOS2_SP_REGNUM && ra == NIOS2_FP_REGNUM)
            break;
 
          if (rb != 0)
@@ -887,7 +901,10 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
              value[rb].offset = value[ra].offset + imm;
            }
 
-         prologue_end = pc;
+         /* The add is only considered a prologue instruction
+            if the destination is SP or FP.  */
+         if (rb == NIOS2_SP_REGNUM || rb == NIOS2_FP_REGNUM)
+           prologue_end = pc;
        }
 
       else if (nios2_match_orhi (insn, op, mach, &ra, &rb, &uimm))