[v2,4/4] Add native target for FreeBSD/riscv.

Message ID 20180924205151.22217-5-jhb@FreeBSD.org
State New, archived
Headers

Commit Message

John Baldwin Sept. 24, 2018, 8:51 p.m. UTC
  gdb/ChangeLog:

	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.
	* NEWS: Mention new FreeBSD/riscv native configuration.
	* configure.host: Add riscv*-*-freebsd*.
	* configure.nat: Likewise.
	* riscv-fbsd-nat.c: New file.

gdb/doc/ChangeLog:

	* gdb.texinfo (Contributors): Add SRI International and University
	of Cambridge for FreeBSD/riscv.
---
 gdb/ChangeLog        |   8 +++
 gdb/Makefile.in      |   1 +
 gdb/NEWS             |   1 +
 gdb/configure.host   |   1 +
 gdb/configure.nat    |   4 ++
 gdb/doc/ChangeLog    |   5 ++
 gdb/doc/gdb.texinfo  |   6 ++
 gdb/riscv-fbsd-nat.c | 135 +++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 161 insertions(+)
 create mode 100644 gdb/riscv-fbsd-nat.c
  

Comments

Eli Zaretskii Sept. 24, 2018, 9:16 p.m. UTC | #1
> From: John Baldwin <jhb@FreeBSD.org>
> Cc: andrew.burgess@embecosm.com,	jimw@sifive.com
> Date: Mon, 24 Sep 2018 13:51:51 -0700
> 
> gdb/ChangeLog:
> 
> 	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.
> 	* NEWS: Mention new FreeBSD/riscv native configuration.
> 	* configure.host: Add riscv*-*-freebsd*.
> 	* configure.nat: Likewise.
> 	* riscv-fbsd-nat.c: New file.
> 
> gdb/doc/ChangeLog:
> 
> 	* gdb.texinfo (Contributors): Add SRI International and University
> 	of Cambridge for FreeBSD/riscv.

OK for the documentation parts.

Thanks.
  
Simon Marchi Sept. 27, 2018, 8:04 p.m. UTC | #2
On 2018-09-24 04:51 PM, John Baldwin wrote:
> gdb/ChangeLog:

> 

> 	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.

> 	* NEWS: Mention new FreeBSD/riscv native configuration.

> 	* configure.host: Add riscv*-*-freebsd*.

> 	* configure.nat: Likewise.

> 	* riscv-fbsd-nat.c: New file.

> 

> gdb/doc/ChangeLog:

> 

> 	* gdb.texinfo (Contributors): Add SRI International and University

> 	of Cambridge for FreeBSD/riscv.

> ---

>  gdb/ChangeLog        |   8 +++

>  gdb/Makefile.in      |   1 +

>  gdb/NEWS             |   1 +

>  gdb/configure.host   |   1 +

>  gdb/configure.nat    |   4 ++

>  gdb/doc/ChangeLog    |   5 ++

>  gdb/doc/gdb.texinfo  |   6 ++

>  gdb/riscv-fbsd-nat.c | 135 +++++++++++++++++++++++++++++++++++++++++++

>  8 files changed, 161 insertions(+)

>  create mode 100644 gdb/riscv-fbsd-nat.c

> 

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

> index 1367f37db7..19c63706e9 100644

> --- a/gdb/ChangeLog

> +++ b/gdb/ChangeLog

> @@ -1,3 +1,11 @@

> +2018-09-24  John Baldwin  <jhb@FreeBSD.org>

> +

> +	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.

> +	* NEWS: Mention new FreeBSD/riscv native configuration.

> +	* configure.host: Add riscv*-*-freebsd*.

> +	* configure.nat: Likewise.

> +	* riscv-fbsd-nat.c: New file.

> +

>  2018-09-24  John Baldwin  <jhb@FreeBSD.org>

>  

>  	* Makefile.in (ALL_TARGET_OBS): Add riscv-fbsd-tdep.o.

