riscv: add gdbserver support

Message ID 00e401d5cb52$63a4d000$2aee7000$@c-sky.com
State New, archived
Headers

Commit Message

jiangshuai_li@c-sky.com Jan. 15, 2020, 3:17 a.m. UTC
  This patch is a base support for Riscv32 and Riscv64  arch. It implemented
how to
r/w gprs and fprs, identify the software bkpt insns and the *.dat files for
regs_info.
I have tested it on kernel 5.1.15, and it works normally.

Some requirements may be implemented later:
1. if fpu has 64bits in riscv32
2. hardware bkpt/watchpoint support
3. vector regitsers r/w

Add riscv base linux32 add linux64 gdbserver support.

gdb/gdbserver/Changlog:

2020-0113 Jiangshuai Li <jiangshuai_li@c-sky.com>

	* Makefile.in (SFILES): Add '$(srcdir)/linux-riscv-low.c'.
	* configure.srv: Target support riscv*-*linux*
	* linux-riscv-low.c: New file: Riscv low target supporting code
	(init_registers_riscv32_linux): Defined in auto-generated file
	 riscv32-linux-generated.c for RV32 linux.
	(init_registers_riscv64_linux): Defined in auto-generated file
	 riscv64-linux-generated.c for RV64 linux.
	(riscv_cannot_fetch_register): Implement
	linux_target_ops.cannot_fetch_register.
	(riscv_cannot_store_register,): Implement
	linux_target_ops.cannot_store_register.
	(riscv_fill_gregset): Fill *BUF according to elf_greg_t.
	(riscv_store_gregset): Supply *BUF according to elf_greg_t.
	(riscv_fill_fpregset): Fill *BUF according to prfpregset_t.
	(riscv_store_fpregset): Supply *BUF according to prfpregset_t.
	(riscv_arch_setup): Init current_process ()->tdesc with RV32 or
RV64.
	(regs_info): Implement linux_target_ops.riscv_regs_info.
	(riscv_sw_breakpoint_from_kind): Implement
	linux_target_ops.sw_breakpoint_from_kind, 32bits ebreak or 16bits c.
ebreak.
	(riscv_breakpoint_at): Implement
	linux_target_ops.breakpoint_at, check if mem at pc is bkpt-insn.

2020-0113 Jiangshuai Li <jiangshuai_li@c-sky.com>

	* regformats/riscv32-linux.dat: New file.
	* regformats/riscv64-linux.dat: New file.

Change-Id: Ie94277dd709b853912afe3a146be0ac2e636d5a1
---
 gdb/ChangeLog                    |   5 +
 gdb/gdbserver/ChangeLog          |  24 ++++
 gdb/gdbserver/Makefile.in        |   1 +
 gdb/gdbserver/configure.srv      |   5 +
 gdb/gdbserver/linux-riscv-low.c  | 229
+++++++++++++++++++++++++++++++++++++++
 gdb/regformats/riscv32-linux.dat |  71 ++++++++++++
 gdb/regformats/riscv64-linux.dat |  71 ++++++++++++
 7 files changed, 406 insertions(+)
 create mode 100644 gdb/gdbserver/linux-riscv-low.c
 create mode 100644 gdb/regformats/riscv32-linux.dat
 create mode 100644 gdb/regformats/riscv64-linux.dat
  

Comments

Jim Wilson Jan. 20, 2020, 11:04 p.m. UTC | #1
On Tue, Jan 14, 2020 at 7:18 PM <jiangshuai_li@c-sky.com> wrote:
> This patch is a base support for Riscv32 and Riscv64  arch. It implemented
> how to
> r/w gprs and fprs, identify the software bkpt insns and the *.dat files for
> regs_info.
> I have tested it on kernel 5.1.15, and it works normally.

I believe that Maciej has a RISC-V gdbserver port also.  It would be
nice to see some comment from him.

> Some requirements may be implemented later:
> 1. if fpu has 64bits in riscv32

This is common, and will have to be fixed, but not necessarily fixed
in the first version.  We also have riscv32 linux targets with no FP
registers.  I don't know what the *.dat files are for, but I think the
general registers and the FP registers should be separate files if
possible.  If not, then we need 6 dat files, as we have 2 general reg
sizes and 3 FP reg sizes, and 2*3=6.

