gdb/arm-tdep: fix to adapt insn "str rd, [sp, #-imm]"

Message ID 1576762299-7119-1-git-send-email-chenzefeng2@huawei.com
State New, archived
Headers

Commit Message

chenzefeng Dec. 19, 2019, 1:31 p.m. UTC
  In the code below, GDB get an incorrect backtrace:

0x000f13fc <+0>:	str	r4, [sp, #-8]!

according to the ARMV7 manual, the insn of str have
12 bits immediate.

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
---
 gdb/arm-tdep.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
  

Comments

Luis Machado Jan. 14, 2020, 5:32 p.m. UTC | #1
Hi,

On 12/19/19 10:31 AM, chenzefeng wrote:
> In the code below, GDB get an incorrect backtrace:
> 
> 0x000f13fc <+0>:	str	r4, [sp, #-8]!
> 
> according to the ARMV7 manual, the insn of str have
> 12 bits immediate.
> 
> Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
> ---
>   gdb/arm-tdep.c | 7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 69c87c5..8a9f878 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -1539,12 +1539,13 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
>   	  regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], -imm);
>   	  continue;
>   	}
> -      else if ((insn & 0xffff0fff) == 0xe52d0004)	/* str Rd,
> -							   [sp, #-4]! */
> +      else if ((insn & 0xffff0000) == 0xe52d0000)	/* str Rd,
> +							   [sp, #-imm]! */
>   	{
> +	  unsigned imm = insn & 0xfff;
>   	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
>   	    break;
> -	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -4);
> +	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
>   	  stack.store (regs[ARM_SP_REGNUM], 4,
>   		       regs[bits (insn, 12, 15)]);
>   	  continue;
> 

Thanks for the patch. Do you have a test for this particular problem? Or 
instructions on how to reproduce it?
  

Patch

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 69c87c5..8a9f878 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -1539,12 +1539,13 @@  arm_analyze_prologue (struct gdbarch *gdbarch,
 	  regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], -imm);
 	  continue;
 	}
-      else if ((insn & 0xffff0fff) == 0xe52d0004)	/* str Rd,
-							   [sp, #-4]! */
+      else if ((insn & 0xffff0000) == 0xe52d0000)	/* str Rd,
+							   [sp, #-imm]! */
 	{
+	  unsigned imm = insn & 0xfff;
 	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
 	    break;
-	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -4);
+	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
 	  stack.store (regs[ARM_SP_REGNUM], 4,
 		       regs[bits (insn, 12, 15)]);
 	  continue;