[2/5] fbsd-nat: Add helper functions to fetch and store register sets.

Message ID 20210528202614.2081-3-jhb@FreeBSD.org
State New
Headers show
Series
  • Add helper functions for FreeBSD native targets
Related show

Commit Message

John Baldwin May 28, 2021, 8:26 p.m.
In particular, this supports register sets described by a regcache_map
which are fetched and stored with dedicated ptrace operations.  These
functions are intended to be used in architecture-specific
fetch_registers and store_registers target methods.

gdb/ChangeLog:

	* fbsd-nat.h (fetch_register_set, store_register_set): New.
---
 gdb/ChangeLog  |  4 ++++
 gdb/fbsd-nat.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

-- 
2.31.1

Comments

Pedro Alves July 10, 2021, 7:42 p.m. | #1
On 2021-05-28 9:26 p.m., John Baldwin wrote:
> In particular, this supports register sets described by a regcache_map

> which are fetched and stored with dedicated ptrace operations.  These

> functions are intended to be used in architecture-specific

> fetch_registers and store_registers target methods.

> 

> gdb/ChangeLog:

> 

> 	* fbsd-nat.h (fetch_register_set, store_register_set): New.

> ---

>  gdb/ChangeLog  |  4 ++++

>  gdb/fbsd-nat.h | 44 ++++++++++++++++++++++++++++++++++++++++++++

>  2 files changed, 48 insertions(+)

> 

> diff --git a/gdb/ChangeLog b/gdb/ChangeLog

> index 2e61aead178..cb48a7f242d 100644

> --- a/gdb/ChangeLog

> +++ b/gdb/ChangeLog

> @@ -1,3 +1,7 @@

> +2021-05-28  John Baldwin <jhb@FreeBSD.org>

> +

> +	* fbsd-nat.h (fetch_register_set, store_register_set): New.

> +

>  2021-05-28  John Baldwin <jhb@FreeBSD.org>

>  

>  	* regcache.c (regcache_map_supplies): New.

> diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h

> index 772655d320e..3cca361df4a 100644

> --- a/gdb/fbsd-nat.h

> +++ b/gdb/fbsd-nat.h

> @@ -21,6 +21,8 @@

>  #define FBSD_NAT_H

>  

>  #include "inf-ptrace.h"

> +#include "regcache.h"

> +#include "regset.h"

>  #include <osreldate.h>

>  #include <sys/proc.h>

>  

> @@ -98,6 +100,48 @@ class fbsd_nat_target : public inf_ptrace_target

>  #endif

>  

>    bool supports_multi_process () override;

> +

> +protected:

> +  template <class R>

> +  void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op,

> +			   const struct regset *regset)

> +  {

> +    const struct regcache_map_entry *map =

> +      (const struct regcache_map_entry *) regset->regmap;

> +    pid_t pid = get_ptrace_pid (regcache->ptid ());

> +    R regs;

> +

> +    if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),

> +					       sizeof(regs)))

> +      {

> +	if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)

> +	  perror_with_name (_("Couldn't get registers"));

> +

> +	regcache->supply_regset (regset, regnum, &regs, sizeof (regs));

> +      }

> +  }


BTW, AFAICT, you could de-duplicate most of this template function by splitting
it in two, with the main worker part not needing doesn't need to care about R's type.
Something like:

private:
  void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op,
			   const struct regset *regset, 
			   void *regs, size_t sizeof_regs)
  {
    const struct regcache_map_entry *map =
      (const struct regcache_map_entry *) regset->regmap;
    pid_t pid = get_ptrace_pid (regcache->ptid ());

    if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
					       sizeof_regs))
      {
	if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1)
	  perror_with_name (_("Couldn't get registers"));

	regcache->supply_regset (regset, regnum, regs, sizeof (regs));
      }
  }

protected:
  template <class R>
  void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op,
			   const struct regset *regset)
  {
    R regs;
    fetch_register_set (regcache, regnum, fetch_op, regset, 
			&regs, sizeof (regs));
  }
John Baldwin July 12, 2021, 3:56 p.m. | #2
On 7/10/21 12:42 PM, Pedro Alves wrote:
> On 2021-05-28 9:26 p.m., John Baldwin wrote:

>> In particular, this supports register sets described by a regcache_map

>> which are fetched and stored with dedicated ptrace operations.  These

>> functions are intended to be used in architecture-specific

>> fetch_registers and store_registers target methods.

>>

>> gdb/ChangeLog:

>>

>> 	* fbsd-nat.h (fetch_register_set, store_register_set): New.

>> ---

