public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v7 1/2] gdb/riscv: Update API for looking up target descriptions
  2020-02-14 19:32 [PATCH v7 0/2] RISC-V/Linux `gdbserver' support and associated fixes Maciej W. Rozycki
@ 2020-02-14 19:32 ` Maciej W. Rozycki
  2020-02-19  1:28   ` Maciej W. Rozycki
  2020-02-14 19:33 ` [PATCH v7 2/2] gdbserver: Add RISC-V/Linux support Maciej W. Rozycki
  1 sibling, 1 reply; 5+ messages in thread
From: Maciej W. Rozycki @ 2020-02-14 19:32 UTC (permalink / raw)
  To: gdb-patches
  Cc: Jim Wilson, Andrew Burgess, Palmer Dabbelt, Tom Tromey, guoren,
	lifang_xia, yunhai_shang, jiangshuai_li

From: Andrew Burgess <andrew.burgess@embecosm.com>

In preparation for adding the RISC-V gdbserver, this commit
restructures the API for looking up target descriptions.

The current API is riscv_create_target_description, which creates a
target description from a riscv_gdbarch_features, but also caches the
created target descriptions so that for a given features object we
always get back the same target description object.  This is important
for GDB due to the way gdbarch objects are reused.

As the same target description is always returned to GDB, and can be
returned multiple times, it is returned as a const, however, the
current cache actually stores a non-const target description.  This is
improved in this patch so that the cache holds a const target
description.

For gdbsever, this caching of the target descriptions is not needed,
the gdbserver looks up one target description to describe the target
it is actually running on and that is it.  Further the gdbserver
actually needs to modify the target description that is looked up, so
for the gdbsever, returning a const target description is not
acceptable.

This commit aims to address this by creating two parallel target
description APIs, on is the old riscv_create_target_description,
however, this no longer performs any caching, and just creates a new
target description, and returns it as non-const.

The second API is riscv_lookup_target_description, this one performs
the caching, and calls riscv_create_target_description to create a
target description when needed.

In order to make sure the correct API is used in the correct place I
have guarded the code using the GDBSERVER define.  For GDB the
riscv_create_target_description is static, and not generally usable
throughout GDB, only the lookup API is global.  In gdbserver, the
lookup functions, and the cache are not defined or created at all,
only the riscv_create_target_description API is available.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* arch/riscv.c (struct riscv_gdbarch_features_hasher): Only define
	if GDBSERVER is not defined.
	(riscv_tdesc_cache): Likewise, also store const target_desc.
	(STATIC_IN_GDB): Define.
	(riscv_create_target_description): Update declaration with
	STATIC_IN_GDB.
	(riscv_lookup_target_description): New function, only define if
	GDBSERVER is not defined.
	* arch/riscv.h (riscv_create_target_description): Declare only
	when GDBSERVER is defined.
	(riscv_lookup_target_description): New declaration when GDBSERVER
	is not defined.
	* nat/riscv-linux-tdesc.c (riscv_linux_read_description): Rename to...
	(riscv_linux_read_features): ...this, and return
	riscv_gdbarch_features instead of target_desc.
	* nat/riscv-linux-tdesc.h: Include 'arch/riscv.h'.
	(riscv_linux_read_description): Rename to...
	(riscv_linux_read_features): ...this.
	* riscv-linux-nat.c (riscv_linux_nat_target::read_description):
	Update to use riscv_gdbarch_features and
	riscv_lookup_target_description.
	* riscv-tdep.c (riscv_find_default_target_description): Use
	riscv_lookup_target_description instead of
	riscv_create_target_description.
---
 gdb/arch/riscv.c            |   69 ++++++++++++++++++++++++++------------------
 gdb/arch/riscv.h            |   26 ++++++++++++++--
 gdb/nat/riscv-linux-tdesc.c |    8 ++---
 gdb/nat/riscv-linux-tdesc.h |    7 ++--
 gdb/riscv-linux-nat.c       |    4 +-
 gdb/riscv-tdep.c            |    2 -
 6 files changed, 76 insertions(+), 40 deletions(-)

gdb-aburgess-riscv-tdesc-api-gdbserver.diff
Index: binutils-gdb/gdb/arch/riscv.c
===================================================================
--- binutils-gdb.orig/gdb/arch/riscv.c
+++ binutils-gdb/gdb/arch/riscv.c
@@ -25,37 +25,17 @@
 #include "../features/riscv/32bit-fpu.c"
 #include "../features/riscv/64bit-fpu.c"
 
-/* Wrapper used by std::unordered_map to generate hash for feature set.  */
-struct riscv_gdbarch_features_hasher
-{
-  std::size_t
-  operator() (const riscv_gdbarch_features &features) const noexcept
-  {
-    return features.hash ();
-  }
-};
-
-/* Cache of previously seen target descriptions, indexed by the feature set
-   that created them.  */
-static std::unordered_map<riscv_gdbarch_features,
-                          target_desc *,
-                          riscv_gdbarch_features_hasher> riscv_tdesc_cache;
+#ifndef GDBSERVER
+#define STATIC_IN_GDB static
+#else
+#define STATIC_IN_GDB
+#endif
 
 /* See arch/riscv.h.  */
 
