[ARM] Access FPSCR on vfpv2

Message ID 1500973532-7116-1-git-send-email-yao.qi@linaro.org
State New, archived
Headers

Commit Message

Yao Qi July 25, 2017, 9:05 a.m. UTC
  GDB can fetch or store FPSCR on vfpv3, which has 32 VFP registers, but
fail to do so on vfpv2, which has 16 VFP registers.  GDB code is incorrect
for vfpv2,

       else if (tdep->vfp_register_count > 0
 	       && regno >= ARM_D0_REGNUM
	       && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)

while FPSCR register number is defined as ARM_D0_REGNUM + 32.

  ARM_D0_REGNUM,		/* VFP double-precision registers.  */
  ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
  ARM_FPSCR_REGNUM,

The code above uses "<=" rather than "<", in order to put FPSCR in the
range, but it is only correct when tdep->vfp_register_count is 32.  On
vpfv2, it is 16, and FPSCR is out of the range, so fetch_vfp_regs or
store_vfp_regs are not called.

gdb:

2017-07-25  Yao Qi  <yao.qi@linaro.org>

	PR tdep/21717
	* arm-linux-nat.c (arm_linux_fetch_inferior_registers): Update
	condition for FPSCR.
	(arm_linux_store_inferior_registers): Likewise.
---
 gdb/ChangeLog       | 7 +++++++
 gdb/arm-linux-nat.c | 6 ++++--
 2 files changed, 11 insertions(+), 2 deletions(-)
  

Comments

Yao Qi July 25, 2017, 9:24 a.m. UTC | #1
On Tue, Jul 25, 2017 at 10:05 AM, Yao Qi <qiyaoltc@gmail.com> wrote:
> GDB can fetch or store FPSCR on vfpv3, which has 32 VFP registers, but
> fail to do so on vfpv2, which has 16 VFP registers.  GDB code is incorrect
> for vfpv2,
>
>        else if (tdep->vfp_register_count > 0
>                && regno >= ARM_D0_REGNUM
>                && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
>
> while FPSCR register number is defined as ARM_D0_REGNUM + 32.
>
>   ARM_D0_REGNUM,                /* VFP double-precision registers.  */
>   ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
>   ARM_FPSCR_REGNUM,
>
> The code above uses "<=" rather than "<", in order to put FPSCR in the
> range, but it is only correct when tdep->vfp_register_count is 32.  On
> vpfv2, it is 16, and FPSCR is out of the range, so fetch_vfp_regs or
> store_vfp_regs are not called.

I also pushed it to 8.0 branch, and update the wiki
page  for 8.0.1 release.
https://sourceware.org/gdb/wiki/GDB_8.0_Release
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8944833..eb49001 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@ 
+2017-07-25  Yao Qi  <yao.qi@linaro.org>
+
+	PR tdep/21717
+	* arm-linux-nat.c (arm_linux_fetch_inferior_registers): Update
+	condition for FPSCR.
+	(arm_linux_store_inferior_registers): Likewise.
+
 2017-07-22  Tom Tromey  <tom@tromey.com>
 
 	* break-catch-syscall.c (struct catch_syscall_inferior_data)
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index ad3085a..4039d1e 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -402,7 +402,8 @@  arm_linux_fetch_inferior_registers (struct target_ops *ops,
 	fetch_wmmx_regs (regcache);
       else if (tdep->vfp_register_count > 0
 	       && regno >= ARM_D0_REGNUM
-	       && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
+	       && (regno < ARM_D0_REGNUM + tdep->vfp_register_count
+		   || regno == ARM_FPSCR_REGNUM))
 	fetch_vfp_regs (regcache);
     }
 }
@@ -439,7 +440,8 @@  arm_linux_store_inferior_registers (struct target_ops *ops,
 	store_wmmx_regs (regcache);
       else if (tdep->vfp_register_count > 0
 	       && regno >= ARM_D0_REGNUM
-	       && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
+	       && (regno < ARM_D0_REGNUM + tdep->vfp_register_count
+		   || regno == ARM_FPSCR_REGNUM))
 	store_vfp_regs (regcache);
     }
 }