From aa4893954a75660d2aa66245cb9d020049cb9546 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Tue, 25 Nov 2014 18:40:28 -0800 Subject: [PATCH] Fix Nios II prologue analyzer to handle multiple stack adjustments. 2014-11-25 Sandra Loosemore 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 | 6 ++++++ gdb/nios2-tdep.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d7f756357d6..de98b3cb151 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2014-11-25 Sandra Loosemore + + * 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 * nios2-tdep.c (nios2_in_epilogue_p): Handle multiple stack diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c index 27580128dc3..13aa407eacb 100644 --- a/gdb/nios2-tdep.c +++ b/gdb/nios2-tdep.c @@ -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)) -- 2.30.2