-const target_desc *
-riscv_create_target_description (struct riscv_gdbarch_features features)
+STATIC_IN_GDB target_desc *
+riscv_create_target_description (const struct riscv_gdbarch_features features)
 {
-  /* Have we seen this feature set before?  If we have return the same
-     target description.  GDB expects that if two target descriptions are
-     the same (in content terms) then they will actually be the same
-     instance.  This is important when trying to lookup gdbarch objects as
-     GDBARCH_LIST_LOOKUP_BY_INFO performs a pointer comparison on target
-     descriptions to find candidate gdbarch objects.  */
-  const auto it = riscv_tdesc_cache.find (features);
-  if (it != riscv_tdesc_cache.end ())
-    return it->second;
-
   /* Now we should create a new target description.  */
   target_desc *tdesc = allocate_target_description ();
 
@@ -93,8 +73,43 @@ riscv_create_target_description (struct
   else if (features.flen == 8)
     regnum = create_feature_riscv_64bit_fpu (tdesc, regnum);
 
+  return tdesc;
+}
+
+#ifndef GDBSERVER
+
+/* Wrapper used by std::unordered_map to generate hash for feature set.  */
+struct riscv_gdbarch_features_hasher
+{
+  std::size_t
+  operator() (const riscv_gdbarch_features &features) const noexcept
+  {
+    return features.hash ();
+  }
+};
+
+/* Cache of previously seen target descriptions, indexed by the feature set
+   that created them.  */
+static std::unordered_map<riscv_gdbarch_features,
+			  const target_desc *,
+			  riscv_gdbarch_features_hasher> riscv_tdesc_cache;
+
+/* See arch/riscv.h.  */
+
+const target_desc *
+riscv_lookup_target_description (const struct riscv_gdbarch_features features)
+{
+  /* Lookup in the cache.  */
+  const auto it = riscv_tdesc_cache.find (features);
+  if (it != riscv_tdesc_cache.end ())
+    return it->second;
+
+  target_desc *tdesc = riscv_create_target_description (features);
+
   /* Add to the cache.  */
   riscv_tdesc_cache.emplace (features, tdesc);
 
   return tdesc;
 }
+
+#endif /* !GDBSERVER */
Index: binutils-gdb/gdb/arch/riscv.h
===================================================================
--- binutils-gdb.orig/gdb/arch/riscv.h
+++ binutils-gdb/gdb/arch/riscv.h
@@ -66,10 +66,28 @@ struct riscv_gdbarch_features
   }
 };
 
-/* Create and return a target description that is compatible with
-   FEATURES.  */
+#ifdef GDBSERVER
+
+/* Create and return a target description that is compatible with FEATURES.
+   This is only used directly from the gdbserver where the created target
+   description is modified after it is return.  */
+
+target_desc *riscv_create_target_description
+	(const struct riscv_gdbarch_features features);
+
+#else
+
+/* Lookup an already existing target description matching FEATURES, or
+   create a new target description if this is the first time we have seen
+   FEATURES.  For the same FEATURES the same target_desc is always
+   returned.  This is important when trying to lookup gdbarch objects as
+   GDBARCH_LIST_LOOKUP_BY_INFO performs a pointer comparison on target
+   descriptions to find candidate gdbarch objects.  */
+
+const target_desc *riscv_lookup_target_description
+	(const struct riscv_gdbarch_features features);
+
+#endif /* GDBSERVER */
 
-const target_desc *riscv_create_target_description
-	(struct riscv_gdbarch_features features);
 
 #endif /* ARCH_RISCV_H */
Index: binutils-gdb/gdb/nat/riscv-linux-tdesc.c
===================================================================
--- binutils-gdb.orig/gdb/nat/riscv-linux-tdesc.c
+++ binutils-gdb/gdb/nat/riscv-linux-tdesc.c
@@ -31,10 +31,10 @@
 # define NFPREG 33
 #endif
 
-/* Determine XLEN and FLEN and return a corresponding target description.  */
+/* See nat/riscv-linux-tdesc.h.  */
 
-const struct target_desc *
-riscv_linux_read_description (int tid)
+struct riscv_gdbarch_features
+riscv_linux_read_features (int tid)
 {
   struct riscv_gdbarch_features features;
   elf_fpregset_t regs;
@@ -79,5 +79,5 @@ riscv_linux_read_description (int tid)
       break;
     }
 
-  return riscv_create_target_description (features);
+  return features;
 }
Index: binutils-gdb/gdb/nat/riscv-linux-tdesc.h
===================================================================
--- binutils-gdb.orig/gdb/nat/riscv-linux-tdesc.h
+++ binutils-gdb/gdb/nat/riscv-linux-tdesc.h
@@ -19,9 +19,10 @@
 #ifndef NAT_RISCV_LINUX_TDESC_H
 #define NAT_RISCV_LINUX_TDESC_H
 
-struct target_desc;
+#include "arch/riscv.h"
 
-/* Return a target description for the LWP identified by TID.  */
-const struct target_desc *riscv_linux_read_description (int tid);
+/* Determine XLEN and FLEN for the LWP identified by TID, and return a
+   corresponding features object.  */
+struct riscv_gdbarch_features riscv_linux_read_features (int tid);
 
 #endif /* NAT_RISCV_LINUX_TDESC_H */