> diff --git a/gdb/Makefile.in b/gdb/Makefile.in

> index 2e03bb956c..13a8e16eec 100644

> --- a/gdb/Makefile.in

> +++ b/gdb/Makefile.in

> @@ -2308,6 +2308,7 @@ ALLDEPFILES = \

>  	procfs.c \

>  	ravenscar-thread.c \

>  	remote-sim.c \

> +	riscv-fbsd-nat.c \

>  	riscv-fbsd-tdep.c \

>  	riscv-linux-nat.c \

>  	riscv-linux-tdep.c \

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

> index a191ae2714..4ae3adedc0 100644

> --- a/gdb/NEWS

> +++ b/gdb/NEWS

> @@ -80,6 +80,7 @@ thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND

>  * New native configurations

>  

>  GNU/Linux/RISC-V		riscv*-*-linux*

> +FreeBSD/riscv			riscv*-*-freebsd*


I just noticed that we write RISC-V in two different ways for GNU/Linux and
FreeBSD: RISC-V and riscv.  It's not a big deal, but it looks a bit inconsistent.

Otherwise everything looks good to me, but again I think the RISC-V ninjas should take a look.

Simon
  
Jim Wilson Sept. 27, 2018, 8:21 p.m. UTC | #3
On Thu, Sep 27, 2018 at 1:04 PM Simon Marchi <simon.marchi@ericsson.com> wrote:
> > --- a/gdb/NEWS
> > +++ b/gdb/NEWS
> > @@ -80,6 +80,7 @@ thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND
> >  * New native configurations
> >
> >  GNU/Linux/RISC-V             riscv*-*-linux*
> > +FreeBSD/riscv                        riscv*-*-freebsd*
>
> I just noticed that we write RISC-V in two different ways for GNU/Linux and
> FreeBSD: RISC-V and riscv.  It's not a big deal, but it looks a bit inconsistent.
>
> Otherwise everything looks good to me, but again I think the RISC-V ninjas should take a look.

RISC-V is the official spelling of the architecture name, and riscv is
what we use for configure triplets.  I try to use the official
spelling whenever possible which is why I used RISC-V here.

Jim
  
Andrew Burgess Sept. 28, 2018, 10:58 a.m. UTC | #4
* John Baldwin <jhb@FreeBSD.org> [2018-09-24 13:51:51 -0700]:

> gdb/ChangeLog:
> 
> 	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.
> 	* NEWS: Mention new FreeBSD/riscv native configuration.
> 	* configure.host: Add riscv*-*-freebsd*.
> 	* configure.nat: Likewise.
> 	* riscv-fbsd-nat.c: New file.
> 
> gdb/doc/ChangeLog:
> 
> 	* gdb.texinfo (Contributors): Add SRI International and University
> 	of Cambridge for FreeBSD/riscv.

I'm happy with these being merged.

Thanks,
Andrew