>>   gdb/ChangeLog  |  4 ++++

>>   gdb/fbsd-nat.h | 44 ++++++++++++++++++++++++++++++++++++++++++++

>>   2 files changed, 48 insertions(+)

>>

>> diff --git a/gdb/ChangeLog b/gdb/ChangeLog

>> index 2e61aead178..cb48a7f242d 100644

>> --- a/gdb/ChangeLog

>> +++ b/gdb/ChangeLog

>> @@ -1,3 +1,7 @@

>> +2021-05-28  John Baldwin <jhb@FreeBSD.org>

>> +

>> +	* fbsd-nat.h (fetch_register_set, store_register_set): New.

>> +

>>   2021-05-28  John Baldwin <jhb@FreeBSD.org>

>>   

>>   	* regcache.c (regcache_map_supplies): New.

>> diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h

>> index 772655d320e..3cca361df4a 100644

>> --- a/gdb/fbsd-nat.h

>> +++ b/gdb/fbsd-nat.h

>> @@ -21,6 +21,8 @@

>>   #define FBSD_NAT_H

>>   

>>   #include "inf-ptrace.h"

>> +#include "regcache.h"

>> +#include "regset.h"

>>   #include <osreldate.h>

>>   #include <sys/proc.h>

>>   

>> @@ -98,6 +100,48 @@ class fbsd_nat_target : public inf_ptrace_target

>>   #endif

>>   

>>     bool supports_multi_process () override;

>> +

>> +protected:

>> +  template <class R>

>> +  void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op,

>> +			   const struct regset *regset)

>> +  {

>> +    const struct regcache_map_entry *map =

>> +      (const struct regcache_map_entry *) regset->regmap;

>> +    pid_t pid = get_ptrace_pid (regcache->ptid ());

>> +    R regs;

>> +

>> +    if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),

>> +					       sizeof(regs)))

>> +      {

>> +	if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)

>> +	  perror_with_name (_("Couldn't get registers"));

>> +

>> +	regcache->supply_regset (regset, regnum, &regs, sizeof (regs));

>> +      }

>> +  }

> 

> BTW, AFAICT, you could de-duplicate most of this template function by splitting

> it in two, with the main worker part not needing doesn't need to care about R's type.

> Something like:


I've done that (with the change of putting the private methods in the .c file
itself) along with fixing the style things.  I've just mailed it out as a V2 of
the series (easier to see the result).  Thanks!

-- 
John Baldwin

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2e61aead178..cb48a7f242d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@ 
+2021-05-28  John Baldwin <jhb@FreeBSD.org>
+
+	* fbsd-nat.h (fetch_register_set, store_register_set): New.
+
 2021-05-28  John Baldwin <jhb@FreeBSD.org>
 
 	* regcache.c (regcache_map_supplies): New.
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index 772655d320e..3cca361df4a 100644
--- a/gdb/fbsd-nat.h
+++ b/gdb/fbsd-nat.h
@@ -21,6 +21,8 @@ 
 #define FBSD_NAT_H
 
 #include "inf-ptrace.h"
+#include "regcache.h"
+#include "regset.h"
 #include <osreldate.h>
 #include <sys/proc.h>
 
@@ -98,6 +100,48 @@  class fbsd_nat_target : public inf_ptrace_target
 #endif
 
   bool supports_multi_process () override;
+
+protected:
+  template <class R>
+  void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op,
+			   const struct regset *regset)
+  {
+    const struct regcache_map_entry *map =
+      (const struct regcache_map_entry *) regset->regmap;
+    pid_t pid = get_ptrace_pid (regcache->ptid ());
+    R regs;
+
+    if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
+					       sizeof(regs)))
+      {
+	if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+	  perror_with_name (_("Couldn't get registers"));
+
+	regcache->supply_regset (regset, regnum, &regs, sizeof (regs));
+      }
+  }
+
+  template <class R>
+  void store_register_set (struct regcache *regcache, int regnum, int fetch_op,
+			   int store_op, const struct regset *regset)
+  {
+    const struct regcache_map_entry *map =
+      (const struct regcache_map_entry *) regset->regmap;
+    pid_t pid = get_ptrace_pid (regcache->ptid ());
+    R regs;
+
+    if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
+					       sizeof(regs)))
+      {
+	if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+	  perror_with_name (_("Couldn't get registers"));
+
+	regcache->collect_regset (regset, regnum, &regs, sizeof (regs));
+
+	if (ptrace (store_op, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+	  perror_with_name (_("Couldn't write registers"));
+      }
+  }
 };
 
 #endif /* fbsd-nat.h */