Index: binutils-gdb/gdb/riscv-linux-nat.c
===================================================================
--- binutils-gdb.orig/gdb/riscv-linux-nat.c
+++ binutils-gdb/gdb/riscv-linux-nat.c
@@ -201,7 +201,9 @@ fill_fpregset (const struct regcache *re
 const struct target_desc *
 riscv_linux_nat_target::read_description ()
 {
-  return riscv_linux_read_description (inferior_ptid.lwp ());
+  const struct riscv_gdbarch_features features
+    = riscv_linux_read_features (inferior_ptid.lwp ());
+  return riscv_lookup_target_description (features);
 }
 
 /* Fetch REGNUM (or all registers if REGNUM == -1) from the target
Index: binutils-gdb/gdb/riscv-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/riscv-tdep.c
+++ binutils-gdb/gdb/riscv-tdep.c
@@ -2973,7 +2973,7 @@ riscv_find_default_target_description (c
     features.xlen = 8;
 
   /* Now build a target description based on the feature set.  */
-  return riscv_create_target_description (features);
+  return riscv_lookup_target_description (features);
 }
 
 /* All of the registers in REG_SET are checked for in FEATURE, TDESC_DATA

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v7 0/2] RISC-V/Linux `gdbserver' support and associated fixes
@ 2020-02-14 19:32 Maciej W. Rozycki
  2020-02-14 19:32 ` [PATCH v7 1/2] gdb/riscv: Update API for looking up target descriptions Maciej W. Rozycki
  2020-02-14 19:33 ` [PATCH v7 2/2] gdbserver: Add RISC-V/Linux support Maciej W. Rozycki
  0 siblings, 2 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2020-02-14 19:32 UTC (permalink / raw)
  To: gdb-patches
  Cc: Jim Wilson, Andrew Burgess, Palmer Dabbelt, Tom Tromey, guoren,
	lifang_xia, yunhai_shang, jiangshuai_li

Hi,

 This is v7 of RISC-V/Linux `gdbserver' support, based on Andrew's XML 
target description look-up API update and the original submission, 
adjusted for the move of gdbserver/ to the top level and the rename of .c 
files to .cc.  No functional change compared to v6 posted by Andrew.

 Regression-tested with the `riscv64-linux-gnu' target, natively for the 
API update, which took 56 hours per iteration this time (sigh), and also 
remotely.

 Given that these changes have been already approved in v6 I will apply 
them in a couple of days' time unless I hear any objections.

  Maciej

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v7 2/2] gdbserver: Add RISC-V/Linux support
  2020-02-14 19:32 [PATCH v7 0/2] RISC-V/Linux `gdbserver' support and associated fixes Maciej W. Rozycki
  2020-02-14 19:32 ` [PATCH v7 1/2] gdb/riscv: Update API for looking up target descriptions Maciej W. Rozycki
@ 2020-02-14 19:33 ` Maciej W. Rozycki
  2020-02-19  1:35   ` [committed v8 " Maciej W. Rozycki
  1 sibling, 1 reply; 5+ messages in thread
From: Maciej W. Rozycki @ 2020-02-14 19:33 UTC (permalink / raw)
  To: gdb-patches
  Cc: Jim Wilson, Andrew Burgess, Palmer Dabbelt, Tom Tromey, guoren,
	lifang_xia, yunhai_shang, jiangshuai_li

Implement RISC-V/Linux support for both RV64 and RV32 systems, including
XML target description handling based on features determined, GPR and
FPR regset support including dynamic sizing of the latter, and software
breakpoint handling.  Define two NT_FPREGSET regsets of a different size
matching the FPR sizes supported for generic `gdbserver' code to pick
from according to what the OS supplies.

Also handle a glibc bug where ELF_NFPREG is defined in terms of NFPREG,
however NFPREG is nowhere defined.

2020-02-14  Maciej W. Rozycki  <macro@wdc.com>
	    Andrew Burgess  <andrew.burgess@embecosm.com>

	gdbserver/
	* linux-riscv-low.cc: New file.
	* Makefile.in (SFILES): Add linux-riscv-low.cc, arch/riscv.c,
	and nat/riscv-linux-tdesc.c.
	* configure.srv <riscv*-*-linux*> (srv_tgtobj)
	(srv_linux_regsets, srv_linux_usrregs, srv_linux_thread_db):
	Define.
---
Changes from v6:

- Regenerate for the gdbserver/ move to the top level.

- Use the .cc suffix following the rename of other files.

Changes from v4:

- Add 128-bit FP regset.

Changes from v3:

- Actually include changes from v2.

Changes from v2:

- Advance through the buffer accessed in `riscv_fill_fpregset' and
  `riscv_store_fpregset' so as to avoid doing a variable multiplication in
  a loop; rename the `regset' variable to `regbuf'.

- Use OPTIONAL_REGS rather than FP_REGS as the type for the floating-point
  regsets.

- Add comments throughout.

Changes from v1:

- Make `gdbserver' selected for automatic build in a RISC-V/Linux/native
  GDB configuration (thanks, Jim, for pointing this out!).

- Remove most of `riscv_arch_setup' and use `riscv_linux_read_description'
  from 2/3 instead.

- Stop using `elf_fpregset_t*' in favour to just a raw `gdb_byte *' buffer
  and size the regset according to the FPR size in `riscv_fill_fpregset'
  and `riscv_store_fpregset'.

- Define 2 NT_FPREGSET regsets of a different size for generic `gdbserver'
  code to pick from according to what the OS supplies.
---
 gdbserver/Makefile.in       |    3 
 gdbserver/configure.srv     |    7 +
 gdbserver/linux-riscv-low.c |  279 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 289 insertions(+)
 create mode 100644 gdbserver/linux-riscv-low.c

gdb-riscv-gdbserver-linux.diff
Index: binutils-gdb/gdbserver/Makefile.in
===================================================================
--- binutils-gdb.orig/gdbserver/Makefile.in
+++ binutils-gdb/gdbserver/Makefile.in
@@ -181,6 +181,7 @@ SFILES = \
 	$(srcdir)/linux-mips-low.cc \
 	$(srcdir)/linux-nios2-low.cc \
 	$(srcdir)/linux-ppc-low.cc \
+	$(srcdir)/linux-riscv-low.cc \
 	$(srcdir)/linux-s390-low.cc \
 	$(srcdir)/linux-sh-low.cc \
 	$(srcdir)/linux-sparc-low.cc \
@@ -207,6 +208,7 @@ SFILES = \
 	$(srcdir)/../gdb/arch/arm-get-next-pcs.c \
 	$(srcdir)/../gdb/arch/arm-linux.c \
 	$(srcdir)/../gdb/arch/ppc-linux-common.c \
+	$(srcdir)/../gdb/arch/riscv.c \
 	$(srcdir)/../gdbsupport/btrace-common.cc \
 	$(srcdir)/../gdbsupport/buffer.cc \
 	$(srcdir)/../gdbsupport/cleanups.cc \
@@ -240,6 +242,7 @@ SFILES = \
 	$(srcdir)/../gdb/nat/linux-personality.c \
 	$(srcdir)/../gdb/nat/mips-linux-watch.c \
 	$(srcdir)/../gdb/nat/ppc-linux.c \
+	$(srcdir)/../gdb/nat/riscv-linux-tdesc.c \
 	$(srcdir)/../gdb/nat/fork-inferior.c \
 	$(srcdir)/../gdb/target/waitstatus.c
 
Index: binutils-gdb/gdbserver/configure.srv
===================================================================
--- binutils-gdb.orig/gdbserver/configure.srv
+++ binutils-gdb/gdbserver/configure.srv
@@ -271,6 +271,13 @@ case "${host}" in
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu.xml"
 			srv_lynxos=yes
 			;;
+  riscv*-*-linux*)	srv_tgtobj="arch/riscv.o nat/riscv-linux-tdesc.o"
+			srv_tgtobj="${srv_tgtobj} linux-riscv-low.o"
+			srv_tgtobj="${srv_tgtobj} ${srv_linux_obj}"
+			srv_linux_regsets=yes
+			srv_linux_usrregs=yes
+			srv_linux_thread_db=yes
+			;;
   s390*-*-linux*)	srv_regobj="s390-linux32.o"
 			srv_regobj="${srv_regobj} s390-linux32v1.o"
 			srv_regobj="${srv_regobj} s390-linux32v2.o"
Index: binutils-gdb/gdbserver/linux-riscv-low.cc
===================================================================
--- /dev/null
+++ binutils-gdb/gdbserver/linux-riscv-low.cc
@@ -0,0 +1,279 @@
+/* GNU/Linux/RISC-V 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 "tdesc.h"
+#include "elf/common.h"
+#include "nat/riscv-linux-tdesc.h"
+#include "opcode/riscv.h"
+
+/* Work around glibc header breakage causing ELF_NFPREG not to be usable.  */
+#ifndef NFPREG
+# define NFPREG 33
+#endif
+
+/* Implementation of linux_target_ops method "arch_setup".  */
+
+static void
+riscv_arch_setup ()
+{
+  static const char *expedite_regs[] = { "sp", "pc", NULL };
+
+  const riscv_gdbarch_features features
+    = riscv_linux_read_features (lwpid_of (current_thread));
+  target_desc *tdesc = riscv_create_target_description (features);
+
+  if (!tdesc->expedite_regs)
+    init_target_desc (tdesc, expedite_regs);
+  current_process ()->tdesc = tdesc;
+}
+
+/* Collect GPRs from REGCACHE into BUF.  */
+
+static void
+riscv_fill_gregset (struct regcache *regcache, void *buf)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+  elf_gregset_t *regset = (elf_gregset_t *) buf;
+  int regno = find_regno (tdesc, "zero");
+  int i;
+
+  collect_register_by_name (regcache, "pc", *regset);
+  for (i = 1; i < ARRAY_SIZE (*regset); i++)
+    collect_register (regcache, regno + i, *regset + i);
+}
+
+/* Supply GPRs from BUF into REGCACHE.  */
+
+static void
+riscv_store_gregset (struct regcache *regcache, const void *buf)
+{
+  const elf_gregset_t *regset = (const elf_gregset_t *) buf;
+  const struct target_desc *tdesc = regcache->tdesc;
+  int regno = find_regno (tdesc, "zero");
+  int i;
+
+  supply_register_by_name (regcache, "pc", *regset);
+  supply_register_zeroed (regcache, regno);
+  for (i = 1; i < ARRAY_SIZE (*regset); i++)
+    supply_register (regcache, regno + i, *regset + i);
+}
+
+/* Collect FPRs from REGCACHE into BUF.  */
+
+static void
+riscv_fill_fpregset (struct regcache *regcache, void *buf)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+  int regno = find_regno (tdesc, "ft0");
+  int flen = register_size (regcache->tdesc, regno);
+  gdb_byte *regbuf = (gdb_byte *) buf;
+  int i;
+
+  for (i = 0; i < ELF_NFPREG - 1; i++, regbuf += flen)
+    collect_register (regcache, regno + i, regbuf);
+  collect_register_by_name (regcache, "fcsr", regbuf);
+}
+
+/* Supply FPRs from BUF into REGCACHE.  */
+
+static void
+riscv_store_fpregset (struct regcache *regcache, const void *buf)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+  int regno = find_regno (tdesc, "ft0");
+  int flen = register_size (regcache->tdesc, regno);
+  const gdb_byte *regbuf = (const gdb_byte *) buf;
+  int i;
+
+  for (i = 0; i < ELF_NFPREG - 1; i++, regbuf += flen)
+    supply_register (regcache, regno + i, regbuf);
+  supply_register_by_name (regcache, "fcsr", regbuf);
+}
+
+/* RISC-V/Linux regsets.  FPRs are optional and come in different sizes,
+   so define multiple regsets for them marking them all as OPTIONAL_REGS
+   rather than FP_REGS, so that "regsets_fetch_inferior_registers" picks
+   the right one according to size.  */
+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 (struct __riscv_mc_q_ext_state), OPTIONAL_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
+    sizeof (struct __riscv_mc_d_ext_state), OPTIONAL_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
+    sizeof (struct __riscv_mc_f_ext_state), OPTIONAL_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  NULL_REGSET
+};
+
+/* RISC-V/Linux regset information.  */
+static struct regsets_info riscv_regsets_info =
+  {
+    riscv_regsets, /* regsets */
+    0, /* num_regsets */
+    NULL, /* disabled_regsets */
+  };
+
+/* Definition of linux_target_ops data member "regs_info".  */
+static struct regs_info riscv_regs =
+  {
+    NULL, /* regset_bitmap */
+    NULL, /* usrregs */
+    &riscv_regsets_info,
+  };
+
+/* Implementation of linux_target_ops method "regs_info".  */
+
+static const struct regs_info *
+riscv_regs_info ()
+{
+  return &riscv_regs;
+}
+
+/* Implementation of linux_target_ops method "fetch_register".  */
+
+static int
+riscv_fetch_register (struct regcache *regcache, int regno)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+
+  if (regno != find_regno (tdesc, "zero"))
+    return 0;
+  supply_register_zeroed (regcache, regno);
+  return 1;
+}
+
+/* Implementation of linux_target_ops method "get_pc".  */
+
+static CORE_ADDR
+riscv_get_pc (struct regcache *regcache)
+{
+  elf_gregset_t regset;
+
+  if (sizeof (regset[0]) == 8)
+    return linux_get_pc_64bit (regcache);
+  else
+    return linux_get_pc_32bit (regcache);
+}
+
+/* Implementation of linux_target_ops method "set_pc".  */
+
+static void
+riscv_set_pc (struct regcache *regcache, CORE_ADDR newpc)
+{
+  elf_gregset_t regset;
+
+  if (sizeof (regset[0]) == 8)
+    linux_set_pc_64bit (regcache, newpc);
+  else
+    linux_set_pc_32bit (regcache, newpc);
+}
+
+/* Correct in either endianness.  */
+static const uint16_t riscv_ibreakpoint[] = { 0x0073, 0x0010 };
+static const uint16_t riscv_cbreakpoint = 0x9002;
+
+/* Implementation of linux_target_ops method "breakpoint_kind_from_pc".  */
+
+static int
+riscv_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
+{
+  union
+    {
+      gdb_byte bytes[2];
+      uint16_t insn;
+    }
+  buf;
+
+  if (target_read_memory (*pcptr, buf.bytes, sizeof (buf.insn)) == 0
+      && riscv_insn_length (buf.insn == sizeof (riscv_ibreakpoint)))
+    return sizeof (riscv_ibreakpoint);
+  else
+    return sizeof (riscv_cbreakpoint);
+}
+
+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind".  */
+
+static const gdb_byte *
+riscv_sw_breakpoint_from_kind (int kind, int *size)
+{
+  *size = kind;
+  switch (kind)
+    {
+      case sizeof (riscv_ibreakpoint):
+	return (const gdb_byte *) &riscv_ibreakpoint;
+      default:
+	return (const gdb_byte *) &riscv_cbreakpoint;
+    }
+}
+
+/* Implementation of linux_target_ops method "breakpoint_at".  */
+
+static int
+riscv_breakpoint_at (CORE_ADDR pc)
+{
+  union
+    {
+      gdb_byte bytes[2];
+      uint16_t insn;
+    }
+  buf;
+
+  if (target_read_memory (pc, buf.bytes, sizeof (buf.insn)) == 0
+      && (buf.insn == riscv_cbreakpoint
+	  || (buf.insn == riscv_ibreakpoint[0]
+	      && target_read_memory (pc + sizeof (buf.insn), buf.bytes,
+				     sizeof (buf.insn)) == 0
+	      && buf.insn == riscv_ibreakpoint[1])))
+    return 1;
+  else
+    return 0;
+}
+
+/* RISC-V/Linux target operations.  */
+struct linux_target_ops the_low_target =
+{
+  riscv_arch_setup,
+  riscv_regs_info,
+  NULL, /* cannot_fetch_register */
+  NULL, /* cannot_store_register */
+  riscv_fetch_register,
+  riscv_get_pc,
+  riscv_set_pc,
+  riscv_breakpoint_kind_from_pc,
+  riscv_sw_breakpoint_from_kind,
+  NULL, /* get_next_pcs */
+  0,    /* decr_pc_after_break */
+  riscv_breakpoint_at,
+};
+
+/* Initialize the RISC-V/Linux target.  */
+
+void
+initialize_low_arch ()
+{
+  initialize_regsets_info (&riscv_regsets_info);
+}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v7 1/2] gdb/riscv: Update API for looking up target descriptions
  2020-02-14 19:32 ` [PATCH v7 1/2] gdb/riscv: Update API for looking up target descriptions Maciej W. Rozycki
@ 2020-02-19  1:28   ` Maciej W. Rozycki
  0 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2020-02-19  1:28 UTC (permalink / raw)
  To: gdb-patches
  Cc: Jim Wilson, Andrew Burgess, Palmer Dabbelt, Tom Tromey, guoren,
	lifang_xia, yunhai_shang, jiangshuai_li