> ---
>  gdb/ChangeLog        |   8 +++
>  gdb/Makefile.in      |   1 +
>  gdb/NEWS             |   1 +
>  gdb/configure.host   |   1 +
>  gdb/configure.nat    |   4 ++
>  gdb/doc/ChangeLog    |   5 ++
>  gdb/doc/gdb.texinfo  |   6 ++
>  gdb/riscv-fbsd-nat.c | 135 +++++++++++++++++++++++++++++++++++++++++++
>  8 files changed, 161 insertions(+)
>  create mode 100644 gdb/riscv-fbsd-nat.c
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 1367f37db7..19c63706e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,11 @@
> +2018-09-24  John Baldwin  <jhb@FreeBSD.org>
> +
> +	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.
> +	* NEWS: Mention new FreeBSD/riscv native configuration.
> +	* configure.host: Add riscv*-*-freebsd*.
> +	* configure.nat: Likewise.
> +	* riscv-fbsd-nat.c: New file.
> +
>  2018-09-24  John Baldwin  <jhb@FreeBSD.org>
>  
>  	* Makefile.in (ALL_TARGET_OBS): Add riscv-fbsd-tdep.o.
> diff --git a/gdb/Makefile.in b/gdb/Makefile.in
> index 2e03bb956c..13a8e16eec 100644
> --- a/gdb/Makefile.in
> +++ b/gdb/Makefile.in
> @@ -2308,6 +2308,7 @@ ALLDEPFILES = \
>  	procfs.c \
>  	ravenscar-thread.c \
>  	remote-sim.c \
> +	riscv-fbsd-nat.c \
>  	riscv-fbsd-tdep.c \
>  	riscv-linux-nat.c \
>  	riscv-linux-tdep.c \
> diff --git a/gdb/NEWS b/gdb/NEWS
> index a191ae2714..4ae3adedc0 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -80,6 +80,7 @@ thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND
>  * New native configurations
>  
>  GNU/Linux/RISC-V		riscv*-*-linux*
> +FreeBSD/riscv			riscv*-*-freebsd*
>  
>  * New targets
>  
> diff --git a/gdb/configure.host b/gdb/configure.host
> index 23a2f16399..c87f997abc 100644
> --- a/gdb/configure.host
> +++ b/gdb/configure.host
> @@ -149,6 +149,7 @@ powerpc64*-*-linux*)	gdb_host=ppc64-linux
>  			;;
>  powerpc*-*-linux*)	gdb_host=linux ;;
>  
> +riscv*-*-freebsd*)	gdb_host=fbsd ;;
>  riscv*-*-linux*)	gdb_host=linux ;;
>  
>  s390*-*-linux*)		gdb_host=linux ;;
> diff --git a/gdb/configure.nat b/gdb/configure.nat
> index 10bf65fec3..200b716924 100644
> --- a/gdb/configure.nat
> +++ b/gdb/configure.nat
> @@ -177,6 +177,10 @@ case ${gdb_host} in
>  		# systems running FreeBSD.
>  		NATDEPFILES="${NATDEPFILES} ppc-fbsd-nat.o bsd-kvm.o"
>  		;;
> +	    riscv*)
> +		# Host: FreeBSD/riscv
> +		NATDEPFILES="${NATDEPFILES} riscv-fbsd-nat.o"
> +		;;
>  	    sparc)
>  		# Host: FreeBSD/sparc64
>  		NATDEPFILES="${NATDEPFILES} sparc-nat.o sparc64-nat.o \
> diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
> index 4285a4d8bb..0197650c6a 100644
> --- a/gdb/doc/ChangeLog
> +++ b/gdb/doc/ChangeLog
> @@ -1,3 +1,8 @@
> +2018-09-24  John Baldwin  <jhb@FreeBSD.org>
> +
> +	* gdb.texinfo (Contributors): Add SRI International and University
> +	of Cambridge for FreeBSD/riscv.
> +
>  2018-09-23  Tom Tromey  <tom@tromey.com>
>  
>  	PR python/18852:
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index b5b6089153..b8af74e949 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -546,6 +546,12 @@ was developed by SRI International and the University of Cambridge
>  Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
>  ("CTSRD"), as part of the DARPA CRASH research programme.
>  
> +Initial support for the FreeBSD/riscv target and native configuration
> +was developed by SRI International and the University of Cambridge
> +Computer Laboratory (Department of Computer Science and Technology)
> +under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the DARPA
> +SSITH research programme.
> +
>  The original port to the OpenRISC 1000 is believed to be due to
>  Alessandro Forin and Per Bothner.  More recent ports have been the work
>  of Jeremy Bennett, Franck Jullien, Stefan Wallentowitz and
> diff --git a/gdb/riscv-fbsd-nat.c b/gdb/riscv-fbsd-nat.c
> new file mode 100644
> index 0000000000..ad4ea1e0ad
> --- /dev/null
> +++ b/gdb/riscv-fbsd-nat.c
> @@ -0,0 +1,135 @@
> +/* Native-dependent code for FreeBSD/riscv.
> +
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include "defs.h"
> +#include "target.h"
> +
> +#include <sys/types.h>
> +#include <sys/ptrace.h>
> +#include <machine/reg.h>
> +
> +#include "fbsd-nat.h"
> +#include "riscv-tdep.h"
> +#include "riscv-fbsd-tdep.h"
> +#include "inf-ptrace.h"
> +
> +struct riscv_fbsd_nat_target final : public fbsd_nat_target
> +{
> +  void fetch_registers (struct regcache *, int) override;
> +  void store_registers (struct regcache *, int) override;
> +};
> +
> +static riscv_fbsd_nat_target the_riscv_fbsd_nat_target;
> +
> +/* Determine if PT_GETREGS fetches REGNUM.  */
> +
> +static bool
> +getregs_supplies (struct gdbarch *gdbarch, int regnum)
> +{
> +  return (regnum >= RISCV_RA_REGNUM && regnum <= RISCV_PC_REGNUM);
> +}
> +
> +/* Determine if PT_GETFPREGS fetches REGNUM.  */
> +
> +static bool
> +getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
> +{
> +  return ((regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM)
> +	  || regnum == RISCV_CSR_FCSR_REGNUM);
> +}
> +
> +/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
> +   for all registers.  */
> +
> +void
> +riscv_fbsd_nat_target::fetch_registers (struct regcache *regcache,
> +					int regnum)
> +{
> +  pid_t pid = get_ptrace_pid (regcache->ptid ());
> +
> +  struct gdbarch *gdbarch = regcache->arch ();
> +  if (regnum == -1 || regnum == RISCV_ZERO_REGNUM)
> +    regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM);
> +  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
> +    {
> +      struct reg regs;
> +
> +      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
> +	perror_with_name (_("Couldn't get registers"));
> +
> +      regcache->supply_regset (&riscv_fbsd_gregset, regnum, &regs,
> +			       sizeof (regs));
> +    }
> +
> +  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
> +    {
> +      struct fpreg fpregs;
> +
> +      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
> +	perror_with_name (_("Couldn't get floating point status"));
> +
> +      regcache->supply_regset (&riscv_fbsd_fpregset, regnum, &fpregs,
> +			       sizeof (fpregs));
> +    }
> +}
> +
> +/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
> +   this for all registers.  */
> +
> +void
> +riscv_fbsd_nat_target::store_registers (struct regcache *regcache,
> +					int regnum)
> +{
> +  pid_t pid = get_ptrace_pid (regcache->ptid ());
> +
> +  struct gdbarch *gdbarch = regcache->arch ();
> +  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
> +    {
> +      struct reg regs;
> +
> +      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
> +	perror_with_name (_("Couldn't get registers"));
> +
> +      regcache->collect_regset (&riscv_fbsd_gregset, regnum, &regs,
> +			       sizeof (regs));
> +
> +      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
> +	perror_with_name (_("Couldn't write registers"));
> +    }
> +
> +  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
> +    {
> +      struct fpreg fpregs;
> +
> +      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
> +	perror_with_name (_("Couldn't get floating point status"));
> +
> +      regcache->collect_regset (&riscv_fbsd_fpregset, regnum, &fpregs,
> +				sizeof (fpregs));
> +
> +      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
> +	perror_with_name (_("Couldn't write floating point status"));
> +    }
> +}
> +
> +void
> +_initialize_riscv_fbsd_nat (void)
> +{
> +  add_inf_child_target (&the_riscv_fbsd_nat_target);
> +}
> -- 
> 2.18.0
>
  