> 2. hardware bkpt/watchpoint support

As far as I know, the linux kernel can't set hardware breakpoints with
the current design of the RISC-V debug standard.  They can only be set
via jtag.  So I don't see this as a problem.

> 3. vector regitsers r/w

The vector registers are still in draft form, and are subject to
change.  I'd rather not add support for draft features upstream, as
then we are stuck supporting draft versions of the ISA forever.  Also,
we still don't have a proposal for DWARF register numbers for the
vector registers.

Jim
  
Maciej W. Rozycki Jan. 20, 2020, 11:33 p.m. UTC | #2
Hi Jim,

 Thanks for the heads-up!

On Mon, 20 Jan 2020, Jim Wilson wrote:

> > This patch is a base support for Riscv32 and Riscv64  arch. It implemented
> > how to
> > r/w gprs and fprs, identify the software bkpt insns and the *.dat files for
> > regs_info.
> > I have tested it on kernel 5.1.15, and it works normally.

 So what are the test suite results compared to the native port?

> I believe that Maciej has a RISC-V gdbserver port also.  It would be
> nice to see some comment from him.

 Indeed, however I have stalled my work as my fixes for GDB issues 
triggered in the course of this effort have never been reviewed in some 2 
months now (I continue pinging, but nobody has bothered to pick them up, 
even though I think at least some of them are straightforward if not 
obvious), so I focused on some GCC issues instead.

 Also a bug needs to be fixed with GDB proper not accepting the XML 