On Fri, 14 Feb 2020, Maciej W. Rozycki wrote:

> gdb/ChangeLog:
> 
> 	* arch/riscv.c (struct riscv_gdbarch_features_hasher): Only define
> 	if GDBSERVER is not defined.
> 	(riscv_tdesc_cache): Likewise, also store const target_desc.
> 	(STATIC_IN_GDB): Define.
> 	(riscv_create_target_description): Update declaration with
> 	STATIC_IN_GDB.
> 	(riscv_lookup_target_description): New function, only define if
> 	GDBSERVER is not defined.
> 	* arch/riscv.h (riscv_create_target_description): Declare only
> 	when GDBSERVER is defined.
> 	(riscv_lookup_target_description): New declaration when GDBSERVER
> 	is not defined.
> 	* nat/riscv-linux-tdesc.c (riscv_linux_read_description): Rename to...
> 	(riscv_linux_read_features): ...this, and return
> 	riscv_gdbarch_features instead of target_desc.
> 	* nat/riscv-linux-tdesc.h: Include 'arch/riscv.h'.
> 	(riscv_linux_read_description): Rename to...
> 	(riscv_linux_read_features): ...this.
> 	* riscv-linux-nat.c (riscv_linux_nat_target::read_description):
> 	Update to use riscv_gdbarch_features and
> 	riscv_lookup_target_description.
> 	* riscv-tdep.c (riscv_find_default_target_description): Use
> 	riscv_lookup_target_description instead of
> 	riscv_create_target_description.

 I have committed this change now.

  Maciej

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [committed v8 2/2] gdbserver: Add RISC-V/Linux support
  2020-02-14 19:33 ` [PATCH v7 2/2] gdbserver: Add RISC-V/Linux support Maciej W. Rozycki
@ 2020-02-19  1:35   ` Maciej W. Rozycki
  0 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2020-02-19  1:35 UTC (permalink / raw)
  To: gdb-patches
  Cc: Jim Wilson, Andrew Burgess, Palmer Dabbelt, Tom Tromey, guoren,
	lifang_xia, yunhai_shang, jiangshuai_li

