From: Sandra Loosemore Date: Thu, 30 Jul 2015 20:23:43 +0000 (-0700) Subject: Update trap/break handling in nios2 prologue analyzer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9aaf8e3a2875f719e4d5633ba222a3c04a5d0e8d;p=binutils-gdb.git Update trap/break handling in nios2 prologue analyzer. 2015-07-30 Sandra Loosemore gdb/ * nios2-tdep.c (nios2_analyze_prologue): Update comments to reflect how current GCC emits stack overflow checks. Match both trap and break instructions for backward compatibility. Disallow other trap and break instructions in the prologue. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 64fbe8e55b9..120148a2441 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2015-07-30 Sandra Loosemore + + * nios2-tdep.c (nios2_analyze_prologue): Update comments to + reflect how current GCC emits stack overflow checks. Match + both trap and break instructions for backward compatbility. + Disallow other trap and break instructions in the prologue. + 2015-07-30 Pedro Alves PR threads/18600 diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c index 1968a88a9f6..1c5dcdebfba 100644 --- a/gdb/nios2-tdep.c +++ b/gdb/nios2-tdep.c @@ -697,22 +697,29 @@ nios2_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) stw sp, constant(rx) mov sp, rx - 5) A frame pointer save, which can be either a MOV or ADDI. + 4) A frame pointer save, which can be either a MOV or ADDI. - 6) A further stack pointer adjustment. This is normally included - adjustment in step 4 unless the total adjustment is too large + 5) A further stack pointer adjustment. This is normally included + adjustment in step 3 unless the total adjustment is too large to be done in one step. 7) A stack overflow check, which can take either of these forms: bgeu sp, rx, +8 - break 3 + trap 3 or bltu sp, rx, .Lstack_overflow ... .Lstack_overflow: - break 3 - If present, this is inserted after the stack pointer adjustments - for steps 3, 4, and 6. + trap 3 + + Older versions of GCC emitted "break 3" instead of "trap 3" here, + so we check for both cases. + + Older GCC versions emitted stack overflow checks after the SP + adjustments in both steps 3 and 4. Starting with GCC 6, there is + at most one overflow check, which is placed before the first + stack adjustment for R2 CDX and after the first stack adjustment + otherwise. The prologue instructions may be combined or interleaved with other instructions. @@ -995,14 +1002,15 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc, else if (cond == branch_geu) { /* BGEU sp, rx, +8 - BREAK 3 + TRAP 3 (or BREAK 3) This instruction sequence is used in stack checking; we can ignore it. */ unsigned int next_insn; const struct nios2_opcode *next_op = nios2_fetch_insn (gdbarch, pc, &next_insn); if (next_op != NULL - && nios2_match_break (next_insn, op, mach, &uimm)) + && (nios2_match_trap (next_insn, op, mach, &uimm) + || nios2_match_break (next_insn, op, mach, &uimm))) pc += next_op->size; else break; @@ -1010,13 +1018,14 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc, else if (cond == branch_ltu) { /* BLTU sp, rx, .Lstackoverflow - If the location branched to holds a BREAK 3 instruction - then this is also stack overflow detection. */ + If the location branched to holds a TRAP or BREAK + instruction then this is also stack overflow detection. */ unsigned int next_insn; const struct nios2_opcode *next_op = nios2_fetch_insn (gdbarch, pc + imm, &next_insn); if (next_op != NULL - && nios2_match_break (next_insn, op, mach, &uimm)) + && (nios2_match_trap (next_insn, op, mach, &uimm) + || nios2_match_break (next_insn, op, mach, &uimm))) ; else break; @@ -1025,11 +1034,13 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc, break; } - /* All other calls or jumps (including returns) terminate + /* All other calls, jumps, returns, TRAPs, or BREAKs terminate the prologue. */ else if (nios2_match_callr (insn, op, mach, &ra) || nios2_match_jmpr (insn, op, mach, &ra) - || nios2_match_jmpi (insn, op, mach, &uimm)) + || nios2_match_jmpi (insn, op, mach, &uimm) + || nios2_match_trap (insn, op, mach, &uimm) + || nios2_match_break (insn, op, mach, &uimm)) break; }