John Baldwin Sept. 28, 2018, 4:18 p.m. UTC | #5
On 9/27/18 1:04 PM, Simon Marchi wrote:
> On 2018-09-24 04:51 PM, John Baldwin wrote:
>> diff --git a/gdb/NEWS b/gdb/NEWS
>> index a191ae2714..4ae3adedc0 100644
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -80,6 +80,7 @@ thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND
>>  * New native configurations
>>  
>>  GNU/Linux/RISC-V		riscv*-*-linux*
>> +FreeBSD/riscv			riscv*-*-freebsd*
> 
> I just noticed that we write RISC-V in two different ways for GNU/Linux and
> FreeBSD: RISC-V and riscv.  It's not a big deal, but it looks a bit inconsistent.

To date when describing new FreeBSD targets in NEWS I have used the nomenclature
FreeBSD uses which is generally "FreeBSD/<arch>" where FreeBSD sometimes uses
different arch names (e.g. "amd64" instead of "x86-64", but also lowercase "mips"
vs "MIPS" as used for Linux or "aarch64" vs "AArch64").  It's the string that
shows up in most FreeBSD documentation for a given platform as well as at login
prompts on ttys, etc.  To that end it's kind of the closest thing FreeBSD has for
naming a port of FreeBSD to a given platform.  I had assumed that would be the
clearest way to describe FreeBSD targets.  It's just a cosmetic thing though.
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1367f37db7..19c63706e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@ 
+2018-09-24  John Baldwin  <jhb@FreeBSD.org>
+
+	* Makefile.in (ALLDEPFILES): Add riscv-fbsd-nat.c.
+	* NEWS: Mention new FreeBSD/riscv native configuration.
+	* configure.host: Add riscv*-*-freebsd*.
+	* configure.nat: Likewise.
+	* riscv-fbsd-nat.c: New file.
+
 2018-09-24  John Baldwin  <jhb@FreeBSD.org>
 
 	* Makefile.in (ALL_TARGET_OBS): Add riscv-fbsd-tdep.o.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 2e03bb956c..13a8e16eec 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2308,6 +2308,7 @@  ALLDEPFILES = \
 	procfs.c \
 	ravenscar-thread.c \
 	remote-sim.c \
