Cleanup value_fetch_lazy's comment and return value
[deliverable/binutils-gdb.git] / gdb / arm-linux-nat.c
index 5c0ede60ad1a25f241aab0387f12bb747678329b..c167bce18b3023b5ba87ec3e047c1dc557bdcb5e 100644 (file)
@@ -36,6 +36,8 @@
 #include <sys/utsname.h>
 #include <sys/procfs.h>
 
+#include "nat/linux-ptrace.h"
+
 /* Prototypes for supply_gregset etc.  */
 #include "gregset.h"
 
@@ -61,9 +63,6 @@
 #define PTRACE_SETHBPREGS 30
 #endif
 
-/* A flag for whether the WMMX registers are available.  */
-static int arm_linux_has_wmmx_registers;
-
 extern int arm_apcs_32;
 
 /* On GNU/Linux, threads are implemented as pseudo-processes, in which
@@ -91,12 +90,23 @@ fetch_fpregister (struct regcache *regcache, int regno)
 {
   int ret, tid;
   gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
-  
+
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
 
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &fp;
+      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
+    }
+  else
+    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch floating point register."));
@@ -124,9 +134,20 @@ fetch_fpregs (struct regcache *regcache)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
+
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &fp;
+      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
+    }
+  else
+    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch the floating point registers."));
@@ -153,9 +174,20 @@ store_fpregister (const struct regcache *regcache, int regno)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
+
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &fp;
+      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
+    }
+  else
+    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch the floating point registers."));
@@ -171,7 +203,18 @@ store_fpregister (const struct regcache *regcache, int regno)
   if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
     collect_nwfpe_register (regcache, regno, fp);
 
-  ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &fp;
+      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
+
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
+
   if (ret < 0)
     {
       warning (_("Unable to store floating point register."));
@@ -190,9 +233,21 @@ store_fpregs (const struct regcache *regcache)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
+
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      elf_fpregset_t fpregs;
+      struct iovec iov;
+
+      iov.iov_base = &fpregs;
+      iov.iov_len = sizeof (fpregs);
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
+    }
+  else
+    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch the floating point registers."));
@@ -208,7 +263,18 @@ store_fpregs (const struct regcache *regcache)
     if (REG_VALID == regcache_register_status (regcache, regno))
       collect_nwfpe_register (regcache, regno, fp);
 
-  ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &fp;
+      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
+
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
+
   if (ret < 0)
     {
       warning (_("Unable to store floating point registers."));
@@ -227,8 +293,19 @@ fetch_register (struct regcache *regcache, int regno)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
-  ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &regs;
+      iov.iov_len = sizeof (regs);
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch general register."));
@@ -269,8 +346,19 @@ fetch_regs (struct regcache *regcache)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
-  ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &regs;
+      iov.iov_len = sizeof (regs);
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch general registers."));
@@ -307,9 +395,20 @@ store_register (const struct regcache *regcache, int regno)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
+
   /* Get the general registers from the process.  */
-  ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &regs;
+      iov.iov_len = sizeof (regs);
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch general registers."));
@@ -325,7 +424,18 @@ store_register (const struct regcache *regcache, int regno)
     regcache_raw_collect (regcache, ARM_PC_REGNUM,
                         (char *) &regs[ARM_PC_REGNUM]);
 