Implement RISC-V/Linux support for both RV64 and RV32 systems, including
XML target description handling based on features determined, GPR and
FPR regset support including dynamic sizing of the latter, and software
breakpoint handling.  Define two NT_FPREGSET regsets of a different size
matching the FPR sizes supported for generic `gdbserver' code to pick
from according to what the OS supplies.

Also handle a glibc bug where ELF_NFPREG is defined in terms of NFPREG,
however NFPREG is nowhere defined.

2020-02-19  Maciej W. Rozycki  <macro@wdc.com>
	    Andrew Burgess  <andrew.burgess@embecosm.com>

	gdb/
	* NEWS: Mention RISC-V GNU/Linux GDBserver support.

	gdbserver/
	* linux-riscv-low.cc: New file.
	* Makefile.in (SFILES): Add linux-riscv-low.cc, arch/riscv.c,
	and nat/riscv-linux-tdesc.c.
	* configure.srv <riscv*-*-linux*> (srv_tgtobj)
	(srv_linux_regsets, srv_linux_usrregs, srv_linux_thread_db):
	Define.
---
This is the final version I have committed.

Changes from v7:

- Mention RISC-V GNU/Linux GDBserver support in gdb/NEWS.

Changes from v6:

- Regenerate for the gdbserver/ move to the top level.

- Use the .cc suffix following the rename of other files.

Changes from v4:

- Add 128-bit FP regset.

Changes from v3:

- Actually include changes from v2.

Changes from v2:

- Advance through the buffer accessed in `riscv_fill_fpregset' and
  `riscv_store_fpregset' so as to avoid doing a variable multiplication in
  a loop; rename the `regset' variable to `regbuf'.

