[v4,3/4] gdbserver: Support read-only regsets in linux-low.c

Message ID 1418379431-14407-4-git-send-email-arnez@linux.vnet.ibm.com
State New, archived
Headers

Commit Message

Andreas Arnez Dec. 12, 2014, 10:16 a.m. UTC
  For GNU/Linux targets using the regsets interface, this change
supports regsets that can be read but not written.  The S390 "last
break" regset is an example.  So far it had been defined with
regset->set_request == PTRACE_GETREGSET, such that the respective
ptrace call does not cause any harm.  Now we just skip the whole
read/modify/write sequence for regsets that do not define a
fill_function.

gdb/gdbserver/ChangeLog:

	* linux-low.c (regsets_store_inferior_registers): Skip regsets
	without a fill_function.
	* linux-s390-low.c (s390_fill_last_break): Remove.
	(s390_regsets): Set fill_function to NULL for NT_S390_LAST_BREAK.
	(s390_arch_setup): Use regset's size instead of fill_function for
	loop end condition.
---
 gdb/gdbserver/linux-low.c      |  3 ++-
 gdb/gdbserver/linux-s390-low.c | 14 ++++----------
 2 files changed, 6 insertions(+), 11 deletions(-)
  

Comments

Pedro Alves Dec. 12, 2014, 12:21 p.m. UTC | #1
On 12/12/2014 10:16 AM, Andreas Arnez wrote:
> For GNU/Linux targets using the regsets interface, this change
> supports regsets that can be read but not written.  The S390 "last
> break" regset is an example.  So far it had been defined with
> regset->set_request == PTRACE_GETREGSET, such that the respective
> ptrace call does not cause any harm.  Now we just skip the whole
> read/modify/write sequence for regsets that do not define a
> fill_function.

Looks good to me.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index c1b53ff..5f62010 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4293,7 +4293,8 @@  regsets_store_inferior_registers (struct regsets_info *regsets_info,
       void *buf, *data;
       int nt_type, res;
 
-      if (regset->size == 0 || regset_disabled (regsets_info, regset))
+      if (regset->size == 0 || regset_disabled (regsets_info, regset)
+	  || regset->fill_function == NULL)
 	continue;
 
       buf = xmalloc (regset->size);
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index 79fa6c0..9f77f30 100644
--- a/gdb/gdbserver/linux-s390-low.c
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -290,12 +290,6 @@  s390_fill_gregset (struct regcache *regcache, void *buf)
 /* Fill and store functions for extended register sets.  */
 
 static void
-s390_fill_last_break (struct regcache *regcache, void *buf)
-{
-  /* Last break address is read-only.  */
-}
-
-static void
 s390_store_last_break (struct regcache *regcache, const void *buf)
 {
   const char *p;
@@ -318,9 +312,9 @@  s390_store_system_call (struct regcache *regcache, const void *buf)
 
 static struct regset_info s390_regsets[] = {
   { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
-  /* Last break address is read-only; do not attempt PTRACE_SETREGSET.  */
-  { PTRACE_GETREGSET, PTRACE_GETREGSET, NT_S390_LAST_BREAK, 0,
-    EXTENDED_REGS, s390_fill_last_break, s390_store_last_break },
+  /* Last break address is read-only; no fill function.  */
+  { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
+    NULL, s390_store_last_break },
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
     EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
   { 0, 0, 0, -1, -1, NULL, NULL }
@@ -485,7 +479,7 @@  s390_arch_setup (void)
 #endif
 
   /* Update target_regsets according to available register sets.  */
-  for (regset = s390_regsets; regset->fill_function != NULL; regset++)
+  for (regset = s390_regsets; regset->size >= 0; regset++)
     if (regset->get_request == PTRACE_GETREGSET)
       switch (regset->nt_type)
 	{