-  ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &regs;
+      iov.iov_len = sizeof (regs);
+
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
+
   if (ret < 0)
     {
       warning (_("Unable to store general register."));
@@ -341,9 +451,20 @@ store_regs (const struct regcache *regcache)
 
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
-  
+
   /* Fetch the general registers.  */
-  ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &regs;
+      iov.iov_len = sizeof (regs);
+
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch general registers."));
@@ -360,7 +481,17 @@ store_regs (const struct regcache *regcache)
     regcache_raw_collect (regcache, ARM_PS_REGNUM,
                         (char *) &regs[ARM_CPSR_GREGNUM]);
 
-  ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = &regs;
+      iov.iov_len = sizeof (regs);
+
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
 
   if (ret < 0)
     {
@@ -462,7 +593,17 @@ fetch_vfp_regs (struct regcache *regcache)
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
 
-  ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = regbuf;
+      iov.iov_len = VFP_REGS_SIZE;
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch VFP registers."));
@@ -488,7 +629,17 @@ store_vfp_regs (const struct regcache *regcache)
   /* Get the thread id for the ptrace call.  */
   tid = GET_THREAD_ID (inferior_ptid);
 
-  ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = regbuf;
+      iov.iov_len = VFP_REGS_SIZE;
+      ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf);
+
   if (ret < 0)
     {
       warning (_("Unable to fetch VFP registers (for update)."));
@@ -502,7 +653,16 @@ store_vfp_regs (const struct regcache *regcache)
   regcache_raw_collect (regcache, ARM_FPSCR_REGNUM,
                        (char *) regbuf + 32 * 8);
 
-  ret = ptrace (PTRACE_SETVFPREGS, tid, 0, regbuf);
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    {
+      struct iovec iov;
+
+      iov.iov_base = regbuf;
+      iov.iov_len = VFP_REGS_SIZE;
+      ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_VFP, &iov);
+    }
+  else
+    ret = ptrace (PTRACE_SETVFPREGS, tid, 0, regbuf);
 
   if (ret < 0)
     {
@@ -526,7 +686,7 @@ arm_linux_fetch_inferior_registers (struct target_ops *ops,
     {
       fetch_regs (regcache);
       fetch_fpregs (regcache);
-      if (arm_linux_has_wmmx_registers)
+      if (tdep->have_wmmx_registers)
        fetch_wmmx_regs (regcache);
       if (tdep->vfp_register_count > 0)
        fetch_vfp_regs (regcache);
@@ -537,7 +697,7 @@ arm_linux_fetch_inferior_registers (struct target_ops *ops,
         fetch_register (regcache, regno);
       else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
         fetch_fpregister (regcache, regno);
-      else if (arm_linux_has_wmmx_registers
+      else if (tdep->have_wmmx_registers
               && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
        fetch_wmmx_regs (regcache);
       else if (tdep->vfp_register_count > 0
@@ -562,7 +722,7 @@ arm_linux_store_inferior_registers (struct target_ops *ops,
     {
       store_regs (regcache);
       store_fpregs (regcache);
-      if (arm_linux_has_wmmx_registers)
+      if (tdep->have_wmmx_registers)
        store_wmmx_regs (regcache);
       if (tdep->vfp_register_count > 0)
        store_vfp_regs (regcache);
@@ -573,7 +733,7 @@ arm_linux_store_inferior_registers (struct target_ops *ops,
         store_register (regcache, regno);
       else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
         store_fpregister (regcache, regno);
-      else if (arm_linux_has_wmmx_registers
+      else if (tdep->have_wmmx_registers
               && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
        store_wmmx_regs (regcache);
       else if (tdep->vfp_register_count > 0
@@ -636,7 +796,22 @@ static const struct target_desc *
 arm_linux_read_description (struct target_ops *ops)
 {
   CORE_ADDR arm_hwcap = 0;
-  arm_linux_has_wmmx_registers = 0;
+
+  if (have_ptrace_getregset == TRIBOOL_UNKNOWN)
+    {
+      elf_gregset_t gpregs;
+      struct iovec iov;
+      int tid = GET_THREAD_ID (inferior_ptid);
+
+      iov.iov_base = &gpregs;
+      iov.iov_len = sizeof (gpregs);
+
+      /* Check if PTRACE_GETREGSET works.  */
+      if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov) < 0)
+       have_ptrace_getregset = TRIBOOL_FALSE;
+      else
+       have_ptrace_getregset = TRIBOOL_TRUE;
+    }
 
   if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1)
     {
@@ -644,10 +819,7 @@ arm_linux_read_description (struct target_ops *ops)
     }
 
   if (arm_hwcap & HWCAP_IWMMXT)
-    {
-      arm_linux_has_wmmx_registers = 1;
-      return tdesc_arm_with_iwmmxt;
-    }
+    return tdesc_arm_with_iwmmxt;
 
   if (arm_hwcap & HWCAP_VFP)
     {
This page took 0.029112 seconds and 4 git commands to generate.