diff mbox

[5/6] Fetch and store FP registers by PTRACE_{G,S}ETREGSET

Message ID 1432822816-32327-6-git-send-email-yao.qi@linaro.org
State New
Headers show

Commit Message

Yao Qi May 28, 2015, 2:20 p.m. UTC
If kernel supports PTRACE_GETREGSET, GDB uses PTRACE_{G,S}ETREGSET
to fetch and store FP registers.

gdb:

2015-05-28  Yao Qi  <yao.qi@linaro.org>

	* arm-linux-nat.c (fetch_fpregister): Use PTRACE_GETREGSET.
	(fetch_fpregs): Likewise.
	* arm-linux-nat.c (store_fpregister): Use PTRACE_SETREGSET.
	(store_fpregs): Likewise.
---
 gdb/arm-linux-nat.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 74 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 0a86ed6..b74767c 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -88,12 +88,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 == 1)
+    {
+      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."));
@@ -123,7 +134,18 @@  fetch_fpregs (struct regcache *regcache)
   tid = GET_THREAD_ID (inferior_ptid);
   
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == 1)
+    {
+      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."));
@@ -152,7 +174,18 @@  store_fpregister (const struct regcache *regcache, int regno)
   tid = GET_THREAD_ID (inferior_ptid);
   
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == 1)
+    {
+      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."));
@@ -168,7 +201,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 == 1)
+    {
+      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."));
@@ -189,7 +233,19 @@  store_fpregs (const struct regcache *regcache)
   tid = GET_THREAD_ID (inferior_ptid);
   
   /* Read the floating point state.  */
-  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
+  if (have_ptrace_getregset == 1)
+    {
+      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."));
@@ -205,7 +261,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 == 1)
+    {
+      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."));