Fix PTRACE_GETREGSET failure for compat inferiors on arm64
authorKees Cook <keescook@chromium.org>
Fri, 27 Jan 2017 11:14:47 +0000 (11:14 +0000)
committerYao Qi <yao.qi@linaro.org>
Fri, 27 Jan 2017 11:14:47 +0000 (11:14 +0000)
When running a 32-bit ARM inferior with a 32-bit ARM GDB on a 64-bit
AArch64 host, only VFP registers (NT_ARM_VFP) are available. The FPA
registers (NT_PRFPREG) are not available so GDB must not request them, as
this will fail with -EINVAL.  This is most noticeably exposed when running
"generate-core-file":

(gdb) generate-core-file myprog.core
Unable to fetch the floating point registers.: Invalid argument.

ptrace(PTRACE_GETREGSET, 27642, NT_FPREGSET, 0xffcc67f0) = -1 EINVAL (Invalid argument)

gdb/ChangeLog:

2017-01-27  Kees Cook  <keescook@google.com>

* gdb/arm-linux-nat.c (arm_linux_fetch_inferior_registers): Call
fetch_fpregs if target has fpa registers.
(arm_linux_store_inferior_registers): Call store_fpregs if target
has fpa registers.

gdb/ChangeLog
gdb/arm-linux-nat.c

index b7ce729..c146e0b 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-27  Kees Cook  <keescook@google.com>
+
+       * gdb/arm-linux-nat.c (arm_linux_fetch_inferior_registers): Call
+       fetch_fpregs if target has fpa registers.
+       (arm_linux_store_inferior_registers): Call store_fpregs if target
+       has fpa registers.
+
 2017-01-26  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
        * cris-tdep.c (cris_gdbarch_init): Remove check for
index 3c48812..c8474a9 100644 (file)
@@ -384,13 +384,14 @@ arm_linux_fetch_inferior_registers (struct target_ops *ops,
   if (-1 == regno)
     {
       fetch_regs (regcache);
-      fetch_fpregs (regcache);
       if (tdep->have_wmmx_registers)
        fetch_wmmx_regs (regcache);
       if (tdep->vfp_register_count > 0)
        fetch_vfp_regs (regcache);
+      if (tdep->have_fpa_registers)
+       fetch_fpregs (regcache);
     }
-  else 
+  else
     {
       if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
        fetch_regs (regcache);
@@ -420,11 +421,12 @@ arm_linux_store_inferior_registers (struct target_ops *ops,
   if (-1 == regno)
     {
       store_regs (regcache);
-      store_fpregs (regcache);
       if (tdep->have_wmmx_registers)
        store_wmmx_regs (regcache);
       if (tdep->vfp_register_count > 0)
        store_vfp_regs (regcache);
+      if (tdep->have_fpa_registers)
+       store_fpregs (regcache);
     }
   else
     {