- Use OPTIONAL_REGS rather than FP_REGS as the type for the floating-point
  regsets.

- Add comments throughout.

Changes from v1:

- Make `gdbserver' selected for automatic build in a RISC-V/Linux/native
  GDB configuration (thanks, Jim, for pointing this out!).

- Remove most of `riscv_arch_setup' and use `riscv_linux_read_description'
  from 2/3 instead.

- Stop using `elf_fpregset_t*' in favour to just a raw `gdb_byte *' buffer
  and size the regset according to the FPR size in `riscv_fill_fpregset'
  and `riscv_store_fpregset'.

- Define 2 NT_FPREGSET regsets of a different size for generic `gdbserver'
  code to pick from according to what the OS supplies.
---
 gdb/ChangeLog                |   4 +
 gdb/NEWS                     |   8 ++
 gdbserver/ChangeLog          |  10 ++
 gdbserver/Makefile.in        |   3 +
 gdbserver/configure.srv      |   7 ++
 gdbserver/linux-riscv-low.cc | 279 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 311 insertions(+)
 create mode 100644 gdbserver/linux-riscv-low.cc

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 144fd4f256a..0077a9824aa 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2020-02-19  Maciej W. Rozycki  <macro@wdc.com>
+
+	* NEWS: Mention RISC-V GNU/Linux GDBserver support.
+
 2020-02-19  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* arch/riscv.c (struct riscv_gdbarch_features_hasher): Only define
diff --git a/gdb/NEWS b/gdb/NEWS
index c202fe06de2..91add18d6f5 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 9
 
+* New features in the GDB remote stub, GDBserver
+
+  ** GDBserver is now supported on RISC-V GNU/Linux.
+
 * Debugging MS-Windows processes now sets $_exitsignal when the
   inferior is terminated by a signal, instead of setting $_exitcode.
 
@@ -26,6 +30,10 @@ show exec-file-mismatch -- Show exec-file-mismatch handling (ask|warn|off).
   whether to load the process executable file; if 'warn', just display
   a warning; if 'off', don't attempt to detect a mismatch.
 
+* New targets
+
+GNU/Linux/RISC-V (gdbserver)	riscv*-*-linux*
+
 *** Changes in GDB 9
 
 * 'thread-exited' event is now available in the annotations interface.
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
index d27eeb557da..4851002a7e5 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,3 +1,13 @@
+2020-02-19  Maciej W. Rozycki  <macro@wdc.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* linux-riscv-low.cc: New file.
+	* Makefile.in (SFILES): Add linux-riscv-low.cc, arch/riscv.c,
+	and nat/riscv-linux-tdesc.c.
+	* configure.srv <riscv*-*-linux*> (srv_tgtobj)
+	(srv_linux_regsets, srv_linux_usrregs, srv_linux_thread_db):
+	Define.
+
 2020-02-14  Tom Tromey  <tom@tromey.com>
 
 	* acinclude.m4: Don't include acx_configure_dir.m4.
diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in
index d66bc81da1c..1baebba0f56 100644
--- a/gdbserver/Makefile.in
+++ b/gdbserver/Makefile.in
@@ -177,6 +177,7 @@ SFILES = \
 	$(srcdir)/linux-mips-low.cc \
 	$(srcdir)/linux-nios2-low.cc \
 	$(srcdir)/linux-ppc-low.cc \
+	$(srcdir)/linux-riscv-low.cc \
 	$(srcdir)/linux-s390-low.cc \
 	$(srcdir)/linux-sh-low.cc \
 	$(srcdir)/linux-sparc-low.cc \
@@ -203,6 +204,7 @@ SFILES = \
 	$(srcdir)/../gdb/arch/arm-get-next-pcs.c \
 	$(srcdir)/../gdb/arch/arm-linux.c \
 	$(srcdir)/../gdb/arch/ppc-linux-common.c \
+	$(srcdir)/../gdb/arch/riscv.c \
 	$(srcdir)/../gdbsupport/btrace-common.cc \
 	$(srcdir)/../gdbsupport/buffer.cc \
 	$(srcdir)/../gdbsupport/cleanups.cc \
@@ -236,6 +238,7 @@ SFILES = \
 	$(srcdir)/../gdb/nat/linux-personality.c \
 	$(srcdir)/../gdb/nat/mips-linux-watch.c \
 	$(srcdir)/../gdb/nat/ppc-linux.c \
+	$(srcdir)/../gdb/nat/riscv-linux-tdesc.c \
 	$(srcdir)/../gdb/nat/fork-inferior.c \
 	$(srcdir)/../gdb/target/waitstatus.c
 
diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
index 375ac0aeb2a..ecdd63a310a 100644
--- a/gdbserver/configure.srv
+++ b/gdbserver/configure.srv
@@ -278,6 +278,13 @@ case "${gdbserver_host}" in
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu.xml"
 			srv_lynxos=yes
 			;;
+  riscv*-*-linux*)	srv_tgtobj="arch/riscv.o nat/riscv-linux-tdesc.o"
+			srv_tgtobj="${srv_tgtobj} linux-riscv-low.o"
+			srv_tgtobj="${srv_tgtobj} ${srv_linux_obj}"
+			srv_linux_regsets=yes
+			srv_linux_usrregs=yes
+			srv_linux_thread_db=yes
+			;;
   s390*-*-linux*)	srv_regobj="s390-linux32.o"
 			srv_regobj="${srv_regobj} s390-linux32v1.o"
 			srv_regobj="${srv_regobj} s390-linux32v2.o"
diff --git a/gdbserver/linux-riscv-low.cc b/gdbserver/linux-riscv-low.cc
new file mode 100644
index 00000000000..07ae6174ee3
--- /dev/null
+++ b/gdbserver/linux-riscv-low.cc
@@ -0,0 +1,279 @@
+/* GNU/Linux/RISC-V 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 "tdesc.h"
+#include "elf/common.h"
+#include "nat/riscv-linux-tdesc.h"
+#include "opcode/riscv.h"
+
+/* Work around glibc header breakage causing ELF_NFPREG not to be usable.  */
+#ifndef NFPREG
+# define NFPREG 33
+#endif
+
+/* Implementation of linux_target_ops method "arch_setup".  */
+
+static void
+riscv_arch_setup ()
+{
+  static const char *expedite_regs[] = { "sp", "pc", NULL };
+
+  const riscv_gdbarch_features features
+    = riscv_linux_read_features (lwpid_of (current_thread));
+  target_desc *tdesc = riscv_create_target_description (features);
+
+  if (!tdesc->expedite_regs)
+    init_target_desc (tdesc, expedite_regs);
+  current_process ()->tdesc = tdesc;
+}
+
+/* Collect GPRs from REGCACHE into BUF.  */
+
+static void
+riscv_fill_gregset (struct regcache *regcache, void *buf)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+  elf_gregset_t *regset = (elf_gregset_t *) buf;
+  int regno = find_regno (tdesc, "zero");
+  int i;
+
+  collect_register_by_name (regcache, "pc", *regset);
+  for (i = 1; i < ARRAY_SIZE (*regset); i++)
+    collect_register (regcache, regno + i, *regset + i);
+}
+
+/* Supply GPRs from BUF into REGCACHE.  */
+
+static void
+riscv_store_gregset (struct regcache *regcache, const void *buf)
+{
+  const elf_gregset_t *regset = (const elf_gregset_t *) buf;
+  const struct target_desc *tdesc = regcache->tdesc;
+  int regno = find_regno (tdesc, "zero");
+  int i;
+
+  supply_register_by_name (regcache, "pc", *regset);
+  supply_register_zeroed (regcache, regno);
+  for (i = 1; i < ARRAY_SIZE (*regset); i++)
+    supply_register (regcache, regno + i, *regset + i);
+}
+
+/* Collect FPRs from REGCACHE into BUF.  */
+
+static void
+riscv_fill_fpregset (struct regcache *regcache, void *buf)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+  int regno = find_regno (tdesc, "ft0");
+  int flen = register_size (regcache->tdesc, regno);
+  gdb_byte *regbuf = (gdb_byte *) buf;
+  int i;
+
+  for (i = 0; i < ELF_NFPREG - 1; i++, regbuf += flen)
+    collect_register (regcache, regno + i, regbuf);
+  collect_register_by_name (regcache, "fcsr", regbuf);
+}
+
+/* Supply FPRs from BUF into REGCACHE.  */
+
+static void
+riscv_store_fpregset (struct regcache *regcache, const void *buf)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+  int regno = find_regno (tdesc, "ft0");
+  int flen = register_size (regcache->tdesc, regno);
+  const gdb_byte *regbuf = (const gdb_byte *) buf;
+  int i;
+
+  for (i = 0; i < ELF_NFPREG - 1; i++, regbuf += flen)
+    supply_register (regcache, regno + i, regbuf);
+  supply_register_by_name (regcache, "fcsr", regbuf);
+}
+
+/* RISC-V/Linux regsets.  FPRs are optional and come in different sizes,
+   so define multiple regsets for them marking them all as OPTIONAL_REGS
+   rather than FP_REGS, so that "regsets_fetch_inferior_registers" picks
+   the right one according to size.  */
+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 (struct __riscv_mc_q_ext_state), OPTIONAL_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
+    sizeof (struct __riscv_mc_d_ext_state), OPTIONAL_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
+    sizeof (struct __riscv_mc_f_ext_state), OPTIONAL_REGS,
+    riscv_fill_fpregset, riscv_store_fpregset },
+  NULL_REGSET
+};
+
+/* RISC-V/Linux regset information.  */
+static struct regsets_info riscv_regsets_info =
+  {
+    riscv_regsets, /* regsets */
+    0, /* num_regsets */
+    NULL, /* disabled_regsets */
+  };
+
+/* Definition of linux_target_ops data member "regs_info".  */
+static struct regs_info riscv_regs =
+  {
+    NULL, /* regset_bitmap */
+    NULL, /* usrregs */
+    &riscv_regsets_info,
+  };
+
+/* Implementation of linux_target_ops method "regs_info".  */
+
+static const struct regs_info *
+riscv_regs_info ()
+{
+  return &riscv_regs;
+}
+
+/* Implementation of linux_target_ops method "fetch_register".  */
+
+static int
+riscv_fetch_register (struct regcache *regcache, int regno)
+{
+  const struct target_desc *tdesc = regcache->tdesc;
+
+  if (regno != find_regno (tdesc, "zero"))
+    return 0;
+  supply_register_zeroed (regcache, regno);
+  return 1;
+}
+
+/* Implementation of linux_target_ops method "get_pc".  */
+
+static CORE_ADDR
+riscv_get_pc (struct regcache *regcache)
+{
+  elf_gregset_t regset;
+
+  if (sizeof (regset[0]) == 8)
+    return linux_get_pc_64bit (regcache);
+  else
+    return linux_get_pc_32bit (regcache);
+}
+
+/* Implementation of linux_target_ops method "set_pc".  */
+
+static void
+riscv_set_pc (struct regcache *regcache, CORE_ADDR newpc)
+{
+  elf_gregset_t regset;
+
+  if (sizeof (regset[0]) == 8)
+    linux_set_pc_64bit (regcache, newpc);
+  else
+    linux_set_pc_32bit (regcache, newpc);
+}
+
+/* Correct in either endianness.  */
+static const uint16_t riscv_ibreakpoint[] = { 0x0073, 0x0010 };
+static const uint16_t riscv_cbreakpoint = 0x9002;
+
+/* Implementation of linux_target_ops method "breakpoint_kind_from_pc".  */
+
+static int
+riscv_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
+{
+  union
+    {
+      gdb_byte bytes[2];
+      uint16_t insn;
+    }
+  buf;
+
+  if (target_read_memory (*pcptr, buf.bytes, sizeof (buf.insn)) == 0
+      && riscv_insn_length (buf.insn == sizeof (riscv_ibreakpoint)))
+    return sizeof (riscv_ibreakpoint);
+  else
+    return sizeof (riscv_cbreakpoint);
+}
+
+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind".  */
+
+static const gdb_byte *
+riscv_sw_breakpoint_from_kind (int kind, int *size)
+{
+  *size = kind;
+  switch (kind)
+    {
+      case sizeof (riscv_ibreakpoint):
+	return (const gdb_byte *) &riscv_ibreakpoint;
+      default:
+	return (const gdb_byte *) &riscv_cbreakpoint;
+    }
+}
+
+/* Implementation of linux_target_ops method "breakpoint_at".  */
+
+static int
+riscv_breakpoint_at (CORE_ADDR pc)
+{
+  union
+    {
+      gdb_byte bytes[2];
+      uint16_t insn;
+    }
+  buf;
+
+  if (target_read_memory (pc, buf.bytes, sizeof (buf.insn)) == 0
+      && (buf.insn == riscv_cbreakpoint
+	  || (buf.insn == riscv_ibreakpoint[0]
+	      && target_read_memory (pc + sizeof (buf.insn), buf.bytes,
+				     sizeof (buf.insn)) == 0
+	      && buf.insn == riscv_ibreakpoint[1])))
+    return 1;
+  else
+    return 0;
+}
+
+/* RISC-V/Linux target operations.  */
+struct linux_target_ops the_low_target =
+{
+  riscv_arch_setup,
+  riscv_regs_info,
+  NULL, /* cannot_fetch_register */
+  NULL, /* cannot_store_register */
+  riscv_fetch_register,
+  riscv_get_pc,
+  riscv_set_pc,
+  riscv_breakpoint_kind_from_pc,
+  riscv_sw_breakpoint_from_kind,
+  NULL, /* get_next_pcs */
+  0,    /* decr_pc_after_break */
+  riscv_breakpoint_at,
+};
+
+/* Initialize the RISC-V/Linux target.  */
+
+void
+initialize_low_arch ()
+{
+  initialize_regsets_info (&riscv_regsets_info);
+}
-- 
2.11.0

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-02-19  1:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-14 19:32 [PATCH v7 0/2] RISC-V/Linux `gdbserver' support and associated fixes Maciej W. Rozycki
2020-02-14 19:32 ` [PATCH v7 1/2] gdb/riscv: Update API for looking up target descriptions Maciej W. Rozycki
2020-02-19  1:28   ` Maciej W. Rozycki
2020-02-14 19:33 ` [PATCH v7 2/2] gdbserver: Add RISC-V/Linux support Maciej W. Rozycki
2020-02-19  1:35   ` [committed v8 " Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).