diff options
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/arm-tdep.c | 25 |
2 files changed, 20 insertions, 11 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 112a869..7bc1d03 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2014-07-11 Yao Qi <yao@codesourcery.com> + * arm-tdep.c (thumb_instruction_restores_sp): New function. + (thumb_in_function_epilogue_p): Call + thumb_instruction_restores_sp. + +2014-07-11 Yao Qi <yao@codesourcery.com> + * arm-tdep.c (thumb_analyze_prologue): Don't match instruction 'add sp, #imm'. (thumb_in_function_epilogue_p): Don't match 'sub sp, #imm'. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 6b1cf3c..0e7d9c2 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -685,6 +685,17 @@ thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2) return 0; } +/* Return 1 if the 16-bit Thumb instruction INSN restores SP in + epilogue, 0 otherwise. */ + +static int +thumb_instruction_restores_sp (unsigned short insn) +{ + return (insn == 0x46bd /* mov sp, r7 */ + || (insn & 0xff80) == 0xb000 /* add sp, imm */ + || (insn & 0xfe00) == 0xbc00); /* pop <registers> */ +} + /* Analyze a Thumb prologue, looking for a recognizable stack frame and frame pointer. Scan until we encounter a store that could clobber the stack frame unexpectedly, or an unknown instruction. @@ -3257,14 +3268,10 @@ thumb_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) found_return = 1; else if (insn == 0x46f7) /* mov pc, lr */ found_return = 1; - else if (insn == 0x46bd) /* mov sp, r7 */ - found_stack_adjust = 1; - else if ((insn & 0xff80) == 0xb000) /* add sp, imm */ - found_stack_adjust = 1; - else if ((insn & 0xfe00) == 0xbc00) /* pop <registers> */ + else if (thumb_instruction_restores_sp (insn)) { found_stack_adjust = 1; - if (insn & 0x0100) /* <registers> include PC. */ + if ((insn & 0xfe00) == 0xbd00) /* pop <registers, PC> */ found_return = 1; } else if (thumb_insn_size (insn) == 4) /* 32-bit Thumb-2 instruction */ @@ -3317,11 +3324,7 @@ thumb_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) insn = extract_unsigned_integer (buf, 2, byte_order_for_code); insn2 = extract_unsigned_integer (buf + 2, 2, byte_order_for_code); - if (insn2 == 0x46bd) /* mov sp, r7 */ - found_stack_adjust = 1; - else if ((insn2 & 0xff80) == 0xb000) /* add sp, imm */ - found_stack_adjust = 1; - else if ((insn2 & 0xff00) == 0xbc00) /* pop <registers> without PC */ + if (thumb_instruction_restores_sp (insn2)) found_stack_adjust = 1; else if (insn == 0xe8bd) /* ldm.w sp!, <registers> */ found_stack_adjust = 1; |