architecture names generated by itself (i.e. code shared between GDB 
proper and `gdbserver') or XML descriptions generated by `gdbserver' are 
rejected.

 Offhand I can see the proposal fails to implement XML register 
descriptions, which I think every modern port is expected to do (we also 
need to disallow non-XML-enabled RISC-V stubs in GDB proper, as we 
discussed before; I fail to understand why it wasn't done right away with 
the initial implementation, as it's quite straightforward and would have 
set the policy for debug stubs right from the beginning).

> > Some requirements may be implemented later:
> > 1. if fpu has 64bits in riscv32
> 
> This is common, and will have to be fixed, but not necessarily fixed
> in the first version.  We also have riscv32 linux targets with no FP
> registers.  I don't know what the *.dat files are for, but I think the
> general registers and the FP registers should be separate files if
> possible.  If not, then we need 6 dat files, as we have 2 general reg
> sizes and 3 FP reg sizes, and 2*3=6.

 I have a version that supports 64-bit FPU across both RV64 and RV32, as 
required by the Linux kernel; a fix is required for the native port as 
well, which I have made too.

 The .dat files are not needed by our port AFAICT, because it generates 
the XML description dynamically, and they are only used for the ports that 
do it statically.

 I'll look into this proposal more deeply once I have fully recovered from 
my last week's trip to linux.conf.au; or maybe I'll just post mine 
instead, as it lacks some of the deficiencies discussed here and I expect 
it to be fully functional if not the XML acceptance bug on the GDB side.

 NB my RV64 HiFive Unleashed test results look like below:

                === gdb Summary ===

# of expected passes		58054
# of unexpected failures	621
# of unexpected successes	4
# of expected failures		49
# of unknown successes		5
# of known failures		72
# of unresolved testcases	110
# of untested testcases		100
# of unsupported tests		232

however I have not analysed them further, due to the reasons stated above.

 HTH,

  Maciej
  
Simon Marchi Jan. 21, 2020, 1:31 a.m. UTC | #3
On 2020-01-20 6:33 p.m., Maciej W. Rozycki wrote:
>  Offhand I can see the proposal fails to implement XML register 
> descriptions, which I think every modern port is expected to do (we also 
> need to disallow non-XML-enabled RISC-V stubs in GDB proper, as we 
> discussed before; I fail to understand why it wasn't done right away with 
> the initial implementation, as it's quite straightforward and would have 
> set the policy for debug stubs right from the beginning).

I would also expect new ports to use XML target descriptions.  And I see
that there is already code in arch/riscv.c to build target descriptions based
on detected features... so should gdbserver use it?

Simon

[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/arch/riscv.c;h=a3ab8a92909f082754dfd6eb9a70f19153b8684f;hb=HEAD
  
Maciej W. Rozycki Jan. 21, 2020, 2:14 a.m. UTC | #4
On Mon, 20 Jan 2020, Simon Marchi wrote:

> >  Offhand I can see the proposal fails to implement XML register 
> > descriptions, which I think every modern port is expected to do (we also 
> > need to disallow non-XML-enabled RISC-V stubs in GDB proper, as we 
> > discussed before; I fail to understand why it wasn't done right away with 
> > the initial implementation, as it's quite straightforward and would have 
> > set the policy for debug stubs right from the beginning).
> 
> I would also expect new ports to use XML target descriptions.  And I see
> that there is already code in arch/riscv.c to build target descriptions based
> on detected features... so should gdbserver use it?

 Yes, that's what I used with my implementation; a minor change was 
required for `riscv_create_target_description' not to return a `const' 
result (or `init_target_desc' couldn't be called on it).

 Unfortunately the result is not accepted by GDB proper as it does not 
know architecture names produced by this code (and native support bypasses 
this step as it uses a different code path for XML description setup).  I 
haven't got to fixing that yet and therefore I have concluded my 
`gdbserver' implementation is not ready for upstreaming at this point; 
test results, although clearly not catastrophic, are also affected by this 
problem I believe.

  Maciej
  
Andrew Burgess Jan. 21, 2020, 12:56 p.m. UTC | #5
* Simon Marchi <simark@simark.ca> [2020-01-20 20:31:31 -0500]:

> On 2020-01-20 6:33 p.m., Maciej W. Rozycki wrote:
> >  Offhand I can see the proposal fails to implement XML register 
> > descriptions, which I think every modern port is expected to do (we also 
> > need to disallow non-XML-enabled RISC-V stubs in GDB proper, as we 
> > discussed before; I fail to understand why it wasn't done right away with 
> > the initial implementation, as it's quite straightforward and would have 
> > set the policy for debug stubs right from the beginning).
> 
> I would also expect new ports to use XML target descriptions.  And I see
> that there is already code in arch/riscv.c to build target descriptions based
> on detected features... so should gdbserver use it?

Completely agree.

I started reviewing this patch last weekend, but ended up getting
distracted when I tried to get a RISC-V/Linux VM running again - the
instructions I previously followed[1] no longer produce a usable VM.

I had planned to go back and review this code next w/e, but I might
hold off now to see if the xml issue is addressed.

Thanks,
Andrew
  
Andrew Burgess Jan. 21, 2020, 1 p.m. UTC | #6
* Andrew Burgess <andrew.burgess@embecosm.com> [2020-01-21 12:56:57 +0000]:

> I started reviewing this patch last weekend, but ended up getting
> distracted when I tried to get a RISC-V/Linux VM running again - the
> instructions I previously followed[1] no longer produce a usable VM.

[1] https://fedoraproject.org/wiki/Architectures/RISC-V/Installing

If anyone knows of some instructions that will result in a RISC-V VM
that works (defined as can configure/build GDB) do please let me know.

Thanks,
Andrew
  
Andreas Schwab Jan. 21, 2020, 1:30 p.m. UTC | #7
On Jan 21 2020, Andrew Burgess wrote:

> If anyone knows of some instructions that will result in a RISC-V VM
> that works (defined as can configure/build GDB) do please let me know.

Not sure whether the QEMU linux-user emulation is good enough for
building GDB:

https://en.opensuse.org/openSUSE:RISC-V

Andreas.
  
Maciej W. Rozycki Jan. 21, 2020, 4:27 p.m. UTC | #8
On Tue, 21 Jan 2020, Andrew Burgess wrote:

> I had planned to go back and review this code next w/e, but I might
> hold off now to see if the xml issue is addressed.

 I have given it some thought and I'll actually post the whole series of 
my changes; there are 4 patches total, 3 of which addressing some bugs 
before the actual `gdbserver' implementation is put on top of them (I 
could ignore some of these bugs, but I couldn't persuade myself to put in 
bug-compatible nonsense only to be fixed later on).  Since this whole 
series does not address the XML arch acceptance bug (which I'm fairly sure 
will require poking at BFD too) I do not think this can go in as it stands 
anyway and I will not rerun full verification.

 I do need to do some smoke testing however, including for the bug fixes, 
as Tom has been working on some build infrastructure rework and I had to 
take it into account while updating the patches from their last October's 
state.  I expect to be ready with this sometime tomorrow.

 There's a minor ptrace(2) Linux kernel API abuse bug in RISC-V arch code 
that I find worth addressing while this work is being done.  I have a 
patch for that too, which needs final verification.  By chance it doesn't 
trigger in GDB's use, and it may not at all, but the way the RISC-V kernel 
backend has been implemented mismatches the core Linux kernel API as 
documented and is at the very least confusing to the reader.

 NB I have been verifying this work with the HiFive Unleashed real 
hardware running Linux (including native support as a reference).  

 FWIW,

  Maciej
  
Jim Wilson Jan. 21, 2020, 11:49 p.m. UTC | #9
On Mon, Jan 20, 2020 at 3:33 PM Maciej W. Rozycki <macro@wdc.com> wrote:
>  NB my RV64 HiFive Unleashed test results look like below:

For my last run in early January, on fedora rawhide with a patched
4.15 linux kernel and lots of packages installed, I get

                === gdb Summary ===

# of expected passes            62674
# of unexpected failures        980
# of unexpected successes       2
# of expected failures          71
# of unknown successes          5
# of known failures             105
# of untested testcases         93
# of unresolved testcases       10
# of unsupported tests          243

So it looks similarly to your results.

Jim
  
Jim Wilson Jan. 21, 2020, 11:56 p.m. UTC | #10
On Tue, Jan 21, 2020 at 5:30 AM Andreas Schwab <schwab@suse.de> wrote:
> Not sure whether the QEMU linux-user emulation is good enough for
> building GDB:

No, I wouldn't recommend a user mode qemu for gdb work.  A system mode
qemu does work for building and running gdb.  I used this to develop
the risc-v linux native gdb port.  Though I suspect trying to run the
gdb testsuite on qemu would find some interesting risc-v qemu bugs.
It is possible to use a cross gdb with a program running on a system
or user mode qemu via target remote, though I don't test this very
often.

Jim
  
Jim Wilson Jan. 22, 2020, 12:11 a.m. UTC | #11
On Tue, Jan 21, 2020 at 5:00 AM Andrew Burgess
<andrew.burgess@embecosm.com> wrote:
> [1] https://fedoraproject.org/wiki/Architectures/RISC-V/Installing
>
> If anyone knows of some instructions that will result in a RISC-V VM
> that works (defined as can configure/build GDB) do please let me know.

The instructions should work.  RISC-V Fedora started a mass rebuild in
mid January, but the images listed by virt-builder should be OK.  Also
keep in mind that you could be hitting a qemu bug, and you might want
to try a different qemu version or top of tree for the qemu sources.
There is a known bug in the RISC-V qemu-4.2 port that can causes FP
programs to fail for instance, a patch was contributed last week to
fix this.  It helps if you mention exactly which fedora image you are
using and exactly which qemu version you are using.

Jim
  
Guo Ren Jan. 22, 2020, 2:15 a.m. UTC | #12
Hi Jim,

On Tue, Jan 21, 2020 at 7:04 AM Jim Wilson <jimw@sifive.com> wrote:
>
> > 3. vector regitsers r/w
>
> The vector registers are still in draft form, and are subject to
> change.  I'd rather not add support for draft features upstream, as
> then we are stuck supporting draft versions of the ISA forever.  Also,
> we still don't have a proposal for DWARF register numbers for the
> vector registers.
In fact, both T-HEAD XuanTie C910 and Andes 27-series CPU cores claim
to support vector extensions, which is good for riscv-v extenstion.
Many complex linux vector development/test-suite need linux/gdb/glibc
to support the vector-regs' context.
So I think these basic functions for linux/gdb/glibc should be merged
in advance, rather than waiting for the entire vector spec to freeze.
After all, register save / restore is only a small part of riscv-v and
very basic, maybe the part of registers(abi) could be frozen in the
vector spec in advance.

Here is the linux riscv-v port V2 for task_switch, singal, ptrace: [1]

[1]: https://lore.kernel.org/linux-riscv/20200116143029.31441-4-guoren@kernel.org/

Best Regrads
 Guo Ren
  
Jim Wilson Jan. 22, 2020, 6:12 a.m. UTC | #13
On Tue, Jan 21, 2020 at 6:15 PM Guo Ren <guoren@kernel.org> wrote:
> In fact, both T-HEAD XuanTie C910 and Andes 27-series CPU cores claim
> to support vector extensions, which is good for riscv-v extenstion.

I believe the XuanTie C910 part implemented the 0.7.1 draft, I have no
idea what Andes implemented.  SiFive also has vector support in
development.  But my concern here is that we have different chips
implementing different incompatible draft versions of the vector spec.
This is going to be a nightmare to maintain.  These draft versions of
the vector spec never should have been implemented in released
hardware.

> Many complex linux vector development/test-suite need linux/gdb/glibc
> to support the vector-regs' context.

The binutils support is on a branch in a github.com/riscv repo,
waiting for the vector extension to reach its final form.  We are only
planning to upstream support for the official vector extension, not
any of the conflicting draft proposals.  The same could be done for
other parts of the vector support.  We can create branches in the
riscv repos, or we could create branches in upstream repos.  We don't
have to add patches now that may conflict with the official vector
extension support.

As for gdb, it is still the case that no one has made a psabi proposal
to assign dwarf register numbers to the vector registers.

Jim
  
Jim Wilson Jan. 22, 2020, 6:15 a.m. UTC | #14
On Tue, Jan 21, 2020 at 4:11 PM Jim Wilson <jimw@sifive.com> wrote:
> fix this.  It helps if you mention exactly which fedora image you are
> using and exactly which qemu version you are using.

Using the 20191123 image and a top of tree qemu (4.2.50) binutils/gdb
configure got stuck in gawk.  Looks like a bug with qemu.  I have a
3.1.92 qemu that got past configure and is now building which will
probably take all night on my laptop.

Jim
  
Andrew Burgess Jan. 22, 2020, 1:39 p.m. UTC | #15
* Jim Wilson <jimw@sifive.com> [2020-01-21 22:15:30 -0800]:

> On Tue, Jan 21, 2020 at 4:11 PM Jim Wilson <jimw@sifive.com> wrote:
> > fix this.  It helps if you mention exactly which fedora image you are
> > using and exactly which qemu version you are using.
> 
> Using the 20191123 image and a top of tree qemu (4.2.50) binutils/gdb
> configure got stuck in gawk.  Looks like a bug with qemu.  I have a
> 3.1.92 qemu that got past configure and is now building which will
> probably take all night on my laptop.

Thank you!  That is exactly the issue I see too.

I'll try building 3.1.92 and see how that works for me - it would be
nice to have this working again.

Thanks,
Andrew
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 39fcac7..f5cf6c7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2020-0113 Jiangshuai Li <jiangshuai_li@c-sky.com>
+
+	* regformats/riscv32-linux.dat: New file.
+	* regformats/riscv64-linux.dat: New file.
+
 2019-09-18  Christian Biesinger  <cbiesinger@google.com>
 
 	* dwarf2loc.c: Change extern declaration of dwarf_always_disassemble
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index faafdfd..be2b8f0 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,27 @@ 
+2020-0113 Jiangshuai Li <jiangshuai_li@c-sky.com>
+
+	* Makefile.in (SFILES): Add '$(srcdir)/linux-riscv-low.c'.
+	* configure.srv: Target support riscv*-*linux*
+	* linux-riscv-low.c: New file: Riscv low target supporting code 
+	(init_registers_riscv32_linux): Defined in auto-generated file
+	 riscv32-linux-generated.c for RV32 linux.
+	(init_registers_riscv64_linux): Defined in auto-generated file
+	 riscv64-linux-generated.c for RV64 linux.
+	(riscv_cannot_fetch_register): Implement
+	linux_target_ops.cannot_fetch_register.
+	(riscv_cannot_store_register,): Implement
+	linux_target_ops.cannot_store_register.
+	(riscv_fill_gregset): Fill *BUF according to elf_greg_t.
+	(riscv_store_gregset): Supply *BUF according to elf_greg_t.
+	(riscv_fill_fpregset): Fill *BUF according to prfpregset_t.
+	(riscv_store_fpregset): Supply *BUF according to prfpregset_t.
+	(riscv_arch_setup): Init current_process ()->tdesc with RV32 or
RV64.
+	(regs_info): Implement linux_target_ops.riscv_regs_info.
+	(riscv_sw_breakpoint_from_kind): Implement
+	linux_target_ops.sw_breakpoint_from_kind, 32bits ebreak or 16bits c.
ebreak.
+	(riscv_breakpoint_at): Implement
+	linux_target_ops.breakpoint_at, check if mem at pc is bkpt-insn.
+
 2019-08-23  Sergio Durigan Junior  <sergiodj@redhat.com>
 
 	* Makefile.in (SFILES): Add 'gdbsupport/gdb-dlfcn.c'.
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index ca0a4cb..ada3494 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -172,6 +172,7 @@  SFILES = \
 	$(srcdir)/linux-mips-low.c \
 	$(srcdir)/linux-nios2-low.c \
 	$(srcdir)/linux-ppc-low.c \
+	$(srcdir)/linux-riscv-low.c \
 	$(srcdir)/linux-s390-low.c \
 	$(srcdir)/linux-sh-low.c \
 	$(srcdir)/linux-sparc-low.c \
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 66d3d42..b1dc77d 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -391,6 +391,11 @@  case "${target}" in
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
+  riscv*-*linux*)	srv_regobj="riscv32-linux.o riscv64-linux.o"
+			srv_tgtobj="$srv_linux_obj linux-riscv-low.o"
+			srv_linux_regsets=yes
+			srv_linux_thread_db=yes
+			;;
   *)			echo "Error: target not supported by gdbserver."
 			exit 1
 			;;
diff --git a/gdb/gdbserver/linux-riscv-low.c
b/gdb/gdbserver/linux-riscv-low.c
new file mode 100644
index 0000000..efd156e
--- /dev/null
+++ b/gdb/gdbserver/linux-riscv-low.c
@@ -0,0 +1,229 @@ 
+/* GNU/Linux/RISCV specific low level interface, for the remote server for
GDB.
+
+   Copyright (C) 2020 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 "server.h"
+#include "linux-low.h"
+#include <asm/ptrace.h>
+#include "elf.h"
+#include "riscv-tdep.h"
+
+
+/* Defined in auto-generated file riscv32-linux-generated.c.  */
+void init_registers_riscv32_linux (void);
+extern const struct target_desc *tdesc_riscv32_linux;
+
+/* Defined in auto-generated file riscv64-linux-generated.c.  */
+void init_registers_riscv64_linux (void);
+extern const struct target_desc *tdesc_riscv64_linux;
+
+static int
+riscv_cannot_fetch_register (int regno)
+{
+  if (regno >=0 && regno <= 63)
+    return 0;
+  else
+    return 1;
+}
+
+static int
+riscv_cannot_store_register (int regno)
+{
+  if (regno >=0 && regno <= 63)
+    return 0;
+  else
+    return 1;
+}
+
+static void
+riscv_fill_gregset (struct regcache *regcache, void *buf)
+{
+   elf_greg_t *regp = (elf_greg_t *)buf;
+
+   /* We only support the integer registers and PC here.  */
+   for (int i = RISCV_ZERO_REGNUM + 1; i < RISCV_PC_REGNUM; i++)
+     collect_register (regcache, i, regp + i);
+
+   collect_register (regcache, 32, regp + 0);
+}
+
+static void
+riscv_store_gregset (struct regcache *regcache, const void *buf)
+{
+  const elf_greg_t *regp = (const elf_greg_t *)buf;
+
+  /* We only support the integer registers and PC here.  */
+  for (int i = RISCV_ZERO_REGNUM + 1; i < RISCV_PC_REGNUM; i++)
+    supply_register (regcache, i, regp + i);
+
+  /* GDB stores PC in reg 32.  Linux kernel stores it in reg 0.  */
+  supply_register (regcache, 32, regp + 0);
+
+  /* Fill the inaccessible zero register with zero.  */
+  supply_register_zeroed (regcache, 0);
+}
+
+static void
+riscv_fill_fpregset (struct regcache *regcache, void *buf)
+{
+  prfpregset_t *fpregs = (prfpregset_t *)buf;
+
+  /* We only support the FP registers and FCSR here.  */
+  for (int i = RISCV_FIRST_FP_REGNUM; i <= RISCV_LAST_FP_REGNUM; i++)
+    collect_register (regcache, i, &fpregs->__d.__f[i -
RISCV_FIRST_FP_REGNUM]);
+
+  collect_register (regcache, RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr);
+}
+
+static void
+riscv_store_fpregset (struct regcache *regcache, const void *buf)
+{
+  const prfpregset_t *fpregs = (const prfpregset_t *)buf;
+
+  /* We only support the FP registers and FCSR here.  */
+  for (int i = RISCV_FIRST_FP_REGNUM; i <= RISCV_LAST_FP_REGNUM; i++)
+    supply_register (regcache, i, &fpregs->__d.__f[i -
RISCV_FIRST_FP_REGNUM]);
+
+  supply_register (regcache, RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr);
+}
+
+static struct regset_info riscv_regsets[] = {
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, sizeof
(elf_gregset_t),
+    GENERAL_REGS,
+    riscv_fill_gregset, riscv_store_gregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET, sizeof
(elf_fpregset_t),
+    FP_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  NULL_REGSET
+};
+
+
+static void
+riscv_arch_setup (void)
+{
+  int size = sizeof (elf_greg_t);
+
+  if (size == 4)
+    current_process ()->tdesc = tdesc_riscv32_linux;
+  else
+    current_process ()->tdesc = tdesc_riscv64_linux;
+}
+
+static struct regsets_info riscv_regsets_info =
+  {
+    riscv_regsets, /* regsets */
+    0, /* num_regsets */
+    NULL, /* disabled_regsets */
+  };
+
+static struct regs_info regs_info =
+  {
+    NULL, /* regset_bitmap */
+    NULL, /* usrregs */
+    &riscv_regsets_info
+  };
+
+static const struct regs_info *
+riscv_regs_info (void)
+{
+  return &regs_info;
+}
+
+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind".  */
+static const gdb_byte ebreak[] = {0x73, 0x00, 0x10, 0x00};
+static const gdb_byte c_ebreak[] = {0x02, 0x90};
+
+static const gdb_byte *
+riscv_sw_breakpoint_from_kind (int kind, int *size)
+{
+  *size = kind;
+
+  switch (kind)
+    {
+      case 2:
+        return c_ebreak;
+      case 4:
+        return ebreak;
+      default:
+        gdb_assert (0);
+    }
+}
+
+static int
+riscv_breakpoint_at (CORE_ADDR where)
+{
+  unsigned char insn[4];
+
+  (*the_target->read_memory) (where, (unsigned char *) insn, 4);
+
+  if (insn[0] == ebreak[0] && insn[1] == ebreak[1]
+      && insn[2] == ebreak[2] && insn[3] == ebreak[3])
+    return 1;
+  else if (insn[0] == ebreak[0] && insn[1] == ebreak[1])
+    return 1;
+  else
+    return 0;
+}
+
+
+struct linux_target_ops the_low_target = {
+  riscv_arch_setup, /* arch_setup */
+  riscv_regs_info, /* regs_info */
+  riscv_cannot_fetch_register, /* cannot_fetch_register */
+  riscv_cannot_store_register, /* cannot_store_register */
+  NULL, /* fetch_register */
+  linux_get_pc_64bit, /* get_pc */
+  linux_set_pc_64bit, /* set_pc */
+  NULL, /* breakpoint_kind_from_pc */
+  riscv_sw_breakpoint_from_kind, /* sw_breakpoint_from_kind */
+  NULL, /* get_next_pcs */
+  0,    /* decr_pc_after_break */
+  riscv_breakpoint_at, /* breakpoint_at */
+  NULL, /* supports_z_point_type */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* collect_ptrace_register */
+  NULL, /* supply_ptrace_register */
+  NULL, /* siginfo_fixup */
+  NULL, /* new_process */
+  NULL, /* delete_process */
+  NULL, /* new_thread */
+  NULL, /* delete_thread */
+  NULL, /* new_fork */
+  NULL, /* prepare_to_resume */
+  NULL, /* process_qsupported */
+  NULL, /* supports_tracepoints */
+  NULL, /* get_thread_area */
+  NULL, /* install_fast_tracepoint_jump_pad */
+  NULL, /* emit_ops */
+  NULL, /* get_min_fast_tracepoint_insn_len */
+  NULL, /* supports_range_stepping */
+  NULL, /* breakpoint_kind_from_current_state */
+  NULL, /* supports_hardware_single_step */
+};
+
+
+void
+initialize_low_arch (void)
+{
+  init_registers_riscv32_linux ();
+  init_registers_riscv64_linux ();
+  initialize_regsets_info (&riscv_regsets_info);
+}
diff --git a/gdb/regformats/riscv32-linux.dat
b/gdb/regformats/riscv32-linux.dat
new file mode 100644
index 0000000..d7dae52
--- /dev/null
+++ b/gdb/regformats/riscv32-linux.dat
@@ -0,0 +1,71 @@ 
+name:riscv32_linux
+xmltarget:riscv32-linux.xml
+expedite:sp,fp,pc
+32:zero
+32:ra
+32:sp
+32:gp
+32:tp
+32:t0
+32:t1
+32:t2
+32:fp
+32:s1
+32:a0
+32:a1
+32:a2
+32:a3
+32:a4
+32:a5
+32:a6
+32:a7
+32:s2
+32:s3
+32:s4
+32:s5
+32:s6
+32:s7
+32:s8
+32:s9
+32:s10
+32:s11
+32:t3
+32:t4
+32:t5
+32:t6
+32:pc
+32:ft0
+32:ft1
+32:ft2
+32:ft3
+32:ft4
+32:ft5
+32:ft6
+32:ft7
+32:fs0
+32:fs1
+32:fa0
+32:fa1
+32:fa2
+32:fa3
+32:fa4
+32:fa5
+32:fa6
+32:fa7
+32:fs2
+32:fs3
+32:fs4
+32:fs5
+32:fs6
+32:fs7
+32:fs8
+32:fs9
+32:fs10
+32:fs11
+32:ft8
+32:ft9
+32:ft10
+32:ft11
+32:fflags
+32:frm
+32:fcsr
diff --git a/gdb/regformats/riscv64-linux.dat
b/gdb/regformats/riscv64-linux.dat
new file mode 100644
index 0000000..1b88f6c
--- /dev/null
+++ b/gdb/regformats/riscv64-linux.dat
@@ -0,0 +1,71 @@ 
+name:riscv64_linux
+xmltarget:riscv64-linux.xml
+expedite:sp,fp,pc
+64:zero
+64:ra
+64:sp
+64:gp
+64:tp
+64:t0
+64:t1
+64:t2
+64:fp
+64:s1
+64:a0
+64:a1
+64:a2
+64:a3
+64:a4
+64:a5
+64:a6
+64:a7
+64:s2
+64:s3
+64:s4
+64:s5
+64:s6
+64:s7
+64:s8
+64:s9
+64:s10
+64:s11
+64:t3
+64:t4
+64:t5
+64:t6
+64:pc
+64:ft0
+64:ft1
+64:ft2
+64:ft3
+64:ft4
+64:ft5
+64:ft6
+64:ft7
+64:fs0
+64:fs1
+64:fa0
+64:fa1
+64:fa2
+64:fa3
+64:fa4
+64:fa5
+64:fa6
+64:fa7
+64:fs2
+64:fs3
+64:fs4
+64:fs5
+64:fs6
+64:fs7
+64:fs8
+64:fs9
+64:fs10
+64:fs11
+64:ft8
+64:ft9
+64:ft10
+64:ft11
+32:fflags
+32:frm
+32:fcsr