+	riscv-fbsd-nat.c \
 	riscv-fbsd-tdep.c \
 	riscv-linux-nat.c \
 	riscv-linux-tdep.c \
diff --git a/gdb/NEWS b/gdb/NEWS
index a191ae2714..4ae3adedc0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -80,6 +80,7 @@  thread apply [all | COUNT | -COUNT] [FLAG]... COMMAND
 * New native configurations
 
 GNU/Linux/RISC-V		riscv*-*-linux*
+FreeBSD/riscv			riscv*-*-freebsd*
 
 * New targets
 
diff --git a/gdb/configure.host b/gdb/configure.host
index 23a2f16399..c87f997abc 100644
--- a/gdb/configure.host
+++ b/gdb/configure.host
@@ -149,6 +149,7 @@  powerpc64*-*-linux*)	gdb_host=ppc64-linux
 			;;
 powerpc*-*-linux*)	gdb_host=linux ;;
 
+riscv*-*-freebsd*)	gdb_host=fbsd ;;
 riscv*-*-linux*)	gdb_host=linux ;;
 
 s390*-*-linux*)		gdb_host=linux ;;
diff --git a/gdb/configure.nat b/gdb/configure.nat
index 10bf65fec3..200b716924 100644
--- a/gdb/configure.nat
+++ b/gdb/configure.nat
@@ -177,6 +177,10 @@  case ${gdb_host} in
 		# systems running FreeBSD.
 		NATDEPFILES="${NATDEPFILES} ppc-fbsd-nat.o bsd-kvm.o"
 		;;
+	    riscv*)
+		# Host: FreeBSD/riscv
+		NATDEPFILES="${NATDEPFILES} riscv-fbsd-nat.o"
+		;;
 	    sparc)
 		# Host: FreeBSD/sparc64
 		NATDEPFILES="${NATDEPFILES} sparc-nat.o sparc64-nat.o \
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 4285a4d8bb..0197650c6a 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@ 
+2018-09-24  John Baldwin  <jhb@FreeBSD.org>
+
+	* gdb.texinfo (Contributors): Add SRI International and University
+	of Cambridge for FreeBSD/riscv.
+
 2018-09-23  Tom Tromey  <tom@tromey.com>
 
 	PR python/18852:
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b5b6089153..b8af74e949 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -546,6 +546,12 @@  was developed by SRI International and the University of Cambridge
 Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
 ("CTSRD"), as part of the DARPA CRASH research programme.
 
+Initial support for the FreeBSD/riscv target and native configuration
+was developed by SRI International and the University of Cambridge
+Computer Laboratory (Department of Computer Science and Technology)
+under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the DARPA
+SSITH research programme.
+
 The original port to the OpenRISC 1000 is believed to be due to
 Alessandro Forin and Per Bothner.  More recent ports have been the work
 of Jeremy Bennett, Franck Jullien, Stefan Wallentowitz and
diff --git a/gdb/riscv-fbsd-nat.c b/gdb/riscv-fbsd-nat.c
new file mode 100644
index 0000000000..ad4ea1e0ad
--- /dev/null
+++ b/gdb/riscv-fbsd-nat.c
@@ -0,0 +1,135 @@ 
+/* Native-dependent code for FreeBSD/riscv.
+
+   Copyright (C) 2018 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "target.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "fbsd-nat.h"
+#include "riscv-tdep.h"
+#include "riscv-fbsd-tdep.h"
+#include "inf-ptrace.h"
+
+struct riscv_fbsd_nat_target final : public fbsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static riscv_fbsd_nat_target the_riscv_fbsd_nat_target;
+
+/* Determine if PT_GETREGS fetches REGNUM.  */
+
+static bool
+getregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+  return (regnum >= RISCV_RA_REGNUM && regnum <= RISCV_PC_REGNUM);
+}
+
+/* Determine if PT_GETFPREGS fetches REGNUM.  */
+
+static bool
+getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
+{
+  return ((regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM)
+	  || regnum == RISCV_CSR_FCSR_REGNUM);
+}
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.  */
+
+void
+riscv_fbsd_nat_target::fetch_registers (struct regcache *regcache,
+					int regnum)
+{
+  pid_t pid = get_ptrace_pid (regcache->ptid ());
+
+  struct gdbarch *gdbarch = regcache->arch ();
+  if (regnum == -1 || regnum == RISCV_ZERO_REGNUM)
+    regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM);
+  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+    {
+      struct reg regs;
+
+      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+	perror_with_name (_("Couldn't get registers"));
+
+      regcache->supply_regset (&riscv_fbsd_gregset, regnum, &regs,
+			       sizeof (regs));
+    }
+
+  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
+    {
+      struct fpreg fpregs;
+
+      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+	perror_with_name (_("Couldn't get floating point status"));
+
+      regcache->supply_regset (&riscv_fbsd_fpregset, regnum, &fpregs,
+			       sizeof (fpregs));
+    }
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers.  */
+
+void
+riscv_fbsd_nat_target::store_registers (struct regcache *regcache,
+					int regnum)
+{
+  pid_t pid = get_ptrace_pid (regcache->ptid ());
+
+  struct gdbarch *gdbarch = regcache->arch ();
+  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
+    {
+      struct reg regs;
+
+      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+	perror_with_name (_("Couldn't get registers"));
+
+      regcache->collect_regset (&riscv_fbsd_gregset, regnum, &regs,
+			       sizeof (regs));
+
+      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+	perror_with_name (_("Couldn't write registers"));
+    }
+
+  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
+    {
+      struct fpreg fpregs;
+
+      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+	perror_with_name (_("Couldn't get floating point status"));
+
+      regcache->collect_regset (&riscv_fbsd_fpregset, regnum, &fpregs,
+				sizeof (fpregs));
+
+      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+	perror_with_name (_("Couldn't write floating point status"));
+    }
+}
+
+void
+_initialize_riscv_fbsd_nat (void)
+{
+  add_inf_child_target (&the_riscv_fbsd_nat_target);
+}