public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/16] Default register groups, and general related cleanup
@ 2022-03-31 21:04 Andrew Burgess
  2022-03-31 21:04 ` [PATCH 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
                   ` (16 more replies)
  0 siblings, 17 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This work started with this thread:

  https://sourceware.org/pipermail/gdb-patches/2022-March/187071.html

In which it was discovered that the ppc targets don't add the default
register groups during gdbarch initialisation.

I've run into this problem before, and every time I wonder why the
default register groups aren't added by default in all cases.

So, looked at doing just that.

But the register group management code was feeling a bit crusty, so I
thought I'd clean it up.

Then I hit some bugs, which I figured I'd fix.

Anyway, patch #9 is what I set out to do.  Everything else is me
trying to improve the register group handling code.

All feedback welcome.

Thanks,
Andrew

---

Andrew Burgess (16):
  gdb: don't try to use readline before it's initialized
  gdb: add some const in gdb/reggroups.c
  gdb: make gdbarch_register_reggroup_p take a const reggroup *
  gdb: switch to using 'const reggroup *' in tui-regs.{c,h}
  gdb: use 'const reggroup *' in python/py-registers.c file
  gdb: have reggroup_find return a const
  gdb/tui: avoid theoretical bug with 'tui reg' command
  gdb/tui: fix 'tui reg next/prev' command when data window is hidden
  gdb: always add the default register groups
  gdb: convert reggroups to use a std::vector
  gdb: remove reggroup_next and reggroup_prev
  gdb: more 'const' in gdb/reggroups.{c,h}
  gdb: make the pre-defined register groups const
  gdb: convert reggroup to a C++ class with constructor, etc
  gdb: move struct reggroup into reggroups.h header
  gdb: update comments throughout reggroups.{c,h} files

 gdb/aarch64-tdep.c             |  19 +--
 gdb/alpha-tdep.c               |   2 +-
 gdb/amd64-linux-tdep.c         |   2 +-
 gdb/arc-tdep.c                 |  17 --
 gdb/arm-tdep.c                 |   2 +-
 gdb/completer.c                |   8 +-
 gdb/csky-tdep.c                |  14 +-
 gdb/gdbarch-components.py      |   2 +-
 gdb/gdbarch-gen.h              |   4 +-
 gdb/gdbarch.c                  |   2 +-
 gdb/i386-linux-tdep.c          |   2 +-
 gdb/i386-tdep.c                |  13 +-
 gdb/i386-tdep.h                |   2 +-
 gdb/ia64-tdep.c                |   2 +-
 gdb/infcmd.c                   |  14 +-
 gdb/lm32-tdep.c                |  13 +-
 gdb/m32c-tdep.c                |   9 +-
 gdb/m68hc11-tdep.c             |  13 +-
 gdb/mep-tdep.c                 |  12 +-
 gdb/mips-tdep.c                |   4 +-
 gdb/msp430-tdep.c              |   2 +-
 gdb/nds32-tdep.c               |  32 ++--
 gdb/or1k-tdep.c                |  14 +-
 gdb/python/py-registers.c      |  32 ++--
 gdb/regcache-dump.c            |   9 +-
 gdb/reggroups.c                | 298 ++++++++++++---------------------
 gdb/reggroups.h                |  94 +++++++----
 gdb/riscv-tdep.c               |  18 +-
 gdb/rl78-tdep.c                |   2 +-
 gdb/rs6000-tdep.c              |   2 +-
 gdb/s390-tdep.c                |   2 +-
 gdb/sh-tdep.c                  |   2 +-
 gdb/target-descriptions.c      |   6 +-
 gdb/target-descriptions.h      |   2 +-
 gdb/testsuite/gdb.tui/regs.exp |  26 +++
 gdb/tui/tui-regs.c             | 111 +++++++-----
 gdb/tui/tui-regs.h             |   9 +-
 gdb/utils.c                    |  17 +-
 gdb/xtensa-tdep.c              |  25 +--
 39 files changed, 373 insertions(+), 486 deletions(-)

-- 
2.25.4


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

* [PATCH 01/16] gdb: don't try to use readline before it's initialized
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

While working on a different patch, I triggered an assertion from the
initialize_current_architecture code, specifically from one of
the *_gdbarch_init functions in a *-tdep.c file.  This exposes a
couple of issues with GDB.

This is easy enough to reproduce by adding 'gdb_assert (false)' into a
suitable function.  For example, I added a line into i386_gdbarch_init
and can see the following issue.

I start GDB and immediately hit the assert, the output is as you'd
expect, except for the very last line:

  $ ./gdb/gdb --data-directory ./gdb/data-directory/
  ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  ----- Backtrace -----
  ... snip ...
  ---------------------
  ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  Quit this debugging session? (y or n) ../../src.dev-1/gdb/ser-event.c:212:16: runtime error: member access within null pointer of type 'struct serial'

Something goes wrong when we try to query the user.  Note, I
configured GDB with --enable-ubsan, I suspect that without this the
above "error" would actually just be a crash.

The backtrace from ser-event.c:212 looks like this:

  (gdb) bt 10
  #0  serial_event_clear (event=0x675c020) at ../../src/gdb/ser-event.c:212
  #1  0x0000000000769456 in invoke_async_signal_handlers () at ../../src/gdb/async-event.c:211
  #2  0x000000000295049b in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:194
  #3  0x0000000001f015f8 in gdb_readline_wrapper (
      prompt=0x67135c0 "../../src/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugg"...)
      at ../../src/gdb/top.c:1141
  #4  0x0000000002118b64 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) (
      ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ", defchar=0 '\000', args=0x7fffffffa6e0)
      at ../../src/gdb/utils.c:934
  #5  0x0000000002118f72 in query (ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ")
      at ../../src/gdb/utils.c:1026
  #6  0x00000000021170f6 in internal_vproblem(internal_problem *, const char *, int, const char *, typedef __va_list_tag __va_list_tag *) (problem=0x6107bc0 <internal_error_problem>, file=0x2b976c8 "../../src/gdb/i386-tdep.c",
      line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:417
  #7  0x00000000021175a0 in internal_verror (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455,
      fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:485
  #8  0x00000000029503b3 in internal_error (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455,
      fmt=0x2b96d7f "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:55
  #9  0x000000000122d5b6 in i386_gdbarch_init (info=..., arches=0x0) at ../../src/gdb/i386-tdep.c:8455
  (More stack frames follow...)

It turns out that the problem is that the async event handler
mechanism has been invoked, but this has not yet been initialized.

If we look at gdb_init (in gdb/top.c) we can indeed see the call to
gdb_init_signals is after the call to initialize_current_architecture.

If I reorder the calls, moving gdb_init_signals earlier, then the
initial error is resolved, however, things are still broken.  I now
see the same "Quit this debugging session? (y or n)" prompt, but when
I provide an answer and press return GDB immediately crashes.

So what's going on now?  The next problem is that the call_readline
field within the current_ui structure is not initialized, and this
callback is invoked to process the reply I entered.

The problem is that call_readline is setup as a result of calling
set_top_level_interpreter, which is called from captured_main_1.
Unfortunately, set_top_level_interpreter is called after gdb_init is
called.

I wondered how to solve this problem for a while, however, I don't
know if there's an easy "just reorder some lines" solution here.
Looking through captured_main_1 there seems to be a bunch of
dependencies between printing various things, parsing config files,
and setting up the interpreter.  I'm sure there is a solution hiding
in there somewhere.... I'm just not sure I want to spend any longer
looking for it.

So.

I propose a simpler solution, more of a hack/work-around.  In utils.c
we already have a function filtered_printing_initialized, this is
checked in a few places within internal_vproblem.  In some of these
cases the call gates whether or not GDB will query the user.

My proposal is to add a new readline_initialized function, which
checks if the current_ui has had readline initialized yet.  If this is
not the case then we should not attempt to query the user.

After this change GDB prints the error message, the backtrace, and
then aborts (including dumping core).  This actually seems pretty sane
as, if GDB has not yet made it through the initialization then it
doesn't make much sense to allow the user to say "no, I don't want to
quit the debug session" (I think).
---
 gdb/utils.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/gdb/utils.c b/gdb/utils.c
index 9ca268ad07f..375614d685d 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -306,6 +306,16 @@ struct internal_problem
   bool should_print_backtrace;
 };
 
+/* Return true if the readline callbacks have been initialized for UI.
+   This is always true once GDB is fully initialized, but during the early
+   startup phase this is initially false.  */
+
+static bool
+readline_initialized (struct ui *ui)
+{
+  return ui->call_readline != nullptr;
+}
+
 /* Report a problem, internal to GDB, to the user.  Once the problem
    has been reported, and assuming GDB didn't quit, the caller can
    either allow execution to resume or throw an error.  */
@@ -378,6 +388,7 @@ internal_vproblem (struct internal_problem *problem,
   if (problem->should_quit != internal_problem_ask
       || !confirm
       || !filtered_printing_initialized ()
+      || !readline_initialized (current_ui)
       || problem->should_print_backtrace)
     gdb_printf (gdb_stderr, "%s\n", reason.c_str ());
 
@@ -389,7 +400,8 @@ internal_vproblem (struct internal_problem *problem,
       /* Default (yes/batch case) is to quit GDB.  When in batch mode
 	 this lessens the likelihood of GDB going into an infinite
 	 loop.  */
-      if (!confirm || !filtered_printing_initialized ())
+      if (!confirm || !filtered_printing_initialized ()
+	  || !readline_initialized (current_ui))
 	quit_p = 1;
       else
 	quit_p = query (_("%s\nQuit this debugging session? "),
@@ -412,7 +424,8 @@ internal_vproblem (struct internal_problem *problem,
     {
       if (!can_dump_core_warn (LIMIT_MAX, reason.c_str ()))
 	dump_core_p = 0;
-      else if (!filtered_printing_initialized ())
+      else if (!filtered_printing_initialized ()
+	       || !readline_initialized (current_ui))
 	dump_core_p = 1;
       else
 	{
-- 
2.25.4


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

* [PATCH 02/16] gdb: add some const in gdb/reggroups.c
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
  2022-03-31 21:04 ` [PATCH 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This commit makes the 'struct reggroup *' argument const for the
following functions:

  reggroup_next
  reggroup_prev
  reggroup_name
  reggroup_type

There are other places that could benefit from const in the
reggroup.{c,h} files, but these will be changing in further commits.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 8 ++++----
 gdb/reggroups.h | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index b6afa2f895c..169285b7475 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -63,13 +63,13 @@ reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 /* Register group attributes.  */
 
 const char *
-reggroup_name (struct reggroup *group)
+reggroup_name (const struct reggroup *group)
 {
   return group->name;
 }
 
 enum reggroup_type
-reggroup_type (struct reggroup *group)
+reggroup_type (const struct reggroup *group)
 {
   return group->type;
 }
@@ -130,7 +130,7 @@ static struct reggroups default_groups = { NULL, &default_groups.first };
 /* A register group iterator.  */
 
 struct reggroup *
-reggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
+reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
 {
   struct reggroups *groups;
   struct reggroup_el *el;
@@ -161,7 +161,7 @@ reggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
 /* See reggroups.h.  */
 
 struct reggroup *
-reggroup_prev (struct gdbarch *gdbarch, struct reggroup *curr)
+reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
 {
   struct reggroups *groups;
   struct reggroup_el *el;
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index f2e60c4f1da..ef99483f39f 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -50,17 +50,17 @@ extern struct reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
 extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
 
 /* Register group attributes.  */
-extern const char *reggroup_name (struct reggroup *reggroup);
-extern enum reggroup_type reggroup_type (struct reggroup *reggroup);
+extern const char *reggroup_name (const struct reggroup *reggroup);
+extern enum reggroup_type reggroup_type (const struct reggroup *reggroup);
 
 /* Iterators for the architecture's register groups.  Pass in NULL, returns
    the first (for next), or last (for prev) group.  Pass in a group,
    returns the next or previous group, or NULL when either the end or the
    beginning of the group list is reached.  */
 extern struct reggroup *reggroup_next (struct gdbarch *gdbarch,
-				       struct reggroup *last);
+				       const struct reggroup *last);
 extern struct reggroup *reggroup_prev (struct gdbarch *gdbarch,
-				       struct reggroup *curr);
+				       const struct reggroup *curr);
 /* Find a reggroup by name.  */
 extern reggroup *reggroup_find (struct gdbarch *gdbarch, const char *name);
 
-- 
2.25.4


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

* [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup *
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
  2022-03-31 21:04 ` [PATCH 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
  2022-03-31 21:04 ` [PATCH 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-04-04 22:35   ` Lancelot SIX
  2022-03-31 21:04 ` [PATCH 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h} Andrew Burgess
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Change gdbarch_register_reggroup_p to take a 'const struct reggroup *'
argument.  This requires a change to the gdb/gdbarch-components.py
script, regeneration of gdbarch.{c,h}, and then updates to all the
architectures that implement this method.

There should be no user visible changes after this commit.
---
 gdb/aarch64-tdep.c        | 2 +-
 gdb/alpha-tdep.c          | 2 +-
 gdb/amd64-linux-tdep.c    | 2 +-
 gdb/arm-tdep.c            | 2 +-
 gdb/csky-tdep.c           | 2 +-
 gdb/gdbarch-components.py | 2 +-
 gdb/gdbarch-gen.h         | 4 ++--
 gdb/gdbarch.c             | 2 +-
 gdb/i386-linux-tdep.c     | 2 +-
 gdb/i386-tdep.c           | 2 +-
 gdb/i386-tdep.h           | 2 +-
 gdb/ia64-tdep.c           | 2 +-
 gdb/lm32-tdep.c           | 2 +-
 gdb/m32c-tdep.c           | 2 +-
 gdb/m68hc11-tdep.c        | 2 +-
 gdb/mep-tdep.c            | 2 +-
 gdb/mips-tdep.c           | 4 ++--
 gdb/msp430-tdep.c         | 2 +-
 gdb/nds32-tdep.c          | 2 +-
 gdb/reggroups.c           | 2 +-
 gdb/reggroups.h           | 2 +-
 gdb/riscv-tdep.c          | 2 +-
 gdb/rl78-tdep.c           | 2 +-
 gdb/rs6000-tdep.c         | 2 +-
 gdb/s390-tdep.c           | 2 +-
 gdb/sh-tdep.c             | 2 +-
 gdb/target-descriptions.c | 4 ++--
 gdb/target-descriptions.h | 2 +-
 gdb/xtensa-tdep.c         | 4 ++--
 29 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 9a14c4d59dc..400719fbd25 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -2695,7 +2695,7 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 
 static int
 aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				    struct reggroup *group)
+				    const struct reggroup *group)
 {
   aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 7f3af216675..f04bad6bed8 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -139,7 +139,7 @@ alpha_register_type (struct gdbarch *gdbarch, int regno)
 
 static int
 alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			   struct reggroup *group)
+			   const struct reggroup *group)
 {
   /* Filter out any registers eliminated, but whose regnum is 
      reserved for backward compatibility, e.g. the vfp.  */
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index b61428d0e84..208bb10308c 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -279,7 +279,7 @@ static int amd64_linux_sc_reg_offset[] =
 
 static int
 amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				 struct reggroup *group)
+				 const struct reggroup *group)
 { 
   if (regnum == AMD64_LINUX_ORIG_RAX_REGNUM
       || regnum == AMD64_FSBASE_REGNUM
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 4d0f3492410..c857f5ca7d1 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8986,7 +8986,7 @@ arm_elf_osabi_sniffer (bfd *abfd)
 
 static int
 arm_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			 const struct reggroup *group)
 {
   /* FPS register's type is INT, but belongs to float_reggroup.  Beside
      this, FPS register belongs to save_regroup, restore_reggroup, and
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index 09e8fc57246..f1376730c87 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -2063,7 +2063,7 @@ csky_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 csky_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *reggroup)
+			  const struct reggroup *reggroup)
 {
   int raw_p;
 
diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch-components.py
index c820ddae764..e8f20c83ff0 100644
--- a/gdb/gdbarch-components.py
+++ b/gdb/gdbarch-components.py
@@ -1460,7 +1460,7 @@ Is a register in a group
 """,
     type="int",
     name="register_reggroup_p",
-    params=[("int", "regnum"), ("struct reggroup *", "reggroup")],
+    params=[("int", "regnum"), ("const struct reggroup *", "reggroup")],
     predefault="default_register_reggroup_p",
     invalid=False,
 )
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 7a8721328ab..882b9057b1a 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -833,8 +833,8 @@ extern void set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarc
 
 /* Is a register in a group */
 
-typedef int (gdbarch_register_reggroup_p_ftype) (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup);
-extern int gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup);
+typedef int (gdbarch_register_reggroup_p_ftype) (struct gdbarch *gdbarch, int regnum, const struct reggroup *reggroup);
+extern int gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, const struct reggroup *reggroup);
 extern void set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, gdbarch_register_reggroup_p_ftype *register_reggroup_p);
 
 /* Fetch the pointer to the ith function argument. */
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index ff404f47727..a588bdef61a 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -3632,7 +3632,7 @@ set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch,
 }
 
 int
-gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup)
+gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, const struct reggroup *reggroup)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->register_reggroup_p != NULL);
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 1f1aaa7d60a..5d7f54194af 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -54,7 +54,7 @@
    group.  Put the LINUX_ORIG_EAX register in the system group.  */
 static int
 i386_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				struct reggroup *group)
+				const struct reggroup *group)
 {
   if (regnum == I386_LINUX_ORIG_EAX_REGNUM)
     return (group == system_reggroup
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 394bb08718c..e0c8efa8406 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4557,7 +4557,7 @@ i386_add_reggroups (struct gdbarch *gdbarch)
 
 int
 i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   const i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int fp_regnum_p, mmx_regnum_p, xmm_regnum_p, mxcsr_regnum_p,
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index eb58dd68e73..a8067cf6b6c 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -418,7 +418,7 @@ extern int i386_sigtramp_p (struct frame_info *this_frame);
 
 /* Return non-zero if REGNUM is a member of the specified group.  */
 extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				     struct reggroup *group);
+				     const struct reggroup *group);
 
 /* Supply register REGNUM from the general-purpose register set REGSET
    to register cache REGCACHE.  If REGNUM is -1, do this for all
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index c2d1a475bab..69a4b4db4fd 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -322,7 +322,7 @@ ia64_ext_type (struct gdbarch *gdbarch)
 
 static int
 ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   int vector_p;
   int float_p;
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index cb516e846f4..f3f1f87d6bb 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -73,7 +73,7 @@ lm32_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 lm32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   if (group == general_reggroup)
     return ((regnum >= SIM_LM32_R0_REGNUM) && (regnum <= SIM_LM32_RA_REGNUM))
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 5e4844bda0a..94087302892 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -252,7 +252,7 @@ m32c_debug_info_reg_to_regnum (struct gdbarch *gdbarch, int reg_nr)
 
 static int
 m32c_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   struct m32c_reg *reg = &tdep->regs[regnum];
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 070eeb8b3da..f1133fe6780 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1372,7 +1372,7 @@ m68hc11_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 m68hc11_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			     struct reggroup *group)
+			     const struct reggroup *group)
 {
   /* We must save the real hard register as well as gcc
      soft registers including the frame pointer.  */
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 696d9c63bce..50bea7cb49f 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1029,7 +1029,7 @@ static struct reggroup *mep_ccr_reggroup; /* coprocessor control */
 
 static int
 mep_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			 struct reggroup *group)
+			 const struct reggroup *group)
 {
   /* Filter reserved or unused register numbers.  */
   {
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 93945891407..97923e08f5d 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -698,7 +698,7 @@ mips_register_name (struct gdbarch *gdbarch, int regno)
 
 static int
 mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *reggroup)
+			  const struct reggroup *reggroup)
 {
   int vector_p;
   int float_p;
@@ -738,7 +738,7 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 
 static int
 mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				struct reggroup *reggroup)
+				const struct reggroup *reggroup)
 {
   int rawnum = regnum % gdbarch_num_regs (gdbarch);
   int pseudo = regnum / gdbarch_num_regs (gdbarch);
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 86277e0b186..28268a95139 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -203,7 +203,7 @@ msp430_register_name (struct gdbarch *gdbarch, int regnr)
 
 static int
 msp430_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			    struct reggroup *group)
+			    const struct reggroup *group)
 {
   if (group == all_reggroup)
     return 1;
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index f8548561853..425d7d90d64 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -368,7 +368,7 @@ nds32_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 nds32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			   struct reggroup *reggroup)
+			   const struct reggroup *reggroup)
 {
   const char *reg_name;
   const char *group_name;
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 169285b7475..d5a263f8109 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -190,7 +190,7 @@ reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
 /* Is REGNUM a member of REGGROUP?  */
 int
 default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			     struct reggroup *group)
+			     const struct reggroup *group)
 {
   int vector_p;
   int float_p;
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index ef99483f39f..df8e871e365 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -66,6 +66,6 @@ extern reggroup *reggroup_find (struct gdbarch *gdbarch, const char *name);
 
 /* Is REGNUM a member of REGGROUP?  */
 extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-					struct reggroup *reggroup);
+					const struct reggroup *reggroup);
 
 #endif
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index e569f9369b8..c039904daba 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1271,7 +1271,7 @@ riscv_is_unknown_csr (struct gdbarch *gdbarch, int regnum)
 
 static int
 riscv_register_reggroup_p (struct gdbarch  *gdbarch, int regnum,
-			   struct reggroup *reggroup)
+			   const struct reggroup *reggroup)
 {
   /* Used by 'info registers' and 'info registers <groupname>'.  */
 
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index df04939acb1..6ea0473081d 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -586,7 +586,7 @@ rl78_g10_register_name (struct gdbarch *gdbarch, int regnr)
 
 static int
 rl78_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   if (group == all_reggroup)
     return 1;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index c246ce8559a..4a2804dc85f 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2642,7 +2642,7 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 
 static int
 rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				   struct reggroup *group)
+				   const struct reggroup *group)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 91aee632c8e..e7a5c5b65ee 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -1440,7 +1440,7 @@ s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static int
 s390_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				 struct reggroup *group)
+				 const struct reggroup *group)
 {
   s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index c12d40b604c..2341a9beef6 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1490,7 +1490,7 @@ sh_default_register_type (struct gdbarch *gdbarch, int reg_nr)
    TODO: sh2a and dsp registers.  */
 static int
 sh_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			struct reggroup *reggroup)
+			const struct reggroup *reggroup)
 {
   if (gdbarch_register_name (gdbarch, regnum) == NULL
       || *gdbarch_register_name (gdbarch, regnum) == '\0')
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index ae3b8211167..33277c3d02d 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -1007,7 +1007,7 @@ tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
 
 int
 tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
-			      struct reggroup *reggroup)
+			      const struct reggroup *reggroup)
 {
   struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
 
@@ -1028,7 +1028,7 @@ tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
 
 static int
 tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regno,
-			   struct reggroup *reggroup)
+			   const struct reggroup *reggroup)
 {
   int num_regs = gdbarch_num_regs (gdbarch);
   int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);
diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h
index 9d959977062..3b90dedcd80 100644
--- a/gdb/target-descriptions.h
+++ b/gdb/target-descriptions.h
@@ -229,7 +229,7 @@ struct type *tdesc_find_type (struct gdbarch *gdbarch, const char *id);
    specify a group.  */
 
 int tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
-				  struct reggroup *reggroup);
+				  const struct reggroup *reggroup);
 
 /* Methods for constructing a target description.  */
 
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 203d2e883df..62be13643b2 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -755,7 +755,7 @@ xtensa_add_reggroups (struct gdbarch *gdbarch)
 }
 
 static int 
-xtensa_coprocessor_register_group (struct reggroup *group)
+xtensa_coprocessor_register_group (const struct reggroup *group)
 {
   int i;
 
@@ -776,7 +776,7 @@ xtensa_coprocessor_register_group (struct reggroup *group)
 static int
 xtensa_register_reggroup_p (struct gdbarch *gdbarch,
 			    int regnum,
-			    struct reggroup *group)
+			    const struct reggroup *group)
 {
   xtensa_gdbarch_tdep *tdep = (xtensa_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   xtensa_register_t* reg = &tdep->regmap[regnum];
-- 
2.25.4


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

* [PATCH 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h}
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (2 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 05/16] gdb: use 'const reggroup *' in python/py-registers.c file Andrew Burgess
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Make uses of 'reggroup *' const throughout tui-regs.{c,h}.

There should be no user visible changes after this commit.
---
 gdb/tui/tui-regs.c | 22 +++++++++++-----------
 gdb/tui/tui-regs.h |  9 +++++----
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 190985321eb..5c6189a59b1 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -177,7 +177,7 @@ tui_data_window::first_reg_element_no_inline (int line_no) const
 /* Show the registers of the given group in the data window
    and refresh the window.  */
 void
-tui_data_window::show_registers (struct reggroup *group)
+tui_data_window::show_registers (const reggroup *group)
 {
   if (group == 0)
     group = general_reggroup;
@@ -207,7 +207,7 @@ tui_data_window::show_registers (struct reggroup *group)
    refresh_values_only is true.  */
 
 void
-tui_data_window::show_register_group (struct reggroup *group,
+tui_data_window::show_register_group (const reggroup *group,
 				      struct frame_info *frame, 
 				      bool refresh_values_only)
 {
@@ -518,10 +518,10 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
    around behaviour.  Returns the next register group, or NULL if the
    register window is not currently being displayed.  */
 
-static struct reggroup *
-tui_reg_next (struct reggroup *current_group, struct gdbarch *gdbarch)
+static const reggroup *
+tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  struct reggroup *group = NULL;
+  const reggroup *group = NULL;
 
   if (current_group != NULL)
     {
@@ -536,10 +536,10 @@ tui_reg_next (struct reggroup *current_group, struct gdbarch *gdbarch)
    around behaviour.  Returns the previous register group, or NULL if the
    register window is not currently being displayed.  */
 
-static struct reggroup *
-tui_reg_prev (struct reggroup *current_group, struct gdbarch *gdbarch)
+static const reggroup *
+tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  struct reggroup *group = NULL;
+  const reggroup *group = NULL;
 
   if (current_group != NULL)
     {
@@ -561,7 +561,7 @@ tui_reg_command (const char *args, int from_tty)
 
   if (args != NULL)
     {
-      struct reggroup *group, *match = NULL;
+      const reggroup *group, *match = NULL;
       size_t len = strlen (args);
 
       /* Make sure the curses mode is enabled.  */
@@ -575,7 +575,7 @@ tui_reg_command (const char *args, int from_tty)
       if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ())
 	tui_regs_layout ();
 
-      struct reggroup *current_group = TUI_DATA_WIN->get_current_group ();
+      const reggroup *current_group = TUI_DATA_WIN->get_current_group ();
       if (strncmp (args, "next", len) == 0)
 	match = tui_reg_next (current_group, gdbarch);
       else if (strncmp (args, "prev", len) == 0)
@@ -603,7 +603,7 @@ tui_reg_command (const char *args, int from_tty)
     }
   else
     {
-      struct reggroup *group;
+      const reggroup *group;
       int first;
 
       gdb_printf (_("\"tui reg\" must be followed by the name of "
diff --git a/gdb/tui/tui-regs.h b/gdb/tui/tui-regs.h
index 9192a73b177..5289d3a892d 100644
--- a/gdb/tui/tui-regs.h
+++ b/gdb/tui/tui-regs.h
@@ -23,6 +23,7 @@
 #define TUI_TUI_REGS_H
 
 #include "tui/tui-data.h"
+#include "reggroups.h"
 
 /* A data item window.  */
 
@@ -60,9 +61,9 @@ struct tui_data_window : public tui_win_info
 
   void check_register_values (struct frame_info *frame);
 
-  void show_registers (struct reggroup *group);
+  void show_registers (const reggroup *group);
 
-  struct reggroup *get_current_group () const
+  const reggroup *get_current_group () const
   {
     return m_current_group;
   }
@@ -99,7 +100,7 @@ struct tui_data_window : public tui_win_info
      display off the end of the register display.  */
   void display_reg_element_at_line (int start_element_no, int start_line_no);
 
-  void show_register_group (struct reggroup *group,
+  void show_register_group (const reggroup *group,
 			    struct frame_info *frame,
 			    bool refresh_values_only);
 
@@ -125,7 +126,7 @@ struct tui_data_window : public tui_win_info
   /* Windows that are used to display registers.  */
   std::vector<tui_data_item_window> m_regs_content;
   int m_regs_column_count = 0;
-  struct reggroup *m_current_group = nullptr;
+  const reggroup *m_current_group = nullptr;
 
   /* Width of each register's display area.  */
   int m_item_width = 0;
-- 
2.25.4


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

* [PATCH 05/16] gdb: use 'const reggroup *' in python/py-registers.c file
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (3 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h} Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 06/16] gdb: have reggroup_find return a const Andrew Burgess
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert uses of 'struct reggroup *' in python/py-registers.c to be
'const'.

There should be no user visible changes after this commit.
---
 gdb/python/py-registers.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index eab88a30b3b..58d196c37b4 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -35,7 +35,7 @@ struct register_descriptor_iterator_object {
 
   /* The register group that the user is iterating over.  This will never
      be NULL.  */
-  struct reggroup *reggroup;
+  const struct reggroup *reggroup;
 
   /* The next register number to lookup.  Starts at 0 and counts up.  */
   int regnum;
@@ -66,7 +66,7 @@ struct reggroup_iterator_object {
   PyObject_HEAD
 
   /* The last register group returned.  Initially this will be NULL.  */
-  struct reggroup *reggroup;
+  const struct reggroup *reggroup;
 
   /* Pointer back to the architecture we're finding registers for.  */
   struct gdbarch *gdbarch;
@@ -80,7 +80,7 @@ struct reggroup_object {
   PyObject_HEAD
 
   /* The register group being described.  */
-  struct reggroup *reggroup;
+  const struct reggroup *reggroup;
 };
 
 extern PyTypeObject reggroup_object_type
@@ -101,12 +101,12 @@ gdbpy_register_object_data_init (struct gdbarch *gdbarch)
    returned for the same REGGROUP pointer.  */
 
 static gdbpy_ref<>
-gdbpy_get_reggroup (struct reggroup *reggroup)
+gdbpy_get_reggroup (const reggroup *reggroup)
 {
   /* Map from GDB's internal reggroup objects to the Python representation.
      GDB's reggroups are global, and are never deleted, so using a map like
      this is safe.  */
-  static std::unordered_map<struct reggroup *,gdbpy_ref<>>
+  static std::unordered_map<const struct reggroup *,gdbpy_ref<>>
     gdbpy_reggroup_object_map;
 
   /* If there is not already a suitable Python object in the map then
@@ -135,7 +135,7 @@ static PyObject *
 gdbpy_reggroup_to_string (PyObject *self)
 {
   reggroup_object *group = (reggroup_object *) self;
-  struct reggroup *reggroup = group->reggroup;
+  const reggroup *reggroup = group->reggroup;
 
   const char *name = reggroup_name (reggroup);
   return PyUnicode_FromString (name);
@@ -227,7 +227,7 @@ gdbpy_reggroup_iter_next (PyObject *self)
     = (reggroup_iterator_object *) self;
   struct gdbarch *gdbarch = iter_obj->gdbarch;
 
-  struct reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
+  const reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
   if (next_group == NULL)
     {
       PyErr_SetString (PyExc_StopIteration, _("No more groups"));
@@ -269,7 +269,7 @@ PyObject *
 gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
 					const char *group_name)
 {
-  struct reggroup *grp = NULL;
+  const reggroup *grp = NULL;
 
   /* Lookup the requested register group, or find the default.  */
   if (group_name == NULL || *group_name == '\0')
-- 
2.25.4


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

* [PATCH 06/16] gdb: have reggroup_find return a const
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (4 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 05/16] gdb: use 'const reggroup *' in python/py-registers.c file Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Update reggroup_find to return a const reggroup *.

There are other function in gdb/reggroup.{c,h} files that could
benefit from returning const, these will be updated in later commits.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 2 +-
 gdb/reggroups.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index d5a263f8109..6c38ca743f4 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -219,7 +219,7 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 
 /* See reggroups.h.  */
 
-reggroup *
+const reggroup *
 reggroup_find (struct gdbarch *gdbarch, const char *name)
 {
   struct reggroup *group;
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index df8e871e365..bc87a7325f0 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -62,7 +62,8 @@ extern struct reggroup *reggroup_next (struct gdbarch *gdbarch,
 extern struct reggroup *reggroup_prev (struct gdbarch *gdbarch,
 				       const struct reggroup *curr);
 /* Find a reggroup by name.  */
-extern reggroup *reggroup_find (struct gdbarch *gdbarch, const char *name);
+extern const reggroup *reggroup_find (struct gdbarch *gdbarch,
+				      const char *name);
 
 /* Is REGNUM a member of REGGROUP?  */
 extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-- 
2.25.4


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

* [PATCH 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (5 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 06/16] gdb: have reggroup_find return a const Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

While looking at the 'tui reg' command as part of another patch, I
spotted a theoretical bug.

The 'tui reg' command takes the name of a register group, but also
handles partial register group matches, though the partial match has to
be unique.  The current command logic goes:

With the code as currently written, if a target description named a
register group either 'prev' or 'next' then GDB would see this as an
ambiguous register name, and refuse to switch groups.

Naming a register group 'prev' or 'next' seems pretty unlikely, but,
by adding a single else block we can prevent this problem.

Now, if there's a 'prev' or 'next' register group, the user will not
be able to select the group directly, the 'prev' and 'next' names will
always iterate through the available groups instead.  But at least the
user could select their groups by iteration, rather than direct
selection.
---
 gdb/tui/tui-regs.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 5c6189a59b1..75ffa9babbf 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -580,19 +580,21 @@ tui_reg_command (const char *args, int from_tty)
 	match = tui_reg_next (current_group, gdbarch);
       else if (strncmp (args, "prev", len) == 0)
 	match = tui_reg_prev (current_group, gdbarch);
-
-      /* This loop matches on the initial part of a register group
-	 name.  If this initial part in ARGS matches only one register
-	 group then the switch is made.  */
-      for (group = reggroup_next (gdbarch, NULL);
-	   group != NULL;
-	   group = reggroup_next (gdbarch, group))
+      else
 	{
-	  if (strncmp (reggroup_name (group), args, len) == 0)
+	  /* This loop matches on the initial part of a register group
+	     name.  If this initial part in ARGS matches only one register
+	     group then the switch is made.  */
+	  for (group = reggroup_next (gdbarch, NULL);
+	       group != NULL;
+	       group = reggroup_next (gdbarch, group))
 	    {
-	      if (match != NULL)
-		error (_("ambiguous register group name '%s'"), args);
-	      match = group;
+	      if (strncmp (reggroup_name (group), args, len) == 0)
+		{
+		  if (match != NULL)
+		    error (_("ambiguous register group name '%s'"), args);
+		  match = group;
+		}
 	    }
 	}
 
-- 
2.25.4


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

* [PATCH 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (6 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 09/16] gdb: always add the default register groups Andrew Burgess
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Start GDB like:

  $ gdb -q executable
  (gdb) start
  (gdb) layout src
  ... tui windows are now displayed ...
  (gdb) tui reg next

At this point the data (register) window should be displayed, but will
contain the message 'Register Values Unavailable', and at the console
you'll see the message "unknown register group 'next'".

The same happens with 'tui reg prev' (but the error message is
slightly different).

At this point you can continue to use 'tui reg next' and/or 'tui reg
prev' and you'll keep getting the error message.

The problem is that when the data (register) window is first
displayed, it's current register group is nullptr.  As a consequence
tui_reg_next and tui_reg_prev (tui/tui-regs.c) will always just return
nullptr, which triggers an error in tui_reg_command.

In this commit I change tui_reg_next and tui_reg_prev so that they
instead return the first and last register group respectively if the
current register group is nullptr.

So, after this, using 'tui reg next' will (in the above case) show the
first register group, while 'tui reg prev' will display the last
register group.
---
 gdb/testsuite/gdb.tui/regs.exp | 26 ++++++++++++++++++++++++++
 gdb/tui/tui-regs.c             | 34 ++++++++++++++--------------------
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/gdb/testsuite/gdb.tui/regs.exp b/gdb/testsuite/gdb.tui/regs.exp
index 178eba03f19..833f6762d39 100644
--- a/gdb/testsuite/gdb.tui/regs.exp
+++ b/gdb/testsuite/gdb.tui/regs.exp
@@ -44,3 +44,29 @@ Term::check_box "source box in regs layout" 0 6 80 9
 set text [Term::get_line 1]
 # Just check for any register window content at all.
 Term::check_contents "any register contents" "\\|.*\[^ \].*\\|"
+
+
+# Check that we can successfully cause the register window to appear
+# using the 'tui reg next' and 'tui reg prev' commands.
+foreach_with_prefix cmd { next prev } {
+    Term::clean_restart 24 80 $testfile
+
+    if {![runto_main]} {
+	perror "test suppressed"
+	return
+    }
+
+    if {![Term::enter_tui]} {
+	unsupported "TUI not supported"
+	return
+    }
+
+    Term::command "tui reg ${cmd}"
+    Term::check_box "register box" 0 0 80 7
+    Term::check_box "source box in regs layout" 0 6 80 9
+    Term::check_region_contents "check register group title" \
+	0 0 80 1 "Register group: "
+    set contents [Term::get_region 0 15 80 8 "\r\n"]
+    gdb_assert {![regexp -- "unknown register group '${cmd}'" $contents]} \
+	"check register group is known"
+}
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 75ffa9babbf..b968947fa1c 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -515,38 +515,32 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
 }
 
 /* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
-   around behaviour.  Returns the next register group, or NULL if the
-   register window is not currently being displayed.  */
+   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
+   nullptr (e.g. if the tui register window has only just been displayed
+   and has no current group selected), then the first register group will
+   be returned.  */
 
 static const reggroup *
 tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = NULL;
-
-  if (current_group != NULL)
-    {
-      group = reggroup_next (gdbarch, current_group);
-      if (group == NULL)
-	group = reggroup_next (gdbarch, NULL);
-    }
+  const reggroup *group = reggroup_next (gdbarch, current_group);
+  if (group == NULL)
+    group = reggroup_next (gdbarch, NULL);
   return group;
 }
 
 /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
-   around behaviour.  Returns the previous register group, or NULL if the
-   register window is not currently being displayed.  */
+   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
+   nullptr (e.g. if the tui register window has only just been displayed
+   and has no current group selected), then the last register group will
+   be returned.  */
 
 static const reggroup *
 tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = NULL;
-
-  if (current_group != NULL)
-    {
-      group = reggroup_prev (gdbarch, current_group);
-      if (group == NULL)
-	group = reggroup_prev (gdbarch, NULL);
-    }
+  const reggroup *group = reggroup_prev (gdbarch, current_group);
+  if (group == NULL)
+    group = reggroup_prev (gdbarch, NULL);
   return group;
 }
 
-- 
2.25.4


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

* [PATCH 09/16] gdb: always add the default register groups
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (7 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 10/16] gdb: convert reggroups to use a std::vector Andrew Burgess
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

There's a set of 7 default register groups.  If we don't add any
gdbarch specific register groups during gdbarch initialisation, then
when we iterate over the register groups using reggroup_next and
reggroup_prev we will make use of these 7 default groups.  See the use
of default_groups in gdb/reggroups.c for details on this.

However, if the gdbarch adds its own groups during gdbarch
initialisation, then these groups will be used in preference to the
default groups.

A problem arises though if the particular architecture makes use of
the target description mechanism.  If the default target
description(s) (i.e. those internal to GDB that are used when the user
doesn't provide their own) don't mention any additional register
groups then the default register groups will be used.

But if the target description does mention additional groups then the
default groups are not used, and instead, the groups from the target
description are used.

The problem with this is that what usually happens is that the target
description will mention additional groups, e.g. groups for special
registers.  Most architectures that use target descriptions work
around this by adding all (or most) of the default register groups in
all cases.  See i386_add_reggroups, aarch64_add_reggroups,
riscv_add_reggroups, xtensa_add_reggroups, and others.

In this patch, my suggestion is that we should just add the default
register groups for every architecture, always.  This change is in
gdb/reggroups.c.

All the remaining changes are me updating the various architectures to
not add the default groups themselves.

So, where will this change be visible to the user?  I think the
following commands will possibly change:

* info registers / info all-registers:

  The user can provide a register group to these commands.  For example,
  on csky, we previously never added the 'vector' group.  Now, as a
  default group, this will be available, but (presumably) will not
  contain any registers.  I don't think this is necessarily a bad
  thing, there's something to be said for having some consistent
  defaults available.  There are other architectures that didn't add
  all 7 of the defaults, which will now have gained additional groups.

* maint print reggroups

  This prints the set of all available groups.  As a maintenance
  command I'm less concerned with the output changing here.
  Obviously, for the architectures that didn't previously add all the
  defaults, this list just got bigger.

* maint print register-groups

  This prints all the registers, and the groups they are in.  If the
  defaults were not previously being added then a register (obviously)
  can't appear in one of the default groups.  Now the groups are
  available then registers might be in more groups than previously.
  However, this is again a maintenance command, so I'm less concerned
  about this changing.
---
 gdb/aarch64-tdep.c | 17 -------------
 gdb/arc-tdep.c     | 17 -------------
 gdb/csky-tdep.c    |  2 --
 gdb/i386-tdep.c    |  7 ------
 gdb/lm32-tdep.c    | 11 ---------
 gdb/m32c-tdep.c    |  5 ----
 gdb/m68hc11-tdep.c |  7 ------
 gdb/mep-tdep.c     |  4 ----
 gdb/nds32-tdep.c   |  8 -------
 gdb/or1k-tdep.c    | 14 +----------
 gdb/reggroups.c    | 59 +++++++++++++++++++++++++++-------------------
 gdb/riscv-tdep.c   | 12 +---------
 gdb/xtensa-tdep.c  | 13 +---------
 13 files changed, 38 insertions(+), 138 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 400719fbd25..c852a0602ae 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3367,20 +3367,6 @@ aarch64_get_tdesc_vq (const struct target_desc *tdesc)
   return sve_vq_from_vl (vl);
 }
 
-/* Add all the expected register sets into GDBARCH.  */
-
-static void
-aarch64_add_reggroups (struct gdbarch *gdbarch)
-{
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-}
-
 /* Implement the "cannot_store_register" gdbarch method.  */
 
 static int
@@ -3636,9 +3622,6 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Virtual tables.  */
   set_gdbarch_vbit_in_delta (gdbarch, 1);
 
-  /* Register architecture.  */
-  aarch64_add_reggroups (gdbarch);
-
   /* Hook in the ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
   info.tdesc_data = tdesc_data.get ();
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index d6da2886c49..98bd1c4bc0a 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -1952,20 +1952,6 @@ static const struct frame_base arc_normal_base = {
   arc_frame_base_address
 };
 
-/* Add all the expected register sets into GDBARCH.  */
-
-static void
-arc_add_reggroups (struct gdbarch *gdbarch)
-{
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-}
-
 static enum arc_isa
 mach_type_to_arc_isa (const unsigned long mach)
 {
@@ -2364,9 +2350,6 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* This doesn't include possible long-immediate value.  */
   set_gdbarch_max_insn_length (gdbarch, 4);
 
-  /* Add default register groups.  */
-  arc_add_reggroups (gdbarch);
-
   /* Frame unwinders and sniffers.  */
   dwarf2_frame_set_init_reg (gdbarch, arc_dwarf2_frame_init_reg);
   dwarf2_append_unwinders (gdbarch);
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index f1376730c87..feb416a2406 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -2050,8 +2050,6 @@ csky_init_reggroup ()
 static void
 csky_add_reggroups (struct gdbarch *gdbarch)
 {
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
   reggroup_add (gdbarch, cr_reggroup);
   reggroup_add (gdbarch, fr_reggroup);
   reggroup_add (gdbarch, vr_reggroup);
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index e0c8efa8406..0f9e3fde6ce 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4546,13 +4546,6 @@ i386_add_reggroups (struct gdbarch *gdbarch)
 {
   reggroup_add (gdbarch, i386_sse_reggroup);
   reggroup_add (gdbarch, i386_mmx_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
 }
 
 int
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index f3f1f87d6bb..4a781c394e9 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -59,16 +59,6 @@ struct lm32_frame_cache
   trad_frame_saved_reg *saved_regs;
 };
 
-/* Add the available register groups.  */
-
-static void
-lm32_add_reggroups (struct gdbarch *gdbarch)
-{
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-}
-
 /* Return whether a given register is in a given group.  */
 
 static int
@@ -540,7 +530,6 @@ lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_push_dummy_call (gdbarch, lm32_push_dummy_call);
   set_gdbarch_return_value (gdbarch, lm32_return_value);
 
-  lm32_add_reggroups (gdbarch);
   set_gdbarch_register_reggroup_p (gdbarch, lm32_register_reggroup_p);
 
   return gdbarch;
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 94087302892..5a767c9ed52 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -981,11 +981,6 @@ make_regs (struct gdbarch *arch)
   set_gdbarch_dwarf2_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum);
   set_gdbarch_register_reggroup_p (arch, m32c_register_reggroup_p);
 
-  reggroup_add (arch, general_reggroup);
-  reggroup_add (arch, all_reggroup);
-  reggroup_add (arch, save_reggroup);
-  reggroup_add (arch, restore_reggroup);
-  reggroup_add (arch, system_reggroup);
   reggroup_add (arch, m32c_dma_reggroup);
 }
 
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index f1133fe6780..9d978d88018 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1361,13 +1361,6 @@ m68hc11_add_reggroups (struct gdbarch *gdbarch)
 {
   reggroup_add (gdbarch, m68hc11_hard_reggroup);
   reggroup_add (gdbarch, m68hc11_soft_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
 }
 
 static int
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 50bea7cb49f..e449c66c9b5 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -2428,10 +2428,6 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_stab_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum);
 
   set_gdbarch_register_reggroup_p (gdbarch, mep_register_reggroup_p);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
   reggroup_add (gdbarch, mep_csr_reggroup);
   reggroup_add (gdbarch, mep_cr_reggroup);
   reggroup_add (gdbarch, mep_ccr_reggroup);
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 425d7d90d64..a94a03ab2ab 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -343,14 +343,6 @@ nds32_init_reggroups (void)
 static void
 nds32_add_reggroups (struct gdbarch *gdbarch)
 {
-  /* Add pre-defined register groups.  */
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-
   /* Add NDS32 register groups.  */
   reggroup_add (gdbarch, nds32_cr_reggroup);
   reggroup_add (gdbarch, nds32_ir_reggroup);
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index 9f7fa2f169f..2b906fa69d3 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -1260,19 +1260,7 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   if (tdesc_data != NULL)
-    {
-      /* If we are using tdesc, register our own reggroups, otherwise we
-	 will used the defaults.  */
-      reggroup_add (gdbarch, general_reggroup);
-      reggroup_add (gdbarch, system_reggroup);
-      reggroup_add (gdbarch, float_reggroup);
-      reggroup_add (gdbarch, vector_reggroup);
-      reggroup_add (gdbarch, all_reggroup);
-      reggroup_add (gdbarch, save_reggroup);
-      reggroup_add (gdbarch, restore_reggroup);
-
-      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
-    }
+    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 6c38ca743f4..e47a6daf9a0 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -90,15 +90,6 @@ struct reggroups
 
 static struct gdbarch_data *reggroups_data;
 
-static void *
-reggroups_init (struct obstack *obstack)
-{
-  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
-
-  groups->last = &groups->first;
-  return groups;
-}
-
 /* Add a register group (with attribute values) to the pre-defined
    list.  */
 
@@ -119,13 +110,44 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
 
+  /* The same reggroup should not be added multiple times.  */
+  gdb_assert (groups != nullptr);
+  for (struct reggroup_el *el = groups->first;
+       el != nullptr;
+       el = el->next)
+    gdb_assert (group != el->group);
+
   add_group (groups, group,
 	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
 }
 
-/* The default register groups for an architecture.  */
+/* Called to initialize the per-gdbarch register group information.  */
 
-static struct reggroups default_groups = { NULL, &default_groups.first };
+static void *
+reggroups_init (struct obstack *obstack)
+{
+  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
+
+  groups->last = &groups->first;
+
+  /* Add the default groups.  */
+  add_group (groups, general_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, float_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, system_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, vector_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, all_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, save_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, restore_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+
+  return groups;
+}
 
 /* A register group iterator.  */
 
@@ -139,8 +161,7 @@ reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
      creation.  If there are no groups, use the default groups list.  */
   groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
   gdb_assert (groups != NULL);
-  if (groups->first == NULL)
-    groups = &default_groups;
+  gdb_assert (groups->first != NULL);
 
   /* Return the first/next reggroup.  */
   if (last == NULL)
@@ -171,8 +192,7 @@ reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
      creation.  If there are no groups, use the default groups list.  */
   groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
   gdb_assert (groups != NULL);
-  if (groups->first == NULL)
-    groups = &default_groups;
+  gdb_assert (groups->first != NULL);
 
   prev = NULL;
   for (el = groups->first; el != NULL; el = el->next)
@@ -327,15 +347,6 @@ _initialize_reggroup ()
 {
   reggroups_data = gdbarch_data_register_pre_init (reggroups_init);
 
-  /* The pre-defined list of groups.  */
-  add_group (&default_groups, general_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, float_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, system_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, vector_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, all_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, save_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, restore_reggroup, XNEW (struct reggroup_el));
-
   add_cmd ("reggroups", class_maintenance,
 	   maintenance_print_reggroups, _("\
 Print the internal register group names.\n\
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index c039904daba..ce62cfeb65c 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -3497,21 +3497,11 @@ riscv_find_default_target_description (const struct gdbarch_info info)
   return riscv_lookup_target_description (features);
 }
 
-/* Add all the expected register sets into GDBARCH.  */
+/* Add all the RISC-V specific register groups into GDBARCH.  */
 
 static void
 riscv_add_reggroups (struct gdbarch *gdbarch)
 {
-  /* Add predefined register groups.  */
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-
-  /* Add RISC-V specific register groups.  */
   reggroup_add (gdbarch, csr_reggroup);
 }
 
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 62be13643b2..6e478ee893d 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -734,23 +734,12 @@ xtensa_init_reggroups (void)
 static void
 xtensa_add_reggroups (struct gdbarch *gdbarch)
 {
-  int i;
-
-  /* Predefined groups.  */
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-
   /* Xtensa-specific groups.  */
   reggroup_add (gdbarch, xtensa_ar_reggroup);
   reggroup_add (gdbarch, xtensa_user_reggroup);
   reggroup_add (gdbarch, xtensa_vectra_reggroup);
 
-  for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
+  for (int i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
     reggroup_add (gdbarch, xtensa_cp[i]);
 }
 
-- 
2.25.4


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

* [PATCH 10/16] gdb: convert reggroups to use a std::vector
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (8 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 09/16] gdb: always add the default register groups Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Replace manual linked list with a std::vector.  This commit doesn't
change the reggroup_next and reggroup_prev API, but that will change
in a later commit.

This commit is focused on the minimal changes needed to manage the
reggroups using a std::vector, without changing the API exposed by the
reggroup.c file.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 153 ++++++++++++++++++++++++------------------------
 1 file changed, 75 insertions(+), 78 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index e47a6daf9a0..262bf49cea8 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -74,35 +74,46 @@ reggroup_type (const struct reggroup *group)
   return group->type;
 }
 
-/* A linked list of groups for the given architecture.  */
-
-struct reggroup_el
-{
-  struct reggroup *group;
-  struct reggroup_el *next;
-};
+/* A container holding all the register groups for a particular
+   architecture.  */
 
 struct reggroups
 {
-  struct reggroup_el *first;
-  struct reggroup_el **last;
+  /* Add GROUP to the list of register groups.  */
+
+  void add (struct reggroup *group)
+  {
+    gdb_assert (group != nullptr);
+    gdb_assert (std::find (m_groups.begin(), m_groups.end(), group)
+		== m_groups.end());
+
+    m_groups.push_back (group);
+  }
+
+  /* The number of register groups.  */
+
+  std::vector<struct reggroup *>::size_type
+  size () const
+  {
+    return m_groups.size ();
+  }
+
+  /* Return a reference to the list of all groups.  */
+
+  const std::vector<struct reggroup *> &
+  groups () const
+  {
+    return m_groups;
+  }
+
+private:
+  /* The register groups.  */
+  std::vector<struct reggroup *> m_groups;
 };
 
 static struct gdbarch_data *reggroups_data;
 
-/* Add a register group (with attribute values) to the pre-defined
-   list.  */
-
-static void
-add_group (struct reggroups *groups, struct reggroup *group,
-	   struct reggroup_el *el)
-{
-  gdb_assert (group != NULL);
-  el->group = group;
-  el->next = NULL;
-  (*groups->last) = el;
-  groups->last = &el->next;
-}
+/* Add GROUP to the list of register groups for GDBARCH.  */
 
 void
 reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
@@ -110,15 +121,10 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
 
-  /* The same reggroup should not be added multiple times.  */
   gdb_assert (groups != nullptr);
-  for (struct reggroup_el *el = groups->first;
-       el != nullptr;
-       el = el->next)
-    gdb_assert (group != el->group);
+  gdb_assert (group != nullptr);
 
-  add_group (groups, group,
-	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
+  groups->add (group);
 }
 
 /* Called to initialize the per-gdbarch register group information.  */
@@ -126,25 +132,16 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
 static void *
 reggroups_init (struct obstack *obstack)
 {
-  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
-
-  groups->last = &groups->first;
+  struct reggroups *groups = obstack_new<struct reggroups> (obstack);
 
   /* Add the default groups.  */
-  add_group (groups, general_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, float_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, system_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, vector_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, all_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, save_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, restore_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  groups->add (general_reggroup);
+  groups->add (float_reggroup);
+  groups->add (system_reggroup);
+  groups->add (vector_reggroup);
+  groups->add (all_reggroup);
+  groups->add (save_reggroup);
+  groups->add (restore_reggroup);
 
   return groups;
 }
@@ -154,29 +151,28 @@ reggroups_init (struct obstack *obstack)
 struct reggroup *
 reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
 {
-  struct reggroups *groups;
-  struct reggroup_el *el;
-
   /* Don't allow this function to be called during architecture
      creation.  If there are no groups, use the default groups list.  */
-  groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
-  gdb_assert (groups != NULL);
-  gdb_assert (groups->first != NULL);
+  struct reggroups *groups
+    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
+  gdb_assert (groups != nullptr);
+  gdb_assert (groups->size () > 0);
 
   /* Return the first/next reggroup.  */
-  if (last == NULL)
-    return groups->first->group;
-  for (el = groups->first; el != NULL; el = el->next)
+  if (last == nullptr)
+    return groups->groups ().front ();
+  for (int i = 0; i < groups->size (); ++i)
     {
-      if (el->group == last)
+      if (groups->groups ()[i] == last)
 	{
-	  if (el->next != NULL)
-	    return el->next->group;
+	  if (i + 1 < groups->size ())
+	    return groups->groups ()[i + 1];
 	  else
-	    return NULL;
+	    return nullptr;
 	}
     }
-  return NULL;
+
+  return nullptr;
 }
 
 /* See reggroups.h.  */
@@ -184,27 +180,28 @@ reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
 struct reggroup *
 reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
 {
-  struct reggroups *groups;
-  struct reggroup_el *el;
-  struct reggroup *prev;
-
   /* Don't allow this function to be called during architecture
      creation.  If there are no groups, use the default groups list.  */
-  groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
-  gdb_assert (groups != NULL);
-  gdb_assert (groups->first != NULL);
+  struct reggroups *groups
+    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
+  gdb_assert (groups != nullptr);
+  gdb_assert (groups->size () > 0);
 
-  prev = NULL;
-  for (el = groups->first; el != NULL; el = el->next)
+  /* Return the first/next reggroup.  */
+  if (curr == nullptr)
+    return groups->groups ().back ();
+  for (int i = groups->size () - 1; i >= 0; --i)
     {
-      gdb_assert (el->group != NULL);
-      if (el->group == curr)
-	return prev;
-      prev = el->group;
+      if (groups->groups ()[i] == curr)
+	{
+	  if (i - 1 >= 0)
+	    return groups->groups ()[i - 1];
+	  else
+	    return nullptr;
+	}
     }
-  if (curr == NULL)
-    return prev;
-  return NULL;
+
+  return nullptr;
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -234,7 +231,7 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
     return (!vector_p && !float_p);
   if (group == save_reggroup || group == restore_reggroup)
     return raw_p;
-  return 0;   
+  return 0;
 }
 
 /* See reggroups.h.  */
@@ -273,7 +270,7 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
 	  name = reggroup_name (group);
 	gdb_printf (file, " %-10s", name);
       }
-      
+
       /* Group type.  */
       {
 	const char *type;
-- 
2.25.4


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

* [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (9 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 10/16] gdb: convert reggroups to use a std::vector Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-04-05 23:11   ` Lancelot SIX
  2022-03-31 21:04 ` [PATCH 12/16] gdb: more 'const' in gdb/reggroups.{c,h} Andrew Burgess
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Add a new function gdbarch_reggroups that returns a reference to a
vector containing all the reggroups for an architecture.

Make use of this function throughout GDB instead of the existing
reggroup_next and reggroup_prev functions.

Finally, delete the reggroup_next and reggroup_prev functions.

Most of these changes are pretty straight forward, using range based
for loops instead of the old style look using reggroup_next.  There
are two places where the changes are less straight forward.

In gdb/python/py-registers.c, the register group iterator needed to
change slightly.  As the iterator is tightly coupled to the gdbarch, I
just fetch the register group vector from the gdbarch when needed, and
use an index counter to find the next item from the vector when
needed.

In gdb/tui/tui-regs.c the tui_reg_next and tui_reg_prev functions are
just wrappers around reggroup_next and reggroup_prev respectively.
I've just inlined the logic of the old functions into the tui
functions.  As the tui function had its own special twist (wrap around
behaviour) I think this is OK.

There should be no user visible changes after this commit.
---
 gdb/completer.c           |   6 +-
 gdb/infcmd.c              |  14 ++---
 gdb/python/py-registers.c |  17 +++---
 gdb/regcache-dump.c       |   6 +-
 gdb/reggroups.c           | 118 ++++++++------------------------------
 gdb/reggroups.h           |  12 ++--
 gdb/tui/tui-regs.c        |  59 +++++++++++++------
 7 files changed, 88 insertions(+), 144 deletions(-)

diff --git a/gdb/completer.c b/gdb/completer.c
index a51c16ac7f8..8bb12f256af 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1895,11 +1895,7 @@ reg_or_group_completer_1 (completion_tracker &tracker,
 
   if ((targets & complete_reggroup_names) != 0)
     {
-      struct reggroup *group;
-
-      for (group = reggroup_next (gdbarch, NULL);
-	   group != NULL;
-	   group = reggroup_next (gdbarch, group))
+      for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	{
 	  name = reggroup_name (group);
 	  if (strncmp (word, name, len) == 0)
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index fbae4e14a5f..a28250a456d 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2295,17 +2295,17 @@ registers_info (const char *addr_exp, int fpregs)
 
       /* A register group?  */
       {
-	struct reggroup *group;
-
-	for (group = reggroup_next (gdbarch, NULL);
-	     group != NULL;
-	     group = reggroup_next (gdbarch, group))
+	const struct reggroup *group = nullptr;
+	for (const struct reggroup *g : gdbarch_reggroups (gdbarch))
 	  {
 	    /* Don't bother with a length check.  Should the user
 	       enter a short register group name, go with the first
 	       group that matches.  */
-	    if (strncmp (start, reggroup_name (group), end - start) == 0)
-	      break;
+	    if (strncmp (start, reggroup_name (g), end - start) == 0)
+	      {
+		group = g;
+		break;
+	      }
 	  }
 	if (group != NULL)
 	  {
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index 58d196c37b4..7a9d2e22403 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -65,8 +65,8 @@ extern PyTypeObject register_descriptor_object_type
 struct reggroup_iterator_object {
   PyObject_HEAD
 
-  /* The last register group returned.  Initially this will be NULL.  */
-  const struct reggroup *reggroup;
+  /* The index into GROUPS for the next group to return.  */
+  std::vector<const reggroup *>::size_type index;
 
   /* Pointer back to the architecture we're finding registers for.  */
   struct gdbarch *gdbarch;
@@ -225,17 +225,18 @@ gdbpy_reggroup_iter_next (PyObject *self)
 {
   reggroup_iterator_object *iter_obj
     = (reggroup_iterator_object *) self;
-  struct gdbarch *gdbarch = iter_obj->gdbarch;
 
-  const reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
-  if (next_group == NULL)
+  const std::vector<const reggroup *> &groups
+    = gdbarch_reggroups (iter_obj->gdbarch);
+  if (iter_obj->index >= groups.size ())
     {
       PyErr_SetString (PyExc_StopIteration, _("No more groups"));
       return NULL;
     }
 
-  iter_obj->reggroup = next_group;
-  return gdbpy_get_reggroup (iter_obj->reggroup).release ();
+  const reggroup *group = groups[iter_obj->index];
+  iter_obj->index++;
+  return gdbpy_get_reggroup (group).release ();
 }
 
 /* Return a new gdb.RegisterGroupsIterator over all the register groups in
@@ -252,7 +253,7 @@ gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch)
 		    &reggroup_iterator_object_type);
   if (iter == NULL)
     return NULL;
-  iter->reggroup = NULL;
+  iter->index = 0;
   iter->gdbarch = gdbarch;
   return (PyObject *) iter;
 }
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c
index 2a2578558f7..409a868be76 100644
--- a/gdb/regcache-dump.c
+++ b/gdb/regcache-dump.c
@@ -192,11 +192,7 @@ class register_dump_groups : public register_dump
     else
       {
 	const char *sep = "";
-	struct reggroup *group;
-
-	for (group = reggroup_next (m_gdbarch, NULL);
-	     group != NULL;
-	     group = reggroup_next (m_gdbarch, group))
+	for (const struct reggroup *group : gdbarch_reggroups (m_gdbarch))
 	  {
 	    if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group))
 	      {
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 262bf49cea8..4607c4b674c 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -100,7 +100,7 @@ struct reggroups
 
   /* Return a reference to the list of all groups.  */
 
-  const std::vector<struct reggroup *> &
+  const std::vector<const struct reggroup *> &
   groups () const
   {
     return m_groups;
@@ -108,7 +108,7 @@ struct reggroups
 
 private:
   /* The register groups.  */
-  std::vector<struct reggroup *> m_groups;
+  std::vector<const struct reggroup *> m_groups;
 };
 
 static struct gdbarch_data *reggroups_data;
@@ -146,62 +146,15 @@ reggroups_init (struct obstack *obstack)
   return groups;
 }
 
-/* A register group iterator.  */
-
-struct reggroup *
-reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
-{
-  /* Don't allow this function to be called during architecture
-     creation.  If there are no groups, use the default groups list.  */
-  struct reggroups *groups
-    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
-  gdb_assert (groups != nullptr);
-  gdb_assert (groups->size () > 0);
-
-  /* Return the first/next reggroup.  */
-  if (last == nullptr)
-    return groups->groups ().front ();
-  for (int i = 0; i < groups->size (); ++i)
-    {
-      if (groups->groups ()[i] == last)
-	{
-	  if (i + 1 < groups->size ())
-	    return groups->groups ()[i + 1];
-	  else
-	    return nullptr;
-	}
-    }
-
-  return nullptr;
-}
-
 /* See reggroups.h.  */
-
-struct reggroup *
-reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
+const std::vector<const reggroup *>
+gdbarch_reggroups (struct gdbarch *gdbarch)
 {
-  /* Don't allow this function to be called during architecture
-     creation.  If there are no groups, use the default groups list.  */
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
   gdb_assert (groups != nullptr);
   gdb_assert (groups->size () > 0);
-
-  /* Return the first/next reggroup.  */
-  if (curr == nullptr)
-    return groups->groups ().back ();
-  for (int i = groups->size () - 1; i >= 0; --i)
-    {
-      if (groups->groups ()[i] == curr)
-	{
-	  if (i - 1 >= 0)
-	    return groups->groups ()[i - 1];
-	  else
-	    return nullptr;
-	}
-    }
-
-  return nullptr;
+  return groups->groups ();
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -239,11 +192,7 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 const reggroup *
 reggroup_find (struct gdbarch *gdbarch, const char *name)
 {
-  struct reggroup *group;
-
-  for (group = reggroup_next (gdbarch, NULL);
-       group != NULL;
-       group = reggroup_next (gdbarch, group))
+  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
       if (strcmp (name, reggroup_name (group)) == 0)
 	return group;
@@ -256,52 +205,35 @@ reggroup_find (struct gdbarch *gdbarch, const char *name)
 static void
 reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct reggroup *group = NULL;
+  static constexpr const char *fmt = " %-10s %-10s\n";
 
-  do
+  gdb_printf (file, fmt, "Group", "Type");
+
+  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
       /* Group name.  */
-      {
-	const char *name;
-
-	if (group == NULL)
-	  name = "Group";
-	else
-	  name = reggroup_name (group);
-	gdb_printf (file, " %-10s", name);
-      }
+      const char *name = reggroup_name (group);
 
       /* Group type.  */
-      {
-	const char *type;
-
-	if (group == NULL)
-	  type = "Type";
-	else
-	  {
-	    switch (reggroup_type (group))
-	      {
-	      case USER_REGGROUP:
-		type = "user";
-		break;
-	      case INTERNAL_REGGROUP:
-		type = "internal";
-		break;
-	      default:
-		internal_error (__FILE__, __LINE__, _("bad switch"));
-	      }
-	  }
-	gdb_printf (file, " %-10s", type);
-      }
+      const char *type;
+
+      switch (reggroup_type (group))
+	{
+	case USER_REGGROUP:
+	  type = "user";
+	  break;
+	case INTERNAL_REGGROUP:
+	  type = "internal";
+	  break;
+	default:
+	  internal_error (__FILE__, __LINE__, _("bad switch"));
+	}
 
       /* Note: If you change this, be sure to also update the
 	 documentation.  */
-      
-      gdb_printf (file, "\n");
 
-      group = reggroup_next (gdbarch, group);
+      gdb_printf (file, fmt, name, type);
     }
-  while (group != NULL);
 }
 
 static void
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index bc87a7325f0..959191c4180 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -53,14 +53,10 @@ extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
 extern const char *reggroup_name (const struct reggroup *reggroup);
 extern enum reggroup_type reggroup_type (const struct reggroup *reggroup);
 
-/* Iterators for the architecture's register groups.  Pass in NULL, returns
-   the first (for next), or last (for prev) group.  Pass in a group,
-   returns the next or previous group, or NULL when either the end or the
-   beginning of the group list is reached.  */
-extern struct reggroup *reggroup_next (struct gdbarch *gdbarch,
-				       const struct reggroup *last);
-extern struct reggroup *reggroup_prev (struct gdbarch *gdbarch,
-				       const struct reggroup *curr);
+/* Return the list of all register groups for GDBARCH.  */
+extern const std::vector<const reggroup *>
+	gdbarch_reggroups (struct gdbarch *gdbarch);
+
 /* Find a reggroup by name.  */
 extern const reggroup *reggroup_find (struct gdbarch *gdbarch,
 				      const char *name);
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index b968947fa1c..65ec8241370 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -523,10 +523,21 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
 static const reggroup *
 tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = reggroup_next (gdbarch, current_group);
-  if (group == NULL)
-    group = reggroup_next (gdbarch, NULL);
-  return group;
+  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
+
+  if (current_group != nullptr)
+    for (int i = 0; i < groups.size (); ++i)
+      {
+	if (groups[i] == current_group)
+	  {
+	    if (i + 1 < groups.size ())
+	      return groups[i + 1];
+	    else
+	      return groups.front ();
+	  }
+      }
+
+  return groups.front ();
 }
 
 /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
@@ -538,10 +549,27 @@ tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 static const reggroup *
 tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = reggroup_prev (gdbarch, current_group);
-  if (group == NULL)
-    group = reggroup_prev (gdbarch, NULL);
-  return group;
+  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
+
+  if (current_group != nullptr)
+    {
+      /* Iterate backwards.  */
+      for (auto iter = groups.rbegin ();
+	   iter != groups.rend ();
+	   ++iter)
+	{
+	  if (*iter == current_group)
+	    {
+	      ++iter;
+	      if (iter == groups.rend ())
+		return groups.back ();
+	      else
+		return *iter;
+	    }
+	}
+    }
+
+  return groups.back ();
 }
 
 /* Implement the 'tui reg' command.  Changes the register group displayed
@@ -555,7 +583,6 @@ tui_reg_command (const char *args, int from_tty)
 
   if (args != NULL)
     {
-      const reggroup *group, *match = NULL;
       size_t len = strlen (args);
 
       /* Make sure the curses mode is enabled.  */
@@ -569,6 +596,7 @@ tui_reg_command (const char *args, int from_tty)
       if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ())
 	tui_regs_layout ();
 
+      const reggroup *match = nullptr;
       const reggroup *current_group = TUI_DATA_WIN->get_current_group ();
       if (strncmp (args, "next", len) == 0)
 	match = tui_reg_next (current_group, gdbarch);
@@ -579,9 +607,7 @@ tui_reg_command (const char *args, int from_tty)
 	  /* This loop matches on the initial part of a register group
 	     name.  If this initial part in ARGS matches only one register
 	     group then the switch is made.  */
-	  for (group = reggroup_next (gdbarch, NULL);
-	       group != NULL;
-	       group = reggroup_next (gdbarch, group))
+	  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	    {
 	      if (strncmp (reggroup_name (group), args, len) == 0)
 		{
@@ -599,19 +625,16 @@ tui_reg_command (const char *args, int from_tty)
     }
   else
     {
-      const reggroup *group;
-      int first;
-
       gdb_printf (_("\"tui reg\" must be followed by the name of "
 		    "either a register group,\nor one of 'next' "
 		    "or 'prev'.  Known register groups are:\n"));
 
-      for (first = 1, group = reggroup_next (gdbarch, NULL);
-	   group != NULL;
-	   first = 0, group = reggroup_next (gdbarch, group))
+      bool first = true;
+      for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	{
 	  if (!first)
 	    gdb_printf (", ");
+	  first = false;
 	  gdb_printf ("%s", reggroup_name (group));
 	}
 
-- 
2.25.4


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

* [PATCH 12/16] gdb: more 'const' in gdb/reggroups.{c,h}
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (10 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 13/16] gdb: make the pre-defined register groups const Andrew Burgess
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert the reggroup_new and reggroup_gdbarch_new functions to return
a 'const regggroup *', and fix up all the fallout.

There should be no user visible changes after this commit.
---
 gdb/csky-tdep.c    | 10 +++++-----
 gdb/i386-tdep.c    |  4 ++--
 gdb/m32c-tdep.c    |  2 +-
 gdb/m68hc11-tdep.c |  4 ++--
 gdb/mep-tdep.c     |  6 +++---
 gdb/nds32-tdep.c   | 20 ++++++++++----------
 gdb/reggroups.c    |  8 ++++----
 gdb/reggroups.h    | 13 +++++++------
 gdb/riscv-tdep.c   |  2 +-
 gdb/xtensa-tdep.c  |  8 ++++----
 10 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index feb416a2406..3712409dbe8 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -61,11 +61,11 @@
 /* Control debugging information emitted in this file.  */
 static bool csky_debug = false;
 
-static struct reggroup *cr_reggroup;
-static struct reggroup *fr_reggroup;
-static struct reggroup *vr_reggroup;
-static struct reggroup *mmu_reggroup;
-static struct reggroup *prof_reggroup;
+static const reggroup *cr_reggroup;
+static const reggroup *fr_reggroup;
+static const reggroup *vr_reggroup;
+static const reggroup *mmu_reggroup;
+static const reggroup *prof_reggroup;
 
 /* Convenience function to print debug messages in prologue analysis.  */
 
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 0f9e3fde6ce..154d484c342 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4531,8 +4531,8 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 /* i386 register groups.  In addition to the normal groups, add "mmx"
    and "sse".  */
 
-static struct reggroup *i386_sse_reggroup;
-static struct reggroup *i386_mmx_reggroup;
+static const reggroup *i386_sse_reggroup;
+static const reggroup *i386_mmx_reggroup;
 
 static void
 i386_init_reggroups (void)
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 5a767c9ed52..55ef5a551f8 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -35,7 +35,7 @@
 \f
 /* The m32c tdep structure.  */
 
-static struct reggroup *m32c_dma_reggroup;
+static const reggroup *m32c_dma_reggroup;
 
 /* The type of a function that moves the value of REG between CACHE or
    BUF --- in either direction.  */
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 9d978d88018..5c1f20415c8 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1346,8 +1346,8 @@ m68hc11_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
 /* 68HC11/68HC12 register groups.
    Identify real hard registers and soft registers used by gcc.  */
 
-static struct reggroup *m68hc11_soft_reggroup;
-static struct reggroup *m68hc11_hard_reggroup;
+static const reggroup *m68hc11_soft_reggroup;
+static const reggroup *m68hc11_hard_reggroup;
 
 static void
 m68hc11_init_reggroups (void)
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index e449c66c9b5..27a1c5dd1ca 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1022,9 +1022,9 @@ mep_register_name (struct gdbarch *gdbarch, int regnr)
 
 
 /* Custom register groups for the MeP.  */
-static struct reggroup *mep_csr_reggroup; /* control/special */
-static struct reggroup *mep_cr_reggroup;  /* coprocessor general-purpose */
-static struct reggroup *mep_ccr_reggroup; /* coprocessor control */
+static const reggroup *mep_csr_reggroup; /* control/special */
+static const reggroup *mep_cr_reggroup;  /* coprocessor general-purpose */
+static const reggroup *mep_ccr_reggroup; /* coprocessor control */
 
 
 static int
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index a94a03ab2ab..06b129bdd31 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -314,16 +314,16 @@ nds32_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
 }
 \f
 /* NDS32 register groups.  */
-static struct reggroup *nds32_cr_reggroup;
-static struct reggroup *nds32_ir_reggroup;
-static struct reggroup *nds32_mr_reggroup;
-static struct reggroup *nds32_dr_reggroup;
-static struct reggroup *nds32_pfr_reggroup;
-static struct reggroup *nds32_hspr_reggroup;
-static struct reggroup *nds32_dmar_reggroup;
-static struct reggroup *nds32_racr_reggroup;
-static struct reggroup *nds32_idr_reggroup;
-static struct reggroup *nds32_secur_reggroup;
+static const reggroup *nds32_cr_reggroup;
+static const reggroup *nds32_ir_reggroup;
+static const reggroup *nds32_mr_reggroup;
+static const reggroup *nds32_dr_reggroup;
+static const reggroup *nds32_pfr_reggroup;
+static const reggroup *nds32_hspr_reggroup;
+static const reggroup *nds32_dmar_reggroup;
+static const reggroup *nds32_racr_reggroup;
+static const reggroup *nds32_idr_reggroup;
+static const reggroup *nds32_secur_reggroup;
 
 static void
 nds32_init_reggroups (void)
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 4607c4b674c..419e091c3c0 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -36,7 +36,7 @@ struct reggroup
   enum reggroup_type type;
 };
 
-struct reggroup *
+const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
   struct reggroup *group = XNEW (struct reggroup);
@@ -48,7 +48,7 @@ reggroup_new (const char *name, enum reggroup_type type)
 
 /* See reggroups.h.  */
 
-struct reggroup *
+const reggroup *
 reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 		      enum reggroup_type type)
 {
@@ -81,7 +81,7 @@ struct reggroups
 {
   /* Add GROUP to the list of register groups.  */
 
-  void add (struct reggroup *group)
+  void add (const reggroup *group)
   {
     gdb_assert (group != nullptr);
     gdb_assert (std::find (m_groups.begin(), m_groups.end(), group)
@@ -116,7 +116,7 @@ static struct gdbarch_data *reggroups_data;
 /* Add GROUP to the list of register groups for GDBARCH.  */
 
 void
-reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
+reggroup_add (struct gdbarch *gdbarch, const reggroup *group)
 {
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index 959191c4180..28bd00ff176 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -39,15 +39,16 @@ extern struct reggroup *const save_reggroup;
 extern struct reggroup *const restore_reggroup;
 
 /* Create a new local register group.  */
-extern struct reggroup *reggroup_new (const char *name,
-				      enum reggroup_type type);
+extern const reggroup *reggroup_new (const char *name,
+				     enum reggroup_type type);
+
 /* Create a new register group allocated onto the gdbarch obstack.  */
-extern struct reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
-					      const char *name,
-					      enum reggroup_type type);
+extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
+					     const char *name,
+					     enum reggroup_type type);
 
 /* Add a register group (with attribute values) to the pre-defined list.  */
-extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
+extern void reggroup_add (struct gdbarch *gdbarch, const reggroup *group);
 
 /* Register group attributes.  */
 extern const char *reggroup_name (const struct reggroup *reggroup);
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index ce62cfeb65c..f48260fbd93 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -129,7 +129,7 @@ struct riscv_unwind_cache
 
 /* RISC-V specific register group for CSRs.  */
 
-static reggroup *csr_reggroup = NULL;
+static const reggroup *csr_reggroup = nullptr;
 
 /* Callback function for user_reg_add.  */
 
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 6e478ee893d..89bdd7ffd28 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -712,10 +712,10 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
 		    _("invalid register number %d"), regnum);
 }
 
-static struct reggroup *xtensa_ar_reggroup;
-static struct reggroup *xtensa_user_reggroup;
-static struct reggroup *xtensa_vectra_reggroup;
-static struct reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];
+static const reggroup *xtensa_ar_reggroup;
+static const reggroup *xtensa_user_reggroup;
+static const reggroup *xtensa_vectra_reggroup;
+static const reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];
 
 static void
 xtensa_init_reggroups (void)
-- 
2.25.4


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

* [PATCH 13/16] gdb: make the pre-defined register groups const
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (11 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 12/16] gdb: more 'const' in gdb/reggroups.{c,h} Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 14/16] gdb: convert reggroup to a C++ class with constructor, etc Andrew Burgess
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert the 7 global, pre-defined, register groups const, and fix the
fall out (a minor tweak required in riscv-tdep.c).

There should be no user visible changes after this commit.
---
 gdb/reggroups.c  | 30 +++++++++++++++---------------
 gdb/reggroups.h  | 14 +++++++-------
 gdb/riscv-tdep.c |  2 +-
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 419e091c3c0..2888704f2d2 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -254,21 +254,21 @@ maintenance_print_reggroups (const char *args, int from_tty)
 }
 
 /* Pre-defined register groups.  */
-static struct reggroup general_group = { "general", USER_REGGROUP };
-static struct reggroup float_group = { "float", USER_REGGROUP };
-static struct reggroup system_group = { "system", USER_REGGROUP };
-static struct reggroup vector_group = { "vector", USER_REGGROUP };
-static struct reggroup all_group = { "all", USER_REGGROUP };
-static struct reggroup save_group = { "save", INTERNAL_REGGROUP };
-static struct reggroup restore_group = { "restore", INTERNAL_REGGROUP };
-
-struct reggroup *const general_reggroup = &general_group;
-struct reggroup *const float_reggroup = &float_group;
-struct reggroup *const system_reggroup = &system_group;
-struct reggroup *const vector_reggroup = &vector_group;
-struct reggroup *const all_reggroup = &all_group;
-struct reggroup *const save_reggroup = &save_group;
-struct reggroup *const restore_reggroup = &restore_group;
+static const reggroup general_group = { "general", USER_REGGROUP };
+static const reggroup float_group = { "float", USER_REGGROUP };
+static const reggroup system_group = { "system", USER_REGGROUP };
+static const reggroup vector_group = { "vector", USER_REGGROUP };
+static const reggroup all_group = { "all", USER_REGGROUP };
+static const reggroup save_group = { "save", INTERNAL_REGGROUP };
+static const reggroup restore_group = { "restore", INTERNAL_REGGROUP };
+
+const reggroup *const general_reggroup = &general_group;
+const reggroup *const float_reggroup = &float_group;
+const reggroup *const system_reggroup = &system_group;
+const reggroup *const vector_reggroup = &vector_group;
+const reggroup *const all_reggroup = &all_group;
+const reggroup *const save_reggroup = &save_group;
+const reggroup *const restore_reggroup = &restore_group;
 
 void _initialize_reggroup ();
 void
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index 28bd00ff176..ec1d79dfc30 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -28,15 +28,15 @@ struct reggroup;
 enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP };
 
 /* Pre-defined, user visible, register groups.  */
-extern struct reggroup *const general_reggroup;
-extern struct reggroup *const float_reggroup;
-extern struct reggroup *const system_reggroup;
-extern struct reggroup *const vector_reggroup;
-extern struct reggroup *const all_reggroup;
+extern const reggroup *const general_reggroup;
+extern const reggroup *const float_reggroup;
+extern const reggroup *const system_reggroup;
+extern const reggroup *const vector_reggroup;
+extern const reggroup *const all_reggroup;
 
 /* Pre-defined, internal, register groups.  */
-extern struct reggroup *const save_reggroup;
-extern struct reggroup *const restore_reggroup;
+extern const reggroup *const save_reggroup;
+extern const reggroup *const restore_reggroup;
 
 /* Create a new local register group.  */
 extern const reggroup *reggroup_new (const char *name,
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index f48260fbd93..04ecb8f9a17 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1369,7 +1369,7 @@ riscv_print_registers_info (struct gdbarch *gdbarch,
     }
   else
     {
-      struct reggroup *reggroup;
+      const struct reggroup *reggroup;
 
       if (print_all)
 	reggroup = all_reggroup;
-- 
2.25.4


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

* [PATCH 14/16] gdb: convert reggroup to a C++ class with constructor, etc
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (12 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 13/16] gdb: make the pre-defined register groups const Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 15/16] gdb: move struct reggroup into reggroups.h header Andrew Burgess
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert the 'struct reggroup' into a real class, with a constructor
and getter methods.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 48 ++++++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 2888704f2d2..dfae60773bb 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -32,18 +32,33 @@
 
 struct reggroup
 {
-  const char *name;
-  enum reggroup_type type;
+  /* Create a new register group object.  The NAME is not owned by the new
+     reggroup object, so must outlive the object.  */
+  reggroup (const char *name, enum reggroup_type type)
+    : m_name (name),
+      m_type (type)
+  { /* Nothing.  */ }
+
+  /* Return the name for this register group.  */
+  const char *name () const
+  { return m_name; }
+
+  /* Return the type of this register group.  */
+  enum reggroup_type type () const
+  { return m_type; }
+
+private:
+  /* The name of this register group.  */
+  const char *m_name;
+
+  /* The type of this register group.  */
+  enum reggroup_type m_type;
 };
 
 const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
-  struct reggroup *group = XNEW (struct reggroup);
-
-  group->name = name;
-  group->type = type;
-  return group;
+  return new reggroup (name, type);
 }
 
 /* See reggroups.h.  */
@@ -52,12 +67,9 @@ const reggroup *
 reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 		      enum reggroup_type type)
 {
-  struct reggroup *group = GDBARCH_OBSTACK_ZALLOC (gdbarch,
-						   struct reggroup);
-
-  group->name = gdbarch_obstack_strdup (gdbarch, name);
-  group->type = type;
-  return group;
+  name = gdbarch_obstack_strdup (gdbarch, name);
+  return obstack_new<struct reggroup> (gdbarch_obstack (gdbarch),
+				       name, type);
 }
 
 /* Register group attributes.  */
@@ -65,13 +77,13 @@ reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 const char *
 reggroup_name (const struct reggroup *group)
 {
-  return group->name;
+  return group->name ();
 }
 
 enum reggroup_type
 reggroup_type (const struct reggroup *group)
 {
-  return group->type;
+  return group->type ();
 }
 
 /* A container holding all the register groups for a particular
@@ -194,7 +206,7 @@ reggroup_find (struct gdbarch *gdbarch, const char *name)
 {
   for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
-      if (strcmp (name, reggroup_name (group)) == 0)
+      if (strcmp (name, group->name ()) == 0)
 	return group;
     }
   return NULL;
@@ -212,12 +224,12 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
   for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
       /* Group name.  */
-      const char *name = reggroup_name (group);
+      const char *name = group->name ();
 
       /* Group type.  */
       const char *type;
 
-      switch (reggroup_type (group))
+      switch (group->type ())
 	{
 	case USER_REGGROUP:
 	  type = "user";
-- 
2.25.4


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

* [PATCH 15/16] gdb: move struct reggroup into reggroups.h header
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (13 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 14/16] gdb: convert reggroup to a C++ class with constructor, etc Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-03-31 21:04 ` [PATCH 16/16] gdb: update comments throughout reggroups.{c,h} files Andrew Burgess
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Move 'struct reggroup' into the reggroups.h header.  Remove the
reggroup_name and reggroup_type accessor functions, and just use the
name/type member functions within 'struct reggroup', update all uses
of these removed functions.

There should be no user visible changes after this commit.
---
 gdb/completer.c           |  2 +-
 gdb/infcmd.c              |  2 +-
 gdb/nds32-tdep.c          |  2 +-
 gdb/python/py-registers.c |  3 +--
 gdb/regcache-dump.c       |  3 +--
 gdb/reggroups.c           | 41 ---------------------------------------
 gdb/reggroups.h           | 32 +++++++++++++++++++++++++-----
 gdb/target-descriptions.c |  2 +-
 gdb/tui/tui-regs.c        |  6 +++---
 9 files changed, 36 insertions(+), 57 deletions(-)

diff --git a/gdb/completer.c b/gdb/completer.c
index 8bb12f256af..019da9a0603 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1897,7 +1897,7 @@ reg_or_group_completer_1 (completion_tracker &tracker,
     {
       for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	{
-	  name = reggroup_name (group);
+	  name = group->name ();
 	  if (strncmp (word, name, len) == 0)
 	    tracker.add_completion (make_unique_xstrdup (name));
 	}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index a28250a456d..fbbf3cdbc6f 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2301,7 +2301,7 @@ registers_info (const char *addr_exp, int fpregs)
 	    /* Don't bother with a length check.  Should the user
 	       enter a short register group name, go with the first
 	       group that matches.  */
-	    if (strncmp (start, reggroup_name (g), end - start) == 0)
+	    if (strncmp (start, g->name (), end - start) == 0)
 	      {
 		group = g;
 		break;
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 06b129bdd31..e95ad7cc662 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -390,7 +390,7 @@ nds32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   /* The NDS32 reggroup contains registers whose name is prefixed
      by reggroup name.  */
   reg_name = gdbarch_register_name (gdbarch, regnum);
-  group_name = reggroup_name (reggroup);
+  group_name = reggroup->name ();
   return !strncmp (reg_name, group_name, strlen (group_name));
 }
 \f
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index 7a9d2e22403..725cab5d6fb 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -137,8 +137,7 @@ gdbpy_reggroup_to_string (PyObject *self)
   reggroup_object *group = (reggroup_object *) self;
   const reggroup *reggroup = group->reggroup;
 
-  const char *name = reggroup_name (reggroup);
-  return PyUnicode_FromString (name);
+  return PyUnicode_FromString (reggroup->name ());
 }
 
 /* Implement gdb.RegisterGroup.name (self) -> String.
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c
index 409a868be76..0c5da0e241d 100644
--- a/gdb/regcache-dump.c
+++ b/gdb/regcache-dump.c
@@ -196,8 +196,7 @@ class register_dump_groups : public register_dump
 	  {
 	    if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group))
 	      {
-		gdb_printf (file,
-			    "%s%s", sep, reggroup_name (group));
+		gdb_printf (file, "%s%s", sep, group->name ());
 		sep = ",";
 	      }
 	  }
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index dfae60773bb..96d4ae4d1f8 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -28,33 +28,6 @@
 #include "gdbcmd.h"		/* For maintenanceprintlist.  */
 #include "gdbsupport/gdb_obstack.h"
 
-/* Individual register groups.  */
-
-struct reggroup
-{
-  /* Create a new register group object.  The NAME is not owned by the new
-     reggroup object, so must outlive the object.  */
-  reggroup (const char *name, enum reggroup_type type)
-    : m_name (name),
-      m_type (type)
-  { /* Nothing.  */ }
-
-  /* Return the name for this register group.  */
-  const char *name () const
-  { return m_name; }
-
-  /* Return the type of this register group.  */
-  enum reggroup_type type () const
-  { return m_type; }
-
-private:
-  /* The name of this register group.  */
-  const char *m_name;
-
-  /* The type of this register group.  */
-  enum reggroup_type m_type;
-};
-
 const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
@@ -72,20 +45,6 @@ reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 				       name, type);
 }
 
-/* Register group attributes.  */
-
-const char *
-reggroup_name (const struct reggroup *group)
-{
-  return group->name ();
-}
-
-enum reggroup_type
-reggroup_type (const struct reggroup *group)
-{
-  return group->type ();
-}
-
 /* A container holding all the register groups for a particular
    architecture.  */
 
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index ec1d79dfc30..db5625a53bd 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -23,10 +23,36 @@
 #define REGGROUPS_H
 
 struct gdbarch;
-struct reggroup;
 
 enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP };
 
+/* Individual register group.  */
+
+struct reggroup
+{
+  /* Create a new register group object.  The NAME is not owned by the new
+     reggroup object, so must outlive the object.  */
+  reggroup (const char *name, enum reggroup_type type)
+    : m_name (name),
+      m_type (type)
+  { /* Nothing.  */ }
+
+  /* Return the name for this register group.  */
+  const char *name () const
+  { return m_name; }
+
+  /* Return the type of this register group.  */
+  enum reggroup_type type () const
+  { return m_type; }
+
+private:
+  /* The name of this register group.  */
+  const char *m_name;
+
+  /* The type of this register group.  */
+  enum reggroup_type m_type;
+};
+
 /* Pre-defined, user visible, register groups.  */
 extern const reggroup *const general_reggroup;
 extern const reggroup *const float_reggroup;
@@ -50,10 +76,6 @@ extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
 /* Add a register group (with attribute values) to the pre-defined list.  */
 extern void reggroup_add (struct gdbarch *gdbarch, const reggroup *group);
 
-/* Register group attributes.  */
-extern const char *reggroup_name (const struct reggroup *reggroup);
-extern enum reggroup_type reggroup_type (const struct reggroup *reggroup);
-
 /* Return the list of all register groups for GDBARCH.  */
 extern const std::vector<const reggroup *>
 	gdbarch_reggroups (struct gdbarch *gdbarch);
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 33277c3d02d..85954ac2939 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -1012,7 +1012,7 @@ tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
   struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
 
   if (reg != NULL && !reg->group.empty ()
-      && (reg->group == reggroup_name (reggroup)))
+      && (reg->group == reggroup->name ()))
 	return 1;
 
   if (reg != NULL
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 65ec8241370..2086ad4498c 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -216,7 +216,7 @@ tui_data_window::show_register_group (const reggroup *group,
   int regnum, pos;
 
   /* Make a new title showing which group we display.  */
-  title = string_printf ("Register group: %s", reggroup_name (group));
+  title = string_printf ("Register group: %s", group->name ());
 
   /* See how many registers must be displayed.  */
   nr_regs = 0;
@@ -609,7 +609,7 @@ tui_reg_command (const char *args, int from_tty)
 	     group then the switch is made.  */
 	  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	    {
-	      if (strncmp (reggroup_name (group), args, len) == 0)
+	      if (strncmp (group->name (), args, len) == 0)
 		{
 		  if (match != NULL)
 		    error (_("ambiguous register group name '%s'"), args);
@@ -635,7 +635,7 @@ tui_reg_command (const char *args, int from_tty)
 	  if (!first)
 	    gdb_printf (", ");
 	  first = false;
-	  gdb_printf ("%s", reggroup_name (group));
+	  gdb_printf ("%s", group->name ());
 	}
 
       gdb_printf ("\n");
-- 
2.25.4


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

* [PATCH 16/16] gdb: update comments throughout reggroups.{c,h} files
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (14 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 15/16] gdb: move struct reggroup into reggroups.h header Andrew Burgess
@ 2022-03-31 21:04 ` Andrew Burgess
  2022-04-06 14:28   ` Simon Marchi
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-03-31 21:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This commit updates the comments in the gdb/reggroups.{c,h} files.
Fill in some missing comments, correct a few comments that were not
clear, and where we had comments duplicated between .c and .h files,
update the .c to reference the .h.

No user visible changes after this commit.
---
 gdb/reggroups.c | 11 +++++++++--
 gdb/reggroups.h | 14 ++++++++++++--
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 96d4ae4d1f8..ef5e47e0986 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -28,6 +28,8 @@
 #include "gdbcmd.h"		/* For maintenanceprintlist.  */
 #include "gdbsupport/gdb_obstack.h"
 
+/* See reggroups.h.  */
+
 const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
@@ -82,9 +84,11 @@ struct reggroups
   std::vector<const struct reggroup *> m_groups;
 };
 
+/* Key used to lookup register group data from a gdbarch.  */
+
 static struct gdbarch_data *reggroups_data;
 
-/* Add GROUP to the list of register groups for GDBARCH.  */
+/* See reggroups.h.  */
 
 void
 reggroup_add (struct gdbarch *gdbarch, const reggroup *group)
@@ -128,7 +132,8 @@ gdbarch_reggroups (struct gdbarch *gdbarch)
   return groups->groups ();
 }
 
-/* Is REGNUM a member of REGGROUP?  */
+/* See reggroups.h.  */
+
 int
 default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 			     const struct reggroup *group)
@@ -207,6 +212,8 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
     }
 }
 
+/* Implement 'maintenance print reggroups' command.  */
+
 static void
 maintenance_print_reggroups (const char *args, int from_tty)
 {
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index db5625a53bd..8aa9ad8c76f 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -24,7 +24,17 @@
 
 struct gdbarch;
 
-enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP };
+/* The different register group types.  */
+enum reggroup_type {
+  /* Used for any register group that should be visible to the user.
+     Architecture specific register groups, as well as most of the default
+     groups will have this type.  */
+  USER_REGGROUP,
+
+  /* Used for a few groups that GDB uses while managing machine state.
+     These groups are mostly hidden from the user.  */
+  INTERNAL_REGGROUP
+};
 
 /* Individual register group.  */
 
@@ -73,7 +83,7 @@ extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
 					     const char *name,
 					     enum reggroup_type type);
 
-/* Add a register group (with attribute values) to the pre-defined list.  */
+/* Add a register group GROUP to the list of register groups for GDBARCH.  */
 extern void reggroup_add (struct gdbarch *gdbarch, const reggroup *group);
 
 /* Return the list of all register groups for GDBARCH.  */
-- 
2.25.4


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

* Re: [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup *
  2022-03-31 21:04 ` [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
@ 2022-04-04 22:35   ` Lancelot SIX
  2022-04-05  8:24     ` Andrew Burgess
  0 siblings, 1 reply; 48+ messages in thread
From: Lancelot SIX @ 2022-04-04 22:35 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

Hi,

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 4d0f3492410..c857f5ca7d1 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -8986,7 +8986,7 @@ arm_elf_osabi_sniffer (bfd *abfd)
>  
>  static int
>  arm_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
> -			  struct reggroup *group)
> +			 const struct reggroup *group)
                         ^
Small nit, looks like you dropped a space here.

Best,
Lancelot.

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

* Re: [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup *
  2022-04-04 22:35   ` Lancelot SIX
@ 2022-04-05  8:24     ` Andrew Burgess
  0 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-05  8:24 UTC (permalink / raw)
  To: Lancelot SIX; +Cc: gdb-patches

Lancelot SIX via Gdb-patches <gdb-patches@sourceware.org> writes:

> Hi,
>
>> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
>> index 4d0f3492410..c857f5ca7d1 100644
>> --- a/gdb/arm-tdep.c
>> +++ b/gdb/arm-tdep.c
>> @@ -8986,7 +8986,7 @@ arm_elf_osabi_sniffer (bfd *abfd)
>>  
>>  static int
>>  arm_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
>> -			  struct reggroup *group)
>> +			 const struct reggroup *group)
>                          ^
> Small nit, looks like you dropped a space here.

The original line had an extra space, the 'c' of const was aligned to
the 't' of struct above it, so I have removed the extra space here, but
that was intentional.

Always happy to check these things though.

Thanks,
Andrew


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

* Re: [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev
  2022-03-31 21:04 ` [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
@ 2022-04-05 23:11   ` Lancelot SIX
  2022-04-06 12:06     ` Andrew Burgess
  0 siblings, 1 reply; 48+ messages in thread
From: Lancelot SIX @ 2022-04-05 23:11 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

> diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
> index b968947fa1c..65ec8241370 100644
> --- a/gdb/tui/tui-regs.c
> +++ b/gdb/tui/tui-regs.c
> @@ -523,10 +523,21 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
>  static const reggroup *
>  tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
>  {
> -  const reggroup *group = reggroup_next (gdbarch, current_group);
> -  if (group == NULL)
> -    group = reggroup_next (gdbarch, NULL);
> -  return group;
> +  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
> +
> +  if (current_group != nullptr)
> +    for (int i = 0; i < groups.size (); ++i)
> +      {
> +	if (groups[i] == current_group)
> +	  {
> +	    if (i + 1 < groups.size ())
> +	      return groups[i + 1];
> +	    else
> +	      return groups.front ();
> +	  }
> +      }
> +
> +  return groups.front ();
>  }
>  
>  /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
> @@ -538,10 +549,27 @@ tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
>  static const reggroup *
>  tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
>  {
> -  const reggroup *group = reggroup_prev (gdbarch, current_group);
> -  if (group == NULL)
> -    group = reggroup_prev (gdbarch, NULL);
> -  return group;
> +  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
> +
> +  if (current_group != nullptr)
> +    {
> +      /* Iterate backwards.  */
> +      for (auto iter = groups.rbegin ();
> +	   iter != groups.rend ();
> +	   ++iter)
> +	{
> +	  if (*iter == current_group)
> +	    {
> +	      ++iter;
> +	      if (iter == groups.rend ())
> +		return groups.back ();
> +	      else
> +		return *iter;
> +	    }
> +	}
> +    }
> +
> +  return groups.back ();
>  }
>  

Hi,

It looks strange to have tui_reg_next implemented using iteration over
indexes while tui_reg_prev is implemented using iterators.  It looks to
me that both cases are similar enough to use a similar pattern.

Also, the for loop can probably be replaced by a call to std::find which
the overall thing more concise:

    static const reggroup *
    tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
    {
      const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
      auto it = std::find (groups.rbegin (), groups.rend (), current_group);
      it++;
      if (it >= groups.rend ())
        return groups.back ();
      return *it;
    }

and something similar for tui_reg_next, changing rbegin/rend with
begin/end and .back with .front.

WDYT?
Best,
Lancelot.


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

* [PATCHv2 00/16] Default register groups, and general related cleanup
  2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
                   ` (15 preceding siblings ...)
  2022-03-31 21:04 ` [PATCH 16/16] gdb: update comments throughout reggroups.{c,h} files Andrew Burgess
@ 2022-04-06 12:04 ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
                     ` (16 more replies)
  16 siblings, 17 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This work started with this thread:

  https://sourceware.org/pipermail/gdb-patches/2022-March/187071.html

In which it was discovered that the ppc targets don't add the default
register groups during gdbarch initialisation.

I've run into this problem before, and every time I wonder why the
default register groups aren't added by default in all cases.

So, looked at doing just that.

But the register group management code was feeling a bit crusty, so I
thought I'd clean it up.

Then I hit some bugs, which I figured I'd fix.

Anyway, patch #9 is what I set out to do.  Everything else is me
trying to improve the register group handling code.

Changes in v2:

  - Rebased onto current master, the changes I make to
    gdb.tui/regs.exp in one of the patches needed some small
    adjustments given recent tui changes,

  - Updated patch #11 based on Lancelot's feedback, this looks much
    better now.

---

Andrew Burgess (16):
  gdb: don't try to use readline before it's initialized
  gdb: add some const in gdb/reggroups.c
  gdb: make gdbarch_register_reggroup_p take a const reggroup *
  gdb: switch to using 'const reggroup *' in tui-regs.{c,h}
  gdb: use 'const reggroup *' in python/py-registers.c file
  gdb: have reggroup_find return a const
  gdb/tui: avoid theoretical bug with 'tui reg' command
  gdb/tui: fix 'tui reg next/prev' command when data window is hidden
  gdb: always add the default register groups
  gdb: convert reggroups to use a std::vector
  gdb: remove reggroup_next and reggroup_prev
  gdb: more 'const' in gdb/reggroups.{c,h}
  gdb: make the pre-defined register groups const
  gdb: convert reggroup to a C++ class with constructor, etc
  gdb: move struct reggroup into reggroups.h header
  gdb: update comments throughout reggroups.{c,h} files

 gdb/aarch64-tdep.c             |  19 +--
 gdb/alpha-tdep.c               |   2 +-
 gdb/amd64-linux-tdep.c         |   2 +-
 gdb/arc-tdep.c                 |  17 --
 gdb/arm-tdep.c                 |   2 +-
 gdb/completer.c                |   8 +-
 gdb/csky-tdep.c                |  14 +-
 gdb/gdbarch-components.py      |   2 +-
 gdb/gdbarch-gen.h              |   4 +-
 gdb/gdbarch.c                  |   2 +-
 gdb/i386-linux-tdep.c          |   2 +-
 gdb/i386-tdep.c                |  13 +-
 gdb/i386-tdep.h                |   2 +-
 gdb/ia64-tdep.c                |   2 +-
 gdb/infcmd.c                   |  14 +-
 gdb/lm32-tdep.c                |  13 +-
 gdb/m32c-tdep.c                |   9 +-
 gdb/m68hc11-tdep.c             |  13 +-
 gdb/mep-tdep.c                 |  12 +-
 gdb/mips-tdep.c                |   4 +-
 gdb/msp430-tdep.c              |   2 +-
 gdb/nds32-tdep.c               |  32 ++--
 gdb/or1k-tdep.c                |  14 +-
 gdb/python/py-registers.c      |  32 ++--
 gdb/regcache-dump.c            |   9 +-
 gdb/reggroups.c                | 298 ++++++++++++---------------------
 gdb/reggroups.h                |  94 +++++++----
 gdb/riscv-tdep.c               |  18 +-
 gdb/rl78-tdep.c                |   2 +-
 gdb/rs6000-tdep.c              |   2 +-
 gdb/s390-tdep.c                |   2 +-
 gdb/sh-tdep.c                  |   2 +-
 gdb/target-descriptions.c      |   6 +-
 gdb/target-descriptions.h      |   2 +-
 gdb/testsuite/gdb.tui/regs.exp |  26 +++
 gdb/tui/tui-regs.c             | 107 ++++++------
 gdb/tui/tui-regs.h             |   9 +-
 gdb/utils.c                    |  17 +-
 gdb/xtensa-tdep.c              |  25 +--
 39 files changed, 364 insertions(+), 491 deletions(-)

-- 
2.25.4


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

* [PATCHv2 01/16] gdb: don't try to use readline before it's initialized
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:57     ` Simon Marchi
  2022-04-06 12:04   ` [PATCHv2 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
                     ` (15 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

While working on a different patch, I triggered an assertion from the
initialize_current_architecture code, specifically from one of
the *_gdbarch_init functions in a *-tdep.c file.  This exposes a
couple of issues with GDB.

This is easy enough to reproduce by adding 'gdb_assert (false)' into a
suitable function.  For example, I added a line into i386_gdbarch_init
and can see the following issue.

I start GDB and immediately hit the assert, the output is as you'd
expect, except for the very last line:

  $ ./gdb/gdb --data-directory ./gdb/data-directory/
  ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  ----- Backtrace -----
  ... snip ...
  ---------------------
  ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  Quit this debugging session? (y or n) ../../src.dev-1/gdb/ser-event.c:212:16: runtime error: member access within null pointer of type 'struct serial'

Something goes wrong when we try to query the user.  Note, I
configured GDB with --enable-ubsan, I suspect that without this the
above "error" would actually just be a crash.

The backtrace from ser-event.c:212 looks like this:

  (gdb) bt 10
  #0  serial_event_clear (event=0x675c020) at ../../src/gdb/ser-event.c:212
  #1  0x0000000000769456 in invoke_async_signal_handlers () at ../../src/gdb/async-event.c:211
  #2  0x000000000295049b in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:194
  #3  0x0000000001f015f8 in gdb_readline_wrapper (
      prompt=0x67135c0 "../../src/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugg"...)
      at ../../src/gdb/top.c:1141
  #4  0x0000000002118b64 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) (
      ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ", defchar=0 '\000', args=0x7fffffffa6e0)
      at ../../src/gdb/utils.c:934
  #5  0x0000000002118f72 in query (ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ")
      at ../../src/gdb/utils.c:1026
  #6  0x00000000021170f6 in internal_vproblem(internal_problem *, const char *, int, const char *, typedef __va_list_tag __va_list_tag *) (problem=0x6107bc0 <internal_error_problem>, file=0x2b976c8 "../../src/gdb/i386-tdep.c",
      line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:417
  #7  0x00000000021175a0 in internal_verror (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455,
      fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:485
  #8  0x00000000029503b3 in internal_error (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455,
      fmt=0x2b96d7f "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:55
  #9  0x000000000122d5b6 in i386_gdbarch_init (info=..., arches=0x0) at ../../src/gdb/i386-tdep.c:8455
  (More stack frames follow...)

It turns out that the problem is that the async event handler
mechanism has been invoked, but this has not yet been initialized.

If we look at gdb_init (in gdb/top.c) we can indeed see the call to
gdb_init_signals is after the call to initialize_current_architecture.

If I reorder the calls, moving gdb_init_signals earlier, then the
initial error is resolved, however, things are still broken.  I now
see the same "Quit this debugging session? (y or n)" prompt, but when
I provide an answer and press return GDB immediately crashes.

So what's going on now?  The next problem is that the call_readline
field within the current_ui structure is not initialized, and this
callback is invoked to process the reply I entered.

The problem is that call_readline is setup as a result of calling
set_top_level_interpreter, which is called from captured_main_1.
Unfortunately, set_top_level_interpreter is called after gdb_init is
called.

I wondered how to solve this problem for a while, however, I don't
know if there's an easy "just reorder some lines" solution here.
Looking through captured_main_1 there seems to be a bunch of
dependencies between printing various things, parsing config files,
and setting up the interpreter.  I'm sure there is a solution hiding
in there somewhere.... I'm just not sure I want to spend any longer
looking for it.

So.

I propose a simpler solution, more of a hack/work-around.  In utils.c
we already have a function filtered_printing_initialized, this is
checked in a few places within internal_vproblem.  In some of these
cases the call gates whether or not GDB will query the user.

My proposal is to add a new readline_initialized function, which
checks if the current_ui has had readline initialized yet.  If this is
not the case then we should not attempt to query the user.

After this change GDB prints the error message, the backtrace, and
then aborts (including dumping core).  This actually seems pretty sane
as, if GDB has not yet made it through the initialization then it
doesn't make much sense to allow the user to say "no, I don't want to
quit the debug session" (I think).
---
 gdb/utils.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/gdb/utils.c b/gdb/utils.c
index 68bf3a67340..62a75d9e37f 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -306,6 +306,16 @@ struct internal_problem
   bool should_print_backtrace;
 };
 
+/* Return true if the readline callbacks have been initialized for UI.
+   This is always true once GDB is fully initialized, but during the early
+   startup phase this is initially false.  */
+
+static bool
+readline_initialized (struct ui *ui)
+{
+  return ui->call_readline != nullptr;
+}
+
 /* Report a problem, internal to GDB, to the user.  Once the problem
    has been reported, and assuming GDB didn't quit, the caller can
    either allow execution to resume or throw an error.  */
@@ -378,6 +388,7 @@ internal_vproblem (struct internal_problem *problem,
   if (problem->should_quit != internal_problem_ask
       || !confirm
       || !filtered_printing_initialized ()
+      || !readline_initialized (current_ui)
       || problem->should_print_backtrace)
     gdb_printf (gdb_stderr, "%s\n", reason.c_str ());
 
@@ -389,7 +400,8 @@ internal_vproblem (struct internal_problem *problem,
       /* Default (yes/batch case) is to quit GDB.  When in batch mode
 	 this lessens the likelihood of GDB going into an infinite
 	 loop.  */
-      if (!confirm || !filtered_printing_initialized ())
+      if (!confirm || !filtered_printing_initialized ()
+	  || !readline_initialized (current_ui))
 	quit_p = 1;
       else
 	quit_p = query (_("%s\nQuit this debugging session? "),
@@ -413,7 +425,8 @@ internal_vproblem (struct internal_problem *problem,
     {
       if (!can_dump_core_warn (LIMIT_MAX, reason.c_str ()))
 	dump_core_p = 0;
-      else if (!filtered_printing_initialized ())
+      else if (!filtered_printing_initialized ()
+	       || !readline_initialized (current_ui))
 	dump_core_p = 1;
       else
 	{
-- 
2.25.4


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

* [PATCHv2 02/16] gdb: add some const in gdb/reggroups.c
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:58     ` Simon Marchi
  2022-04-06 12:04   ` [PATCHv2 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
                     ` (14 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This commit makes the 'struct reggroup *' argument const for the
following functions:

  reggroup_next
  reggroup_prev
  reggroup_name
  reggroup_type

There are other places that could benefit from const in the
reggroup.{c,h} files, but these will be changing in further commits.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 8 ++++----
 gdb/reggroups.h | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index b6afa2f895c..169285b7475 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -63,13 +63,13 @@ reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 /* Register group attributes.  */
 
 const char *
-reggroup_name (struct reggroup *group)
+reggroup_name (const struct reggroup *group)
 {
   return group->name;
 }
 
 enum reggroup_type
-reggroup_type (struct reggroup *group)
+reggroup_type (const struct reggroup *group)
 {
   return group->type;
 }
@@ -130,7 +130,7 @@ static struct reggroups default_groups = { NULL, &default_groups.first };
 /* A register group iterator.  */
 
 struct reggroup *
-reggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
+reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
 {
   struct reggroups *groups;
   struct reggroup_el *el;
@@ -161,7 +161,7 @@ reggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
 /* See reggroups.h.  */
 
 struct reggroup *
-reggroup_prev (struct gdbarch *gdbarch, struct reggroup *curr)
+reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
 {
   struct reggroups *groups;
   struct reggroup_el *el;
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index f2e60c4f1da..ef99483f39f 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -50,17 +50,17 @@ extern struct reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
 extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
 
 /* Register group attributes.  */
-extern const char *reggroup_name (struct reggroup *reggroup);
-extern enum reggroup_type reggroup_type (struct reggroup *reggroup);
+extern const char *reggroup_name (const struct reggroup *reggroup);
+extern enum reggroup_type reggroup_type (const struct reggroup *reggroup);
 
 /* Iterators for the architecture's register groups.  Pass in NULL, returns
    the first (for next), or last (for prev) group.  Pass in a group,
    returns the next or previous group, or NULL when either the end or the
    beginning of the group list is reached.  */
 extern struct reggroup *reggroup_next (struct gdbarch *gdbarch,
-				       struct reggroup *last);
+				       const struct reggroup *last);
 extern struct reggroup *reggroup_prev (struct gdbarch *gdbarch,
-				       struct reggroup *curr);
+				       const struct reggroup *curr);
 /* Find a reggroup by name.  */
 extern reggroup *reggroup_find (struct gdbarch *gdbarch, const char *name);
 
-- 
2.25.4


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

* [PATCHv2 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup *
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h} Andrew Burgess
                     ` (13 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Change gdbarch_register_reggroup_p to take a 'const struct reggroup *'
argument.  This requires a change to the gdb/gdbarch-components.py
script, regeneration of gdbarch.{c,h}, and then updates to all the
architectures that implement this method.

There should be no user visible changes after this commit.
---
 gdb/aarch64-tdep.c        | 2 +-
 gdb/alpha-tdep.c          | 2 +-
 gdb/amd64-linux-tdep.c    | 2 +-
 gdb/arm-tdep.c            | 2 +-
 gdb/csky-tdep.c           | 2 +-
 gdb/gdbarch-components.py | 2 +-
 gdb/gdbarch-gen.h         | 4 ++--
 gdb/gdbarch.c             | 2 +-
 gdb/i386-linux-tdep.c     | 2 +-
 gdb/i386-tdep.c           | 2 +-
 gdb/i386-tdep.h           | 2 +-
 gdb/ia64-tdep.c           | 2 +-
 gdb/lm32-tdep.c           | 2 +-
 gdb/m32c-tdep.c           | 2 +-
 gdb/m68hc11-tdep.c        | 2 +-
 gdb/mep-tdep.c            | 2 +-
 gdb/mips-tdep.c           | 4 ++--
 gdb/msp430-tdep.c         | 2 +-
 gdb/nds32-tdep.c          | 2 +-
 gdb/reggroups.c           | 2 +-
 gdb/reggroups.h           | 2 +-
 gdb/riscv-tdep.c          | 2 +-
 gdb/rl78-tdep.c           | 2 +-
 gdb/rs6000-tdep.c         | 2 +-
 gdb/s390-tdep.c           | 2 +-
 gdb/sh-tdep.c             | 2 +-
 gdb/target-descriptions.c | 4 ++--
 gdb/target-descriptions.h | 2 +-
 gdb/xtensa-tdep.c         | 4 ++--
 29 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index fb1434c97a3..cdeeece83c0 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -2695,7 +2695,7 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 
 static int
 aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				    struct reggroup *group)
+				    const struct reggroup *group)
 {
   aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 7f3af216675..f04bad6bed8 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -139,7 +139,7 @@ alpha_register_type (struct gdbarch *gdbarch, int regno)
 
 static int
 alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			   struct reggroup *group)
+			   const struct reggroup *group)
 {
   /* Filter out any registers eliminated, but whose regnum is 
      reserved for backward compatibility, e.g. the vfp.  */
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 88a24c176e8..0e5194fbeee 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -279,7 +279,7 @@ static int amd64_linux_sc_reg_offset[] =
 
 static int
 amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				 struct reggroup *group)
+				 const struct reggroup *group)
 { 
   if (regnum == AMD64_LINUX_ORIG_RAX_REGNUM
       || regnum == AMD64_FSBASE_REGNUM
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 4d0f3492410..c857f5ca7d1 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8986,7 +8986,7 @@ arm_elf_osabi_sniffer (bfd *abfd)
 
 static int
 arm_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			 const struct reggroup *group)
 {
   /* FPS register's type is INT, but belongs to float_reggroup.  Beside
      this, FPS register belongs to save_regroup, restore_reggroup, and
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index 09e8fc57246..f1376730c87 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -2063,7 +2063,7 @@ csky_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 csky_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *reggroup)
+			  const struct reggroup *reggroup)
 {
   int raw_p;
 
diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch-components.py
index c820ddae764..e8f20c83ff0 100644
--- a/gdb/gdbarch-components.py
+++ b/gdb/gdbarch-components.py
@@ -1460,7 +1460,7 @@ Is a register in a group
 """,
     type="int",
     name="register_reggroup_p",
-    params=[("int", "regnum"), ("struct reggroup *", "reggroup")],
+    params=[("int", "regnum"), ("const struct reggroup *", "reggroup")],
     predefault="default_register_reggroup_p",
     invalid=False,
 )
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 7a8721328ab..882b9057b1a 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -833,8 +833,8 @@ extern void set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarc
 
 /* Is a register in a group */
 
-typedef int (gdbarch_register_reggroup_p_ftype) (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup);
-extern int gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup);
+typedef int (gdbarch_register_reggroup_p_ftype) (struct gdbarch *gdbarch, int regnum, const struct reggroup *reggroup);
+extern int gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, const struct reggroup *reggroup);
 extern void set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, gdbarch_register_reggroup_p_ftype *register_reggroup_p);
 
 /* Fetch the pointer to the ith function argument. */
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index ff404f47727..a588bdef61a 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -3632,7 +3632,7 @@ set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch,
 }
 
 int
-gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup)
+gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, const struct reggroup *reggroup)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->register_reggroup_p != NULL);
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 1f1aaa7d60a..5d7f54194af 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -54,7 +54,7 @@
    group.  Put the LINUX_ORIG_EAX register in the system group.  */
 static int
 i386_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				struct reggroup *group)
+				const struct reggroup *group)
 {
   if (regnum == I386_LINUX_ORIG_EAX_REGNUM)
     return (group == system_reggroup
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 870cacaf0d3..400ccd6bebf 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4557,7 +4557,7 @@ i386_add_reggroups (struct gdbarch *gdbarch)
 
 int
 i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   const i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int fp_regnum_p, mmx_regnum_p, xmm_regnum_p, mxcsr_regnum_p,
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index eb58dd68e73..a8067cf6b6c 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -418,7 +418,7 @@ extern int i386_sigtramp_p (struct frame_info *this_frame);
 
 /* Return non-zero if REGNUM is a member of the specified group.  */
 extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				     struct reggroup *group);
+				     const struct reggroup *group);
 
 /* Supply register REGNUM from the general-purpose register set REGSET
    to register cache REGCACHE.  If REGNUM is -1, do this for all
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index c2d1a475bab..69a4b4db4fd 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -322,7 +322,7 @@ ia64_ext_type (struct gdbarch *gdbarch)
 
 static int
 ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   int vector_p;
   int float_p;
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index cb516e846f4..f3f1f87d6bb 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -73,7 +73,7 @@ lm32_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 lm32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   if (group == general_reggroup)
     return ((regnum >= SIM_LM32_R0_REGNUM) && (regnum <= SIM_LM32_RA_REGNUM))
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 5e4844bda0a..94087302892 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -252,7 +252,7 @@ m32c_debug_info_reg_to_regnum (struct gdbarch *gdbarch, int reg_nr)
 
 static int
 m32c_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   struct m32c_reg *reg = &tdep->regs[regnum];
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 070eeb8b3da..f1133fe6780 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1372,7 +1372,7 @@ m68hc11_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 m68hc11_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			     struct reggroup *group)
+			     const struct reggroup *group)
 {
   /* We must save the real hard register as well as gcc
      soft registers including the frame pointer.  */
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 696d9c63bce..50bea7cb49f 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1029,7 +1029,7 @@ static struct reggroup *mep_ccr_reggroup; /* coprocessor control */
 
 static int
 mep_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			 struct reggroup *group)
+			 const struct reggroup *group)
 {
   /* Filter reserved or unused register numbers.  */
   {
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 93945891407..97923e08f5d 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -698,7 +698,7 @@ mips_register_name (struct gdbarch *gdbarch, int regno)
 
 static int
 mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *reggroup)
+			  const struct reggroup *reggroup)
 {
   int vector_p;
   int float_p;
@@ -738,7 +738,7 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 
 static int
 mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				struct reggroup *reggroup)
+				const struct reggroup *reggroup)
 {
   int rawnum = regnum % gdbarch_num_regs (gdbarch);
   int pseudo = regnum / gdbarch_num_regs (gdbarch);
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 86277e0b186..28268a95139 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -203,7 +203,7 @@ msp430_register_name (struct gdbarch *gdbarch, int regnr)
 
 static int
 msp430_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			    struct reggroup *group)
+			    const struct reggroup *group)
 {
   if (group == all_reggroup)
     return 1;
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index f8548561853..425d7d90d64 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -368,7 +368,7 @@ nds32_add_reggroups (struct gdbarch *gdbarch)
 
 static int
 nds32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			   struct reggroup *reggroup)
+			   const struct reggroup *reggroup)
 {
   const char *reg_name;
   const char *group_name;
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 169285b7475..d5a263f8109 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -190,7 +190,7 @@ reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
 /* Is REGNUM a member of REGGROUP?  */
 int
 default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			     struct reggroup *group)
+			     const struct reggroup *group)
 {
   int vector_p;
   int float_p;
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index ef99483f39f..df8e871e365 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -66,6 +66,6 @@ extern reggroup *reggroup_find (struct gdbarch *gdbarch, const char *name);
 
 /* Is REGNUM a member of REGGROUP?  */
 extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-					struct reggroup *reggroup);
+					const struct reggroup *reggroup);
 
 #endif
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 2752937f601..8713652b099 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1271,7 +1271,7 @@ riscv_is_unknown_csr (struct gdbarch *gdbarch, int regnum)
 
 static int
 riscv_register_reggroup_p (struct gdbarch  *gdbarch, int regnum,
-			   struct reggroup *reggroup)
+			   const struct reggroup *reggroup)
 {
   /* Used by 'info registers' and 'info registers <groupname>'.  */
 
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index df04939acb1..6ea0473081d 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -586,7 +586,7 @@ rl78_g10_register_name (struct gdbarch *gdbarch, int regnr)
 
 static int
 rl78_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			  struct reggroup *group)
+			  const struct reggroup *group)
 {
   if (group == all_reggroup)
     return 1;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 5bf43644a8e..44828bcff6d 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2642,7 +2642,7 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 
 static int
 rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				   struct reggroup *group)
+				   const struct reggroup *group)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index e54348be04a..14b03a167d7 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -1440,7 +1440,7 @@ s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static int
 s390_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				 struct reggroup *group)
+				 const struct reggroup *group)
 {
   s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index c12d40b604c..2341a9beef6 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1490,7 +1490,7 @@ sh_default_register_type (struct gdbarch *gdbarch, int reg_nr)
    TODO: sh2a and dsp registers.  */
 static int
 sh_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			struct reggroup *reggroup)
+			const struct reggroup *reggroup)
 {
   if (gdbarch_register_name (gdbarch, regnum) == NULL
       || *gdbarch_register_name (gdbarch, regnum) == '\0')
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index ae3b8211167..33277c3d02d 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -1007,7 +1007,7 @@ tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
 
 int
 tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
-			      struct reggroup *reggroup)
+			      const struct reggroup *reggroup)
 {
   struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
 
@@ -1028,7 +1028,7 @@ tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
 
 static int
 tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regno,
-			   struct reggroup *reggroup)
+			   const struct reggroup *reggroup)
 {
   int num_regs = gdbarch_num_regs (gdbarch);
   int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);
diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h
index 9d959977062..3b90dedcd80 100644
--- a/gdb/target-descriptions.h
+++ b/gdb/target-descriptions.h
@@ -229,7 +229,7 @@ struct type *tdesc_find_type (struct gdbarch *gdbarch, const char *id);
    specify a group.  */
 
 int tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
-				  struct reggroup *reggroup);
+				  const struct reggroup *reggroup);
 
 /* Methods for constructing a target description.  */
 
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 203d2e883df..62be13643b2 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -755,7 +755,7 @@ xtensa_add_reggroups (struct gdbarch *gdbarch)
 }
 
 static int 
-xtensa_coprocessor_register_group (struct reggroup *group)
+xtensa_coprocessor_register_group (const struct reggroup *group)
 {
   int i;
 
@@ -776,7 +776,7 @@ xtensa_coprocessor_register_group (struct reggroup *group)
 static int
 xtensa_register_reggroup_p (struct gdbarch *gdbarch,
 			    int regnum,
-			    struct reggroup *group)
+			    const struct reggroup *group)
 {
   xtensa_gdbarch_tdep *tdep = (xtensa_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   xtensa_register_t* reg = &tdep->regmap[regnum];
-- 
2.25.4


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

* [PATCHv2 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h}
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (2 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 05/16] gdb: use 'const reggroup *' in python/py-registers.c file Andrew Burgess
                     ` (12 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Make uses of 'reggroup *' const throughout tui-regs.{c,h}.

There should be no user visible changes after this commit.
---
 gdb/tui/tui-regs.c | 22 +++++++++++-----------
 gdb/tui/tui-regs.h |  9 +++++----
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 190985321eb..5c6189a59b1 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -177,7 +177,7 @@ tui_data_window::first_reg_element_no_inline (int line_no) const
 /* Show the registers of the given group in the data window
    and refresh the window.  */
 void
-tui_data_window::show_registers (struct reggroup *group)
+tui_data_window::show_registers (const reggroup *group)
 {
   if (group == 0)
     group = general_reggroup;
@@ -207,7 +207,7 @@ tui_data_window::show_registers (struct reggroup *group)
    refresh_values_only is true.  */
 
 void
-tui_data_window::show_register_group (struct reggroup *group,
+tui_data_window::show_register_group (const reggroup *group,
 				      struct frame_info *frame, 
 				      bool refresh_values_only)
 {
@@ -518,10 +518,10 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
    around behaviour.  Returns the next register group, or NULL if the
    register window is not currently being displayed.  */
 
-static struct reggroup *
-tui_reg_next (struct reggroup *current_group, struct gdbarch *gdbarch)
+static const reggroup *
+tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  struct reggroup *group = NULL;
+  const reggroup *group = NULL;
 
   if (current_group != NULL)
     {
@@ -536,10 +536,10 @@ tui_reg_next (struct reggroup *current_group, struct gdbarch *gdbarch)
    around behaviour.  Returns the previous register group, or NULL if the
    register window is not currently being displayed.  */
 
-static struct reggroup *
-tui_reg_prev (struct reggroup *current_group, struct gdbarch *gdbarch)
+static const reggroup *
+tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  struct reggroup *group = NULL;
+  const reggroup *group = NULL;
 
   if (current_group != NULL)
     {
@@ -561,7 +561,7 @@ tui_reg_command (const char *args, int from_tty)
 
   if (args != NULL)
     {
-      struct reggroup *group, *match = NULL;
+      const reggroup *group, *match = NULL;
       size_t len = strlen (args);
 
       /* Make sure the curses mode is enabled.  */
@@ -575,7 +575,7 @@ tui_reg_command (const char *args, int from_tty)
       if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ())
 	tui_regs_layout ();
 
-      struct reggroup *current_group = TUI_DATA_WIN->get_current_group ();
+      const reggroup *current_group = TUI_DATA_WIN->get_current_group ();
       if (strncmp (args, "next", len) == 0)
 	match = tui_reg_next (current_group, gdbarch);
       else if (strncmp (args, "prev", len) == 0)
@@ -603,7 +603,7 @@ tui_reg_command (const char *args, int from_tty)
     }
   else
     {
-      struct reggroup *group;
+      const reggroup *group;
       int first;
 
       gdb_printf (_("\"tui reg\" must be followed by the name of "
diff --git a/gdb/tui/tui-regs.h b/gdb/tui/tui-regs.h
index 9192a73b177..5289d3a892d 100644
--- a/gdb/tui/tui-regs.h
+++ b/gdb/tui/tui-regs.h
@@ -23,6 +23,7 @@
 #define TUI_TUI_REGS_H
 
 #include "tui/tui-data.h"
+#include "reggroups.h"
 
 /* A data item window.  */
 
@@ -60,9 +61,9 @@ struct tui_data_window : public tui_win_info
 
   void check_register_values (struct frame_info *frame);
 
-  void show_registers (struct reggroup *group);
+  void show_registers (const reggroup *group);
 
-  struct reggroup *get_current_group () const
+  const reggroup *get_current_group () const
   {
     return m_current_group;
   }
@@ -99,7 +100,7 @@ struct tui_data_window : public tui_win_info
      display off the end of the register display.  */
   void display_reg_element_at_line (int start_element_no, int start_line_no);
 
-  void show_register_group (struct reggroup *group,
+  void show_register_group (const reggroup *group,
 			    struct frame_info *frame,
 			    bool refresh_values_only);
 
@@ -125,7 +126,7 @@ struct tui_data_window : public tui_win_info
   /* Windows that are used to display registers.  */
   std::vector<tui_data_item_window> m_regs_content;
   int m_regs_column_count = 0;
-  struct reggroup *m_current_group = nullptr;
+  const reggroup *m_current_group = nullptr;
 
   /* Width of each register's display area.  */
   int m_item_width = 0;
-- 
2.25.4


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

* [PATCHv2 05/16] gdb: use 'const reggroup *' in python/py-registers.c file
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (3 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h} Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 06/16] gdb: have reggroup_find return a const Andrew Burgess
                     ` (11 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert uses of 'struct reggroup *' in python/py-registers.c to be
'const'.

There should be no user visible changes after this commit.
---
 gdb/python/py-registers.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index eab88a30b3b..58d196c37b4 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -35,7 +35,7 @@ struct register_descriptor_iterator_object {
 
   /* The register group that the user is iterating over.  This will never
      be NULL.  */
-  struct reggroup *reggroup;
+  const struct reggroup *reggroup;
 
   /* The next register number to lookup.  Starts at 0 and counts up.  */
   int regnum;
@@ -66,7 +66,7 @@ struct reggroup_iterator_object {
   PyObject_HEAD
 
   /* The last register group returned.  Initially this will be NULL.  */
-  struct reggroup *reggroup;
+  const struct reggroup *reggroup;
 
   /* Pointer back to the architecture we're finding registers for.  */
   struct gdbarch *gdbarch;
@@ -80,7 +80,7 @@ struct reggroup_object {
   PyObject_HEAD
 
   /* The register group being described.  */
-  struct reggroup *reggroup;
+  const struct reggroup *reggroup;
 };
 
 extern PyTypeObject reggroup_object_type
@@ -101,12 +101,12 @@ gdbpy_register_object_data_init (struct gdbarch *gdbarch)
    returned for the same REGGROUP pointer.  */
 
 static gdbpy_ref<>
-gdbpy_get_reggroup (struct reggroup *reggroup)
+gdbpy_get_reggroup (const reggroup *reggroup)
 {
   /* Map from GDB's internal reggroup objects to the Python representation.
      GDB's reggroups are global, and are never deleted, so using a map like
      this is safe.  */
-  static std::unordered_map<struct reggroup *,gdbpy_ref<>>
+  static std::unordered_map<const struct reggroup *,gdbpy_ref<>>
     gdbpy_reggroup_object_map;
 
   /* If there is not already a suitable Python object in the map then
@@ -135,7 +135,7 @@ static PyObject *
 gdbpy_reggroup_to_string (PyObject *self)
 {
   reggroup_object *group = (reggroup_object *) self;
-  struct reggroup *reggroup = group->reggroup;
+  const reggroup *reggroup = group->reggroup;
 
   const char *name = reggroup_name (reggroup);
   return PyUnicode_FromString (name);
@@ -227,7 +227,7 @@ gdbpy_reggroup_iter_next (PyObject *self)
     = (reggroup_iterator_object *) self;
   struct gdbarch *gdbarch = iter_obj->gdbarch;
 
-  struct reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
+  const reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
   if (next_group == NULL)
     {
       PyErr_SetString (PyExc_StopIteration, _("No more groups"));
@@ -269,7 +269,7 @@ PyObject *
 gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
 					const char *group_name)
 {
-  struct reggroup *grp = NULL;
+  const reggroup *grp = NULL;
 
   /* Lookup the requested register group, or find the default.  */
   if (group_name == NULL || *group_name == '\0')
-- 
2.25.4


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

* [PATCHv2 06/16] gdb: have reggroup_find return a const
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (4 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 05/16] gdb: use 'const reggroup *' in python/py-registers.c file Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
                     ` (10 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Update reggroup_find to return a const reggroup *.

There are other function in gdb/reggroup.{c,h} files that could
benefit from returning const, these will be updated in later commits.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 2 +-
 gdb/reggroups.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index d5a263f8109..6c38ca743f4 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -219,7 +219,7 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 
 /* See reggroups.h.  */
 
-reggroup *
+const reggroup *
 reggroup_find (struct gdbarch *gdbarch, const char *name)
 {
   struct reggroup *group;
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index df8e871e365..bc87a7325f0 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -62,7 +62,8 @@ extern struct reggroup *reggroup_next (struct gdbarch *gdbarch,
 extern struct reggroup *reggroup_prev (struct gdbarch *gdbarch,
 				       const struct reggroup *curr);
 /* Find a reggroup by name.  */
-extern reggroup *reggroup_find (struct gdbarch *gdbarch, const char *name);
+extern const reggroup *reggroup_find (struct gdbarch *gdbarch,
+				      const char *name);
 
 /* Is REGNUM a member of REGGROUP?  */
 extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-- 
2.25.4


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

* [PATCHv2 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (5 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 06/16] gdb: have reggroup_find return a const Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 13:02     ` Simon Marchi
  2022-04-06 12:04   ` [PATCHv2 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
                     ` (9 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

While looking at the 'tui reg' command as part of another patch, I
spotted a theoretical bug.

The 'tui reg' command takes the name of a register group, but also
handles partial register group matches, though the partial match has to
be unique.  The current command logic goes:

With the code as currently written, if a target description named a
register group either 'prev' or 'next' then GDB would see this as an
ambiguous register name, and refuse to switch groups.

Naming a register group 'prev' or 'next' seems pretty unlikely, but,
by adding a single else block we can prevent this problem.

Now, if there's a 'prev' or 'next' register group, the user will not
be able to select the group directly, the 'prev' and 'next' names will
always iterate through the available groups instead.  But at least the
user could select their groups by iteration, rather than direct
selection.
---
 gdb/tui/tui-regs.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 5c6189a59b1..75ffa9babbf 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -580,19 +580,21 @@ tui_reg_command (const char *args, int from_tty)
 	match = tui_reg_next (current_group, gdbarch);
       else if (strncmp (args, "prev", len) == 0)
 	match = tui_reg_prev (current_group, gdbarch);
-
-      /* This loop matches on the initial part of a register group
-	 name.  If this initial part in ARGS matches only one register
-	 group then the switch is made.  */
-      for (group = reggroup_next (gdbarch, NULL);
-	   group != NULL;
-	   group = reggroup_next (gdbarch, group))
+      else
 	{
-	  if (strncmp (reggroup_name (group), args, len) == 0)
+	  /* This loop matches on the initial part of a register group
+	     name.  If this initial part in ARGS matches only one register
+	     group then the switch is made.  */
+	  for (group = reggroup_next (gdbarch, NULL);
+	       group != NULL;
+	       group = reggroup_next (gdbarch, group))
 	    {
-	      if (match != NULL)
-		error (_("ambiguous register group name '%s'"), args);
-	      match = group;
+	      if (strncmp (reggroup_name (group), args, len) == 0)
+		{
+		  if (match != NULL)
+		    error (_("ambiguous register group name '%s'"), args);
+		  match = group;
+		}
 	    }
 	}
 
-- 
2.25.4


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

* [PATCHv2 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (6 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 13:13     ` Simon Marchi
  2022-04-06 12:04   ` [PATCHv2 09/16] gdb: always add the default register groups Andrew Burgess
                     ` (8 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Start GDB like:

  $ gdb -q executable
  (gdb) start
  (gdb) layout src
  ... tui windows are now displayed ...
  (gdb) tui reg next

At this point the data (register) window should be displayed, but will
contain the message 'Register Values Unavailable', and at the console
you'll see the message "unknown register group 'next'".

The same happens with 'tui reg prev' (but the error message is
slightly different).

At this point you can continue to use 'tui reg next' and/or 'tui reg
prev' and you'll keep getting the error message.

The problem is that when the data (register) window is first
displayed, it's current register group is nullptr.  As a consequence
tui_reg_next and tui_reg_prev (tui/tui-regs.c) will always just return
nullptr, which triggers an error in tui_reg_command.

In this commit I change tui_reg_next and tui_reg_prev so that they
instead return the first and last register group respectively if the
current register group is nullptr.

So, after this, using 'tui reg next' will (in the above case) show the
first register group, while 'tui reg prev' will display the last
register group.
---
 gdb/testsuite/gdb.tui/regs.exp | 26 ++++++++++++++++++++++++++
 gdb/tui/tui-regs.c             | 34 ++++++++++++++--------------------
 2 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/gdb/testsuite/gdb.tui/regs.exp b/gdb/testsuite/gdb.tui/regs.exp
index 2f3482f5d38..4f34ced990c 100644
--- a/gdb/testsuite/gdb.tui/regs.exp
+++ b/gdb/testsuite/gdb.tui/regs.exp
@@ -44,3 +44,29 @@ Term::check_box "source box in regs layout" 0 7 80 8
 set text [Term::get_line 1]
 # Just check for any register window content at all.
 Term::check_contents "any register contents" "\\|.*\[^ \].*\\|"
+
+
+# Check that we can successfully cause the register window to appear
+# using the 'tui reg next' and 'tui reg prev' commands.
+foreach_with_prefix cmd { next prev } {
+    Term::clean_restart 24 80 $testfile
+
+    if {![runto_main]} {
+	perror "test suppressed"
+	return
+    }
+
+    if {![Term::enter_tui]} {
+	unsupported "TUI not supported"
+	return
+    }
+
+    Term::command "tui reg ${cmd}"
+    Term::check_box "register box" 0 0 80 8
+    Term::check_box "source box in regs layout" 0 7 80 8
+    Term::check_region_contents "check register group title" \
+	0 0 80 1 "Register group: "
+    set contents [Term::get_region 0 15 80 8 "\r\n"]
+    gdb_assert {![regexp -- "unknown register group '${cmd}'" $contents]} \
+	"check register group is known"
+}
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 75ffa9babbf..b968947fa1c 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -515,38 +515,32 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
 }
 
 /* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
-   around behaviour.  Returns the next register group, or NULL if the
-   register window is not currently being displayed.  */
+   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
+   nullptr (e.g. if the tui register window has only just been displayed
+   and has no current group selected), then the first register group will
+   be returned.  */
 
 static const reggroup *
 tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = NULL;
-
-  if (current_group != NULL)
-    {
-      group = reggroup_next (gdbarch, current_group);
-      if (group == NULL)
-	group = reggroup_next (gdbarch, NULL);
-    }
+  const reggroup *group = reggroup_next (gdbarch, current_group);
+  if (group == NULL)
+    group = reggroup_next (gdbarch, NULL);
   return group;
 }
 
 /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
-   around behaviour.  Returns the previous register group, or NULL if the
-   register window is not currently being displayed.  */
+   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
+   nullptr (e.g. if the tui register window has only just been displayed
+   and has no current group selected), then the last register group will
+   be returned.  */
 
 static const reggroup *
 tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = NULL;
-
-  if (current_group != NULL)
-    {
-      group = reggroup_prev (gdbarch, current_group);
-      if (group == NULL)
-	group = reggroup_prev (gdbarch, NULL);
-    }
+  const reggroup *group = reggroup_prev (gdbarch, current_group);
+  if (group == NULL)
+    group = reggroup_prev (gdbarch, NULL);
   return group;
 }
 
-- 
2.25.4


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

* [PATCHv2 09/16] gdb: always add the default register groups
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (7 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 13:22     ` Simon Marchi
  2022-04-06 12:04   ` [PATCHv2 10/16] gdb: convert reggroups to use a std::vector Andrew Burgess
                     ` (7 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

There's a set of 7 default register groups.  If we don't add any
gdbarch specific register groups during gdbarch initialisation, then
when we iterate over the register groups using reggroup_next and
reggroup_prev we will make use of these 7 default groups.  See the use
of default_groups in gdb/reggroups.c for details on this.

However, if the gdbarch adds its own groups during gdbarch
initialisation, then these groups will be used in preference to the
default groups.

A problem arises though if the particular architecture makes use of
the target description mechanism.  If the default target
description(s) (i.e. those internal to GDB that are used when the user
doesn't provide their own) don't mention any additional register
groups then the default register groups will be used.

But if the target description does mention additional groups then the
default groups are not used, and instead, the groups from the target
description are used.

The problem with this is that what usually happens is that the target
description will mention additional groups, e.g. groups for special
registers.  Most architectures that use target descriptions work
around this by adding all (or most) of the default register groups in
all cases.  See i386_add_reggroups, aarch64_add_reggroups,
riscv_add_reggroups, xtensa_add_reggroups, and others.

In this patch, my suggestion is that we should just add the default
register groups for every architecture, always.  This change is in
gdb/reggroups.c.

All the remaining changes are me updating the various architectures to
not add the default groups themselves.

So, where will this change be visible to the user?  I think the
following commands will possibly change:

* info registers / info all-registers:

  The user can provide a register group to these commands.  For example,
  on csky, we previously never added the 'vector' group.  Now, as a
  default group, this will be available, but (presumably) will not
  contain any registers.  I don't think this is necessarily a bad
  thing, there's something to be said for having some consistent
  defaults available.  There are other architectures that didn't add
  all 7 of the defaults, which will now have gained additional groups.

* maint print reggroups

  This prints the set of all available groups.  As a maintenance
  command I'm less concerned with the output changing here.
  Obviously, for the architectures that didn't previously add all the
  defaults, this list just got bigger.

* maint print register-groups

  This prints all the registers, and the groups they are in.  If the
  defaults were not previously being added then a register (obviously)
  can't appear in one of the default groups.  Now the groups are
  available then registers might be in more groups than previously.
  However, this is again a maintenance command, so I'm less concerned
  about this changing.
---
 gdb/aarch64-tdep.c | 17 -------------
 gdb/arc-tdep.c     | 17 -------------
 gdb/csky-tdep.c    |  2 --
 gdb/i386-tdep.c    |  7 ------
 gdb/lm32-tdep.c    | 11 ---------
 gdb/m32c-tdep.c    |  5 ----
 gdb/m68hc11-tdep.c |  7 ------
 gdb/mep-tdep.c     |  4 ----
 gdb/nds32-tdep.c   |  8 -------
 gdb/or1k-tdep.c    | 14 +----------
 gdb/reggroups.c    | 59 +++++++++++++++++++++++++++-------------------
 gdb/riscv-tdep.c   | 12 +---------
 gdb/xtensa-tdep.c  | 13 +---------
 13 files changed, 38 insertions(+), 138 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index cdeeece83c0..98eaeaf8ca4 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3367,20 +3367,6 @@ aarch64_get_tdesc_vq (const struct target_desc *tdesc)
   return sve_vq_from_vl (vl);
 }
 
-/* Add all the expected register sets into GDBARCH.  */
-
-static void
-aarch64_add_reggroups (struct gdbarch *gdbarch)
-{
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-}
-
 /* Implement the "cannot_store_register" gdbarch method.  */
 
 static int
@@ -3636,9 +3622,6 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Virtual tables.  */
   set_gdbarch_vbit_in_delta (gdbarch, 1);
 
-  /* Register architecture.  */
-  aarch64_add_reggroups (gdbarch);
-
   /* Hook in the ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
   info.tdesc_data = tdesc_data.get ();
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index d6da2886c49..98bd1c4bc0a 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -1952,20 +1952,6 @@ static const struct frame_base arc_normal_base = {
   arc_frame_base_address
 };
 
-/* Add all the expected register sets into GDBARCH.  */
-
-static void
-arc_add_reggroups (struct gdbarch *gdbarch)
-{
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-}
-
 static enum arc_isa
 mach_type_to_arc_isa (const unsigned long mach)
 {
@@ -2364,9 +2350,6 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* This doesn't include possible long-immediate value.  */
   set_gdbarch_max_insn_length (gdbarch, 4);
 
-  /* Add default register groups.  */
-  arc_add_reggroups (gdbarch);
-
   /* Frame unwinders and sniffers.  */
   dwarf2_frame_set_init_reg (gdbarch, arc_dwarf2_frame_init_reg);
   dwarf2_append_unwinders (gdbarch);
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index f1376730c87..feb416a2406 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -2050,8 +2050,6 @@ csky_init_reggroup ()
 static void
 csky_add_reggroups (struct gdbarch *gdbarch)
 {
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
   reggroup_add (gdbarch, cr_reggroup);
   reggroup_add (gdbarch, fr_reggroup);
   reggroup_add (gdbarch, vr_reggroup);
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 400ccd6bebf..99a81b98da1 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4546,13 +4546,6 @@ i386_add_reggroups (struct gdbarch *gdbarch)
 {
   reggroup_add (gdbarch, i386_sse_reggroup);
   reggroup_add (gdbarch, i386_mmx_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
 }
 
 int
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index f3f1f87d6bb..4a781c394e9 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -59,16 +59,6 @@ struct lm32_frame_cache
   trad_frame_saved_reg *saved_regs;
 };
 
-/* Add the available register groups.  */
-
-static void
-lm32_add_reggroups (struct gdbarch *gdbarch)
-{
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-}
-
 /* Return whether a given register is in a given group.  */
 
 static int
@@ -540,7 +530,6 @@ lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_push_dummy_call (gdbarch, lm32_push_dummy_call);
   set_gdbarch_return_value (gdbarch, lm32_return_value);
 
-  lm32_add_reggroups (gdbarch);
   set_gdbarch_register_reggroup_p (gdbarch, lm32_register_reggroup_p);
 
   return gdbarch;
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 94087302892..5a767c9ed52 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -981,11 +981,6 @@ make_regs (struct gdbarch *arch)
   set_gdbarch_dwarf2_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum);
   set_gdbarch_register_reggroup_p (arch, m32c_register_reggroup_p);
 
-  reggroup_add (arch, general_reggroup);
-  reggroup_add (arch, all_reggroup);
-  reggroup_add (arch, save_reggroup);
-  reggroup_add (arch, restore_reggroup);
-  reggroup_add (arch, system_reggroup);
   reggroup_add (arch, m32c_dma_reggroup);
 }
 
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index f1133fe6780..9d978d88018 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1361,13 +1361,6 @@ m68hc11_add_reggroups (struct gdbarch *gdbarch)
 {
   reggroup_add (gdbarch, m68hc11_hard_reggroup);
   reggroup_add (gdbarch, m68hc11_soft_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
 }
 
 static int
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 50bea7cb49f..e449c66c9b5 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -2428,10 +2428,6 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_stab_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum);
 
   set_gdbarch_register_reggroup_p (gdbarch, mep_register_reggroup_p);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
   reggroup_add (gdbarch, mep_csr_reggroup);
   reggroup_add (gdbarch, mep_cr_reggroup);
   reggroup_add (gdbarch, mep_ccr_reggroup);
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 425d7d90d64..a94a03ab2ab 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -343,14 +343,6 @@ nds32_init_reggroups (void)
 static void
 nds32_add_reggroups (struct gdbarch *gdbarch)
 {
-  /* Add pre-defined register groups.  */
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-
   /* Add NDS32 register groups.  */
   reggroup_add (gdbarch, nds32_cr_reggroup);
   reggroup_add (gdbarch, nds32_ir_reggroup);
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index 9f7fa2f169f..2b906fa69d3 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -1260,19 +1260,7 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   if (tdesc_data != NULL)
-    {
-      /* If we are using tdesc, register our own reggroups, otherwise we
-	 will used the defaults.  */
-      reggroup_add (gdbarch, general_reggroup);
-      reggroup_add (gdbarch, system_reggroup);
-      reggroup_add (gdbarch, float_reggroup);
-      reggroup_add (gdbarch, vector_reggroup);
-      reggroup_add (gdbarch, all_reggroup);
-      reggroup_add (gdbarch, save_reggroup);
-      reggroup_add (gdbarch, restore_reggroup);
-
-      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
-    }
+    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 6c38ca743f4..e47a6daf9a0 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -90,15 +90,6 @@ struct reggroups
 
 static struct gdbarch_data *reggroups_data;
 
-static void *
-reggroups_init (struct obstack *obstack)
-{
-  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
-
-  groups->last = &groups->first;
-  return groups;
-}
-
 /* Add a register group (with attribute values) to the pre-defined
    list.  */
 
@@ -119,13 +110,44 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
 
+  /* The same reggroup should not be added multiple times.  */
+  gdb_assert (groups != nullptr);
+  for (struct reggroup_el *el = groups->first;
+       el != nullptr;
+       el = el->next)
+    gdb_assert (group != el->group);
+
   add_group (groups, group,
 	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
 }
 
-/* The default register groups for an architecture.  */
+/* Called to initialize the per-gdbarch register group information.  */
 
-static struct reggroups default_groups = { NULL, &default_groups.first };
+static void *
+reggroups_init (struct obstack *obstack)
+{
+  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
+
+  groups->last = &groups->first;
+
+  /* Add the default groups.  */
+  add_group (groups, general_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, float_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, system_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, vector_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, all_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, save_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  add_group (groups, restore_reggroup,
+	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+
+  return groups;
+}
 
 /* A register group iterator.  */
 
@@ -139,8 +161,7 @@ reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
      creation.  If there are no groups, use the default groups list.  */
   groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
   gdb_assert (groups != NULL);
-  if (groups->first == NULL)
-    groups = &default_groups;
+  gdb_assert (groups->first != NULL);
 
   /* Return the first/next reggroup.  */
   if (last == NULL)
@@ -171,8 +192,7 @@ reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
      creation.  If there are no groups, use the default groups list.  */
   groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
   gdb_assert (groups != NULL);
-  if (groups->first == NULL)
-    groups = &default_groups;
+  gdb_assert (groups->first != NULL);
 
   prev = NULL;
   for (el = groups->first; el != NULL; el = el->next)
@@ -327,15 +347,6 @@ _initialize_reggroup ()
 {
   reggroups_data = gdbarch_data_register_pre_init (reggroups_init);
 
-  /* The pre-defined list of groups.  */
-  add_group (&default_groups, general_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, float_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, system_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, vector_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, all_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, save_reggroup, XNEW (struct reggroup_el));
-  add_group (&default_groups, restore_reggroup, XNEW (struct reggroup_el));
-
   add_cmd ("reggroups", class_maintenance,
 	   maintenance_print_reggroups, _("\
 Print the internal register group names.\n\
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 8713652b099..79b81351039 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -3497,21 +3497,11 @@ riscv_find_default_target_description (const struct gdbarch_info info)
   return riscv_lookup_target_description (features);
 }
 
-/* Add all the expected register sets into GDBARCH.  */
+/* Add all the RISC-V specific register groups into GDBARCH.  */
 
 static void
 riscv_add_reggroups (struct gdbarch *gdbarch)
 {
-  /* Add predefined register groups.  */
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-
-  /* Add RISC-V specific register groups.  */
   reggroup_add (gdbarch, csr_reggroup);
 }
 
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 62be13643b2..6e478ee893d 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -734,23 +734,12 @@ xtensa_init_reggroups (void)
 static void
 xtensa_add_reggroups (struct gdbarch *gdbarch)
 {
-  int i;
-
-  /* Predefined groups.  */
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-
   /* Xtensa-specific groups.  */
   reggroup_add (gdbarch, xtensa_ar_reggroup);
   reggroup_add (gdbarch, xtensa_user_reggroup);
   reggroup_add (gdbarch, xtensa_vectra_reggroup);
 
-  for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
+  for (int i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
     reggroup_add (gdbarch, xtensa_cp[i]);
 }
 
-- 
2.25.4


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

* [PATCHv2 10/16] gdb: convert reggroups to use a std::vector
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (8 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 09/16] gdb: always add the default register groups Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
                     ` (6 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Replace manual linked list with a std::vector.  This commit doesn't
change the reggroup_next and reggroup_prev API, but that will change
in a later commit.

This commit is focused on the minimal changes needed to manage the
reggroups using a std::vector, without changing the API exposed by the
reggroup.c file.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 153 ++++++++++++++++++++++++------------------------
 1 file changed, 75 insertions(+), 78 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index e47a6daf9a0..262bf49cea8 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -74,35 +74,46 @@ reggroup_type (const struct reggroup *group)
   return group->type;
 }
 
-/* A linked list of groups for the given architecture.  */
-
-struct reggroup_el
-{
-  struct reggroup *group;
-  struct reggroup_el *next;
-};
+/* A container holding all the register groups for a particular
+   architecture.  */
 
 struct reggroups
 {
-  struct reggroup_el *first;
-  struct reggroup_el **last;
+  /* Add GROUP to the list of register groups.  */
+
+  void add (struct reggroup *group)
+  {
+    gdb_assert (group != nullptr);
+    gdb_assert (std::find (m_groups.begin(), m_groups.end(), group)
+		== m_groups.end());
+
+    m_groups.push_back (group);
+  }
+
+  /* The number of register groups.  */
+
+  std::vector<struct reggroup *>::size_type
+  size () const
+  {
+    return m_groups.size ();
+  }
+
+  /* Return a reference to the list of all groups.  */
+
+  const std::vector<struct reggroup *> &
+  groups () const
+  {
+    return m_groups;
+  }
+
+private:
+  /* The register groups.  */
+  std::vector<struct reggroup *> m_groups;
 };
 
 static struct gdbarch_data *reggroups_data;
 
-/* Add a register group (with attribute values) to the pre-defined
-   list.  */
-
-static void
-add_group (struct reggroups *groups, struct reggroup *group,
-	   struct reggroup_el *el)
-{
-  gdb_assert (group != NULL);
-  el->group = group;
-  el->next = NULL;
-  (*groups->last) = el;
-  groups->last = &el->next;
-}
+/* Add GROUP to the list of register groups for GDBARCH.  */
 
 void
 reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
@@ -110,15 +121,10 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
 
-  /* The same reggroup should not be added multiple times.  */
   gdb_assert (groups != nullptr);
-  for (struct reggroup_el *el = groups->first;
-       el != nullptr;
-       el = el->next)
-    gdb_assert (group != el->group);
+  gdb_assert (group != nullptr);
 
-  add_group (groups, group,
-	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
+  groups->add (group);
 }
 
 /* Called to initialize the per-gdbarch register group information.  */
@@ -126,25 +132,16 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
 static void *
 reggroups_init (struct obstack *obstack)
 {
-  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
-
-  groups->last = &groups->first;
+  struct reggroups *groups = obstack_new<struct reggroups> (obstack);
 
   /* Add the default groups.  */
-  add_group (groups, general_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, float_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, system_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, vector_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, all_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, save_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
-  add_group (groups, restore_reggroup,
-	     OBSTACK_ZALLOC (obstack, struct reggroup_el));
+  groups->add (general_reggroup);
+  groups->add (float_reggroup);
+  groups->add (system_reggroup);
+  groups->add (vector_reggroup);
+  groups->add (all_reggroup);
+  groups->add (save_reggroup);
+  groups->add (restore_reggroup);
 
   return groups;
 }
@@ -154,29 +151,28 @@ reggroups_init (struct obstack *obstack)
 struct reggroup *
 reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
 {
-  struct reggroups *groups;
-  struct reggroup_el *el;
-
   /* Don't allow this function to be called during architecture
      creation.  If there are no groups, use the default groups list.  */
-  groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
-  gdb_assert (groups != NULL);
-  gdb_assert (groups->first != NULL);
+  struct reggroups *groups
+    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
+  gdb_assert (groups != nullptr);
+  gdb_assert (groups->size () > 0);
 
   /* Return the first/next reggroup.  */
-  if (last == NULL)
-    return groups->first->group;
-  for (el = groups->first; el != NULL; el = el->next)
+  if (last == nullptr)
+    return groups->groups ().front ();
+  for (int i = 0; i < groups->size (); ++i)
     {
-      if (el->group == last)
+      if (groups->groups ()[i] == last)
 	{
-	  if (el->next != NULL)
-	    return el->next->group;
+	  if (i + 1 < groups->size ())
+	    return groups->groups ()[i + 1];
 	  else
-	    return NULL;
+	    return nullptr;
 	}
     }
-  return NULL;
+
+  return nullptr;
 }
 
 /* See reggroups.h.  */
@@ -184,27 +180,28 @@ reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
 struct reggroup *
 reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
 {
-  struct reggroups *groups;
-  struct reggroup_el *el;
-  struct reggroup *prev;
-
   /* Don't allow this function to be called during architecture
      creation.  If there are no groups, use the default groups list.  */
-  groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
-  gdb_assert (groups != NULL);
-  gdb_assert (groups->first != NULL);
+  struct reggroups *groups
+    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
+  gdb_assert (groups != nullptr);
+  gdb_assert (groups->size () > 0);
 
-  prev = NULL;
-  for (el = groups->first; el != NULL; el = el->next)
+  /* Return the first/next reggroup.  */
+  if (curr == nullptr)
+    return groups->groups ().back ();
+  for (int i = groups->size () - 1; i >= 0; --i)
     {
-      gdb_assert (el->group != NULL);
-      if (el->group == curr)
-	return prev;
-      prev = el->group;
+      if (groups->groups ()[i] == curr)
+	{
+	  if (i - 1 >= 0)
+	    return groups->groups ()[i - 1];
+	  else
+	    return nullptr;
+	}
     }
-  if (curr == NULL)
-    return prev;
-  return NULL;
+
+  return nullptr;
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -234,7 +231,7 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
     return (!vector_p && !float_p);
   if (group == save_reggroup || group == restore_reggroup)
     return raw_p;
-  return 0;   
+  return 0;
 }
 
 /* See reggroups.h.  */
@@ -273,7 +270,7 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
 	  name = reggroup_name (group);
 	gdb_printf (file, " %-10s", name);
       }
-      
+
       /* Group type.  */
       {
 	const char *type;
-- 
2.25.4


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

* [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (9 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 10/16] gdb: convert reggroups to use a std::vector Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 14:22     ` Simon Marchi
  2022-04-06 12:04   ` [PATCHv2 12/16] gdb: more 'const' in gdb/reggroups.{c,h} Andrew Burgess
                     ` (5 subsequent siblings)
  16 siblings, 1 reply; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Add a new function gdbarch_reggroups that returns a reference to a
vector containing all the reggroups for an architecture.

Make use of this function throughout GDB instead of the existing
reggroup_next and reggroup_prev functions.

Finally, delete the reggroup_next and reggroup_prev functions.

Most of these changes are pretty straight forward, using range based
for loops instead of the old style look using reggroup_next.  There
are two places where the changes are less straight forward.

In gdb/python/py-registers.c, the register group iterator needed to
change slightly.  As the iterator is tightly coupled to the gdbarch, I
just fetch the register group vector from the gdbarch when needed, and
use an index counter to find the next item from the vector when
needed.

In gdb/tui/tui-regs.c the tui_reg_next and tui_reg_prev functions are
just wrappers around reggroup_next and reggroup_prev respectively.
I've just inlined the logic of the old functions into the tui
functions.  As the tui function had its own special twist (wrap around
behaviour) I think this is OK.

There should be no user visible changes after this commit.
---
 gdb/completer.c           |   6 +-
 gdb/infcmd.c              |  14 ++---
 gdb/python/py-registers.c |  17 +++---
 gdb/regcache-dump.c       |   6 +-
 gdb/reggroups.c           | 118 ++++++++------------------------------
 gdb/reggroups.h           |  12 ++--
 gdb/tui/tui-regs.c        |  65 ++++++++++++---------
 7 files changed, 84 insertions(+), 154 deletions(-)

diff --git a/gdb/completer.c b/gdb/completer.c
index 63b4cd22d24..f4b5917095d 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1819,11 +1819,7 @@ reg_or_group_completer_1 (completion_tracker &tracker,
 
   if ((targets & complete_reggroup_names) != 0)
     {
-      struct reggroup *group;
-
-      for (group = reggroup_next (gdbarch, NULL);
-	   group != NULL;
-	   group = reggroup_next (gdbarch, group))
+      for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	{
 	  name = reggroup_name (group);
 	  if (strncmp (word, name, len) == 0)
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index b76345d8426..9abb91f2faa 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2295,17 +2295,17 @@ registers_info (const char *addr_exp, int fpregs)
 
       /* A register group?  */
       {
-	struct reggroup *group;
-
-	for (group = reggroup_next (gdbarch, NULL);
-	     group != NULL;
-	     group = reggroup_next (gdbarch, group))
+	const struct reggroup *group = nullptr;
+	for (const struct reggroup *g : gdbarch_reggroups (gdbarch))
 	  {
 	    /* Don't bother with a length check.  Should the user
 	       enter a short register group name, go with the first
 	       group that matches.  */
-	    if (strncmp (start, reggroup_name (group), end - start) == 0)
-	      break;
+	    if (strncmp (start, reggroup_name (g), end - start) == 0)
+	      {
+		group = g;
+		break;
+	      }
 	  }
 	if (group != NULL)
 	  {
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index 58d196c37b4..7a9d2e22403 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -65,8 +65,8 @@ extern PyTypeObject register_descriptor_object_type
 struct reggroup_iterator_object {
   PyObject_HEAD
 
-  /* The last register group returned.  Initially this will be NULL.  */
-  const struct reggroup *reggroup;
+  /* The index into GROUPS for the next group to return.  */
+  std::vector<const reggroup *>::size_type index;
 
   /* Pointer back to the architecture we're finding registers for.  */
   struct gdbarch *gdbarch;
@@ -225,17 +225,18 @@ gdbpy_reggroup_iter_next (PyObject *self)
 {
   reggroup_iterator_object *iter_obj
     = (reggroup_iterator_object *) self;
-  struct gdbarch *gdbarch = iter_obj->gdbarch;
 
-  const reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
-  if (next_group == NULL)
+  const std::vector<const reggroup *> &groups
+    = gdbarch_reggroups (iter_obj->gdbarch);
+  if (iter_obj->index >= groups.size ())
     {
       PyErr_SetString (PyExc_StopIteration, _("No more groups"));
       return NULL;
     }
 
-  iter_obj->reggroup = next_group;
-  return gdbpy_get_reggroup (iter_obj->reggroup).release ();
+  const reggroup *group = groups[iter_obj->index];
+  iter_obj->index++;
+  return gdbpy_get_reggroup (group).release ();
 }
 
 /* Return a new gdb.RegisterGroupsIterator over all the register groups in
@@ -252,7 +253,7 @@ gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch)
 		    &reggroup_iterator_object_type);
   if (iter == NULL)
     return NULL;
-  iter->reggroup = NULL;
+  iter->index = 0;
   iter->gdbarch = gdbarch;
   return (PyObject *) iter;
 }
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c
index 2a2578558f7..409a868be76 100644
--- a/gdb/regcache-dump.c
+++ b/gdb/regcache-dump.c
@@ -192,11 +192,7 @@ class register_dump_groups : public register_dump
     else
       {
 	const char *sep = "";
-	struct reggroup *group;
-
-	for (group = reggroup_next (m_gdbarch, NULL);
-	     group != NULL;
-	     group = reggroup_next (m_gdbarch, group))
+	for (const struct reggroup *group : gdbarch_reggroups (m_gdbarch))
 	  {
 	    if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group))
 	      {
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 262bf49cea8..4607c4b674c 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -100,7 +100,7 @@ struct reggroups
 
   /* Return a reference to the list of all groups.  */
 
-  const std::vector<struct reggroup *> &
+  const std::vector<const struct reggroup *> &
   groups () const
   {
     return m_groups;
@@ -108,7 +108,7 @@ struct reggroups
 
 private:
   /* The register groups.  */
-  std::vector<struct reggroup *> m_groups;
+  std::vector<const struct reggroup *> m_groups;
 };
 
 static struct gdbarch_data *reggroups_data;
@@ -146,62 +146,15 @@ reggroups_init (struct obstack *obstack)
   return groups;
 }
 
-/* A register group iterator.  */
-
-struct reggroup *
-reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
-{
-  /* Don't allow this function to be called during architecture
-     creation.  If there are no groups, use the default groups list.  */
-  struct reggroups *groups
-    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
-  gdb_assert (groups != nullptr);
-  gdb_assert (groups->size () > 0);
-
-  /* Return the first/next reggroup.  */
-  if (last == nullptr)
-    return groups->groups ().front ();
-  for (int i = 0; i < groups->size (); ++i)
-    {
-      if (groups->groups ()[i] == last)
-	{
-	  if (i + 1 < groups->size ())
-	    return groups->groups ()[i + 1];
-	  else
-	    return nullptr;
-	}
-    }
-
-  return nullptr;
-}
-
 /* See reggroups.h.  */
-
-struct reggroup *
-reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
+const std::vector<const reggroup *>
+gdbarch_reggroups (struct gdbarch *gdbarch)
 {
-  /* Don't allow this function to be called during architecture
-     creation.  If there are no groups, use the default groups list.  */
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
   gdb_assert (groups != nullptr);
   gdb_assert (groups->size () > 0);
-
-  /* Return the first/next reggroup.  */
-  if (curr == nullptr)
-    return groups->groups ().back ();
-  for (int i = groups->size () - 1; i >= 0; --i)
-    {
-      if (groups->groups ()[i] == curr)
-	{
-	  if (i - 1 >= 0)
-	    return groups->groups ()[i - 1];
-	  else
-	    return nullptr;
-	}
-    }
-
-  return nullptr;
+  return groups->groups ();
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -239,11 +192,7 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 const reggroup *
 reggroup_find (struct gdbarch *gdbarch, const char *name)
 {
-  struct reggroup *group;
-
-  for (group = reggroup_next (gdbarch, NULL);
-       group != NULL;
-       group = reggroup_next (gdbarch, group))
+  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
       if (strcmp (name, reggroup_name (group)) == 0)
 	return group;
@@ -256,52 +205,35 @@ reggroup_find (struct gdbarch *gdbarch, const char *name)
 static void
 reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct reggroup *group = NULL;
+  static constexpr const char *fmt = " %-10s %-10s\n";
 
-  do
+  gdb_printf (file, fmt, "Group", "Type");
+
+  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
       /* Group name.  */
-      {
-	const char *name;
-
-	if (group == NULL)
-	  name = "Group";
-	else
-	  name = reggroup_name (group);
-	gdb_printf (file, " %-10s", name);
-      }
+      const char *name = reggroup_name (group);
 
       /* Group type.  */
-      {
-	const char *type;
-
-	if (group == NULL)
-	  type = "Type";
-	else
-	  {
-	    switch (reggroup_type (group))
-	      {
-	      case USER_REGGROUP:
-		type = "user";
-		break;
-	      case INTERNAL_REGGROUP:
-		type = "internal";
-		break;
-	      default:
-		internal_error (__FILE__, __LINE__, _("bad switch"));
-	      }
-	  }
-	gdb_printf (file, " %-10s", type);
-      }
+      const char *type;
+
+      switch (reggroup_type (group))
+	{
+	case USER_REGGROUP:
+	  type = "user";
+	  break;
+	case INTERNAL_REGGROUP:
+	  type = "internal";
+	  break;
+	default:
+	  internal_error (__FILE__, __LINE__, _("bad switch"));
+	}
 
       /* Note: If you change this, be sure to also update the
 	 documentation.  */
-      
-      gdb_printf (file, "\n");
 
-      group = reggroup_next (gdbarch, group);
+      gdb_printf (file, fmt, name, type);
     }
-  while (group != NULL);
 }
 
 static void
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index bc87a7325f0..959191c4180 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -53,14 +53,10 @@ extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
 extern const char *reggroup_name (const struct reggroup *reggroup);
 extern enum reggroup_type reggroup_type (const struct reggroup *reggroup);
 
-/* Iterators for the architecture's register groups.  Pass in NULL, returns
-   the first (for next), or last (for prev) group.  Pass in a group,
-   returns the next or previous group, or NULL when either the end or the
-   beginning of the group list is reached.  */
-extern struct reggroup *reggroup_next (struct gdbarch *gdbarch,
-				       const struct reggroup *last);
-extern struct reggroup *reggroup_prev (struct gdbarch *gdbarch,
-				       const struct reggroup *curr);
+/* Return the list of all register groups for GDBARCH.  */
+extern const std::vector<const reggroup *>
+	gdbarch_reggroups (struct gdbarch *gdbarch);
+
 /* Find a reggroup by name.  */
 extern const reggroup *reggroup_find (struct gdbarch *gdbarch,
 				      const char *name);
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index b968947fa1c..acffc75238a 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -514,34 +514,48 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
     (void) wstandend (handle);
 }
 
-/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
-   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
-   nullptr (e.g. if the tui register window has only just been displayed
-   and has no current group selected), then the first register group will
-   be returned.  */
+/* Helper for "tui reg next", returns the next register group after
+   CURRENT_GROUP in the register group list for GDBARCH, with wrap around
+   behaviour.
+
+   If CURRENT_GROUP is nullptr (e.g. if the tui register window has only
+   just been displayed and has no current group selected) or the currently
+   selected register group can't be found (e.g. if the architecture has
+   changed since the register window was last updated), then the last
+   register group will be returned.  */
 
 static const reggroup *
 tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = reggroup_next (gdbarch, current_group);
-  if (group == NULL)
-    group = reggroup_next (gdbarch, NULL);
-  return group;
+  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
+  auto it = std::find (groups.begin (), groups.end (), current_group);
+  if (it != groups.end ())
+    it++;
+  if (it == groups.end ())
+    return groups.front ();
+  return *it;
 }
 
-/* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
-   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
-   nullptr (e.g. if the tui register window has only just been displayed
-   and has no current group selected), then the last register group will
-   be returned.  */
+/* Helper for "tui reg prev", returns the register group previous to
+   CURRENT_GROUP in the register group list for GDBARCH, with wrap around
+   behaviour.
+
+   If CURRENT_GROUP is nullptr (e.g. if the tui register window has only
+   just been displayed and has no current group selected) or the currently
+   selected register group can't be found (e.g. if the architecture has
+   changed since the register window was last updated), then the last
+   register group will be returned.  */
 
 static const reggroup *
 tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
 {
-  const reggroup *group = reggroup_prev (gdbarch, current_group);
-  if (group == NULL)
-    group = reggroup_prev (gdbarch, NULL);
-  return group;
+  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
+  auto it = std::find (groups.rbegin (), groups.rend (), current_group);
+  if (it != groups.rend ())
+    it++;
+  if (it == groups.rend ())
+    return groups.back ();
+  return *it;
 }
 
 /* Implement the 'tui reg' command.  Changes the register group displayed
@@ -555,7 +569,6 @@ tui_reg_command (const char *args, int from_tty)
 
   if (args != NULL)
     {
-      const reggroup *group, *match = NULL;
       size_t len = strlen (args);
 
       /* Make sure the curses mode is enabled.  */
@@ -569,6 +582,7 @@ tui_reg_command (const char *args, int from_tty)
       if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ())
 	tui_regs_layout ();
 
+      const reggroup *match = nullptr;
       const reggroup *current_group = TUI_DATA_WIN->get_current_group ();
       if (strncmp (args, "next", len) == 0)
 	match = tui_reg_next (current_group, gdbarch);
@@ -579,9 +593,7 @@ tui_reg_command (const char *args, int from_tty)
 	  /* This loop matches on the initial part of a register group
 	     name.  If this initial part in ARGS matches only one register
 	     group then the switch is made.  */
-	  for (group = reggroup_next (gdbarch, NULL);
-	       group != NULL;
-	       group = reggroup_next (gdbarch, group))
+	  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	    {
 	      if (strncmp (reggroup_name (group), args, len) == 0)
 		{
@@ -599,19 +611,16 @@ tui_reg_command (const char *args, int from_tty)
     }
   else
     {
-      const reggroup *group;
-      int first;
-
       gdb_printf (_("\"tui reg\" must be followed by the name of "
 		    "either a register group,\nor one of 'next' "
 		    "or 'prev'.  Known register groups are:\n"));
 
-      for (first = 1, group = reggroup_next (gdbarch, NULL);
-	   group != NULL;
-	   first = 0, group = reggroup_next (gdbarch, group))
+      bool first = true;
+      for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	{
 	  if (!first)
 	    gdb_printf (", ");
+	  first = false;
 	  gdb_printf ("%s", reggroup_name (group));
 	}
 
-- 
2.25.4


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

* [PATCHv2 12/16] gdb: more 'const' in gdb/reggroups.{c,h}
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (10 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 13/16] gdb: make the pre-defined register groups const Andrew Burgess
                     ` (4 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert the reggroup_new and reggroup_gdbarch_new functions to return
a 'const regggroup *', and fix up all the fallout.

There should be no user visible changes after this commit.
---
 gdb/csky-tdep.c    | 10 +++++-----
 gdb/i386-tdep.c    |  4 ++--
 gdb/m32c-tdep.c    |  2 +-
 gdb/m68hc11-tdep.c |  4 ++--
 gdb/mep-tdep.c     |  6 +++---
 gdb/nds32-tdep.c   | 20 ++++++++++----------
 gdb/reggroups.c    |  8 ++++----
 gdb/reggroups.h    | 13 +++++++------
 gdb/riscv-tdep.c   |  2 +-
 gdb/xtensa-tdep.c  |  8 ++++----
 10 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index feb416a2406..3712409dbe8 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -61,11 +61,11 @@
 /* Control debugging information emitted in this file.  */
 static bool csky_debug = false;
 
-static struct reggroup *cr_reggroup;
-static struct reggroup *fr_reggroup;
-static struct reggroup *vr_reggroup;
-static struct reggroup *mmu_reggroup;
-static struct reggroup *prof_reggroup;
+static const reggroup *cr_reggroup;
+static const reggroup *fr_reggroup;
+static const reggroup *vr_reggroup;
+static const reggroup *mmu_reggroup;
+static const reggroup *prof_reggroup;
 
 /* Convenience function to print debug messages in prologue analysis.  */
 
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 99a81b98da1..8501e12e241 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4531,8 +4531,8 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 /* i386 register groups.  In addition to the normal groups, add "mmx"
    and "sse".  */
 
-static struct reggroup *i386_sse_reggroup;
-static struct reggroup *i386_mmx_reggroup;
+static const reggroup *i386_sse_reggroup;
+static const reggroup *i386_mmx_reggroup;
 
 static void
 i386_init_reggroups (void)
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 5a767c9ed52..55ef5a551f8 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -35,7 +35,7 @@
 \f
 /* The m32c tdep structure.  */
 
-static struct reggroup *m32c_dma_reggroup;
+static const reggroup *m32c_dma_reggroup;
 
 /* The type of a function that moves the value of REG between CACHE or
    BUF --- in either direction.  */
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 9d978d88018..5c1f20415c8 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1346,8 +1346,8 @@ m68hc11_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
 /* 68HC11/68HC12 register groups.
    Identify real hard registers and soft registers used by gcc.  */
 
-static struct reggroup *m68hc11_soft_reggroup;
-static struct reggroup *m68hc11_hard_reggroup;
+static const reggroup *m68hc11_soft_reggroup;
+static const reggroup *m68hc11_hard_reggroup;
 
 static void
 m68hc11_init_reggroups (void)
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index e449c66c9b5..27a1c5dd1ca 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1022,9 +1022,9 @@ mep_register_name (struct gdbarch *gdbarch, int regnr)
 
 
 /* Custom register groups for the MeP.  */
-static struct reggroup *mep_csr_reggroup; /* control/special */
-static struct reggroup *mep_cr_reggroup;  /* coprocessor general-purpose */
-static struct reggroup *mep_ccr_reggroup; /* coprocessor control */
+static const reggroup *mep_csr_reggroup; /* control/special */
+static const reggroup *mep_cr_reggroup;  /* coprocessor general-purpose */
+static const reggroup *mep_ccr_reggroup; /* coprocessor control */
 
 
 static int
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index a94a03ab2ab..06b129bdd31 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -314,16 +314,16 @@ nds32_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
 }
 \f
 /* NDS32 register groups.  */
-static struct reggroup *nds32_cr_reggroup;
-static struct reggroup *nds32_ir_reggroup;
-static struct reggroup *nds32_mr_reggroup;
-static struct reggroup *nds32_dr_reggroup;
-static struct reggroup *nds32_pfr_reggroup;
-static struct reggroup *nds32_hspr_reggroup;
-static struct reggroup *nds32_dmar_reggroup;
-static struct reggroup *nds32_racr_reggroup;
-static struct reggroup *nds32_idr_reggroup;
-static struct reggroup *nds32_secur_reggroup;
+static const reggroup *nds32_cr_reggroup;
+static const reggroup *nds32_ir_reggroup;
+static const reggroup *nds32_mr_reggroup;
+static const reggroup *nds32_dr_reggroup;
+static const reggroup *nds32_pfr_reggroup;
+static const reggroup *nds32_hspr_reggroup;
+static const reggroup *nds32_dmar_reggroup;
+static const reggroup *nds32_racr_reggroup;
+static const reggroup *nds32_idr_reggroup;
+static const reggroup *nds32_secur_reggroup;
 
 static void
 nds32_init_reggroups (void)
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 4607c4b674c..419e091c3c0 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -36,7 +36,7 @@ struct reggroup
   enum reggroup_type type;
 };
 
-struct reggroup *
+const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
   struct reggroup *group = XNEW (struct reggroup);
@@ -48,7 +48,7 @@ reggroup_new (const char *name, enum reggroup_type type)
 
 /* See reggroups.h.  */
 
-struct reggroup *
+const reggroup *
 reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 		      enum reggroup_type type)
 {
@@ -81,7 +81,7 @@ struct reggroups
 {
   /* Add GROUP to the list of register groups.  */
 
-  void add (struct reggroup *group)
+  void add (const reggroup *group)
   {
     gdb_assert (group != nullptr);
     gdb_assert (std::find (m_groups.begin(), m_groups.end(), group)
@@ -116,7 +116,7 @@ static struct gdbarch_data *reggroups_data;
 /* Add GROUP to the list of register groups for GDBARCH.  */
 
 void
-reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
+reggroup_add (struct gdbarch *gdbarch, const reggroup *group)
 {
   struct reggroups *groups
     = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index 959191c4180..28bd00ff176 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -39,15 +39,16 @@ extern struct reggroup *const save_reggroup;
 extern struct reggroup *const restore_reggroup;
 
 /* Create a new local register group.  */
-extern struct reggroup *reggroup_new (const char *name,
-				      enum reggroup_type type);
+extern const reggroup *reggroup_new (const char *name,
+				     enum reggroup_type type);
+
 /* Create a new register group allocated onto the gdbarch obstack.  */
-extern struct reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
-					      const char *name,
-					      enum reggroup_type type);
+extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
+					     const char *name,
+					     enum reggroup_type type);
 
 /* Add a register group (with attribute values) to the pre-defined list.  */
-extern void reggroup_add (struct gdbarch *gdbarch, struct reggroup *group);
+extern void reggroup_add (struct gdbarch *gdbarch, const reggroup *group);
 
 /* Register group attributes.  */
 extern const char *reggroup_name (const struct reggroup *reggroup);
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 79b81351039..ab239744393 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -129,7 +129,7 @@ struct riscv_unwind_cache
 
 /* RISC-V specific register group for CSRs.  */
 
-static reggroup *csr_reggroup = NULL;
+static const reggroup *csr_reggroup = nullptr;
 
 /* Callback function for user_reg_add.  */
 
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 6e478ee893d..89bdd7ffd28 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -712,10 +712,10 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
 		    _("invalid register number %d"), regnum);
 }
 
-static struct reggroup *xtensa_ar_reggroup;
-static struct reggroup *xtensa_user_reggroup;
-static struct reggroup *xtensa_vectra_reggroup;
-static struct reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];
+static const reggroup *xtensa_ar_reggroup;
+static const reggroup *xtensa_user_reggroup;
+static const reggroup *xtensa_vectra_reggroup;
+static const reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];
 
 static void
 xtensa_init_reggroups (void)
-- 
2.25.4


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

* [PATCHv2 13/16] gdb: make the pre-defined register groups const
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (11 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 12/16] gdb: more 'const' in gdb/reggroups.{c,h} Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 14/16] gdb: convert reggroup to a C++ class with constructor, etc Andrew Burgess
                     ` (3 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert the 7 global, pre-defined, register groups const, and fix the
fall out (a minor tweak required in riscv-tdep.c).

There should be no user visible changes after this commit.
---
 gdb/reggroups.c  | 30 +++++++++++++++---------------
 gdb/reggroups.h  | 14 +++++++-------
 gdb/riscv-tdep.c |  2 +-
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 419e091c3c0..2888704f2d2 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -254,21 +254,21 @@ maintenance_print_reggroups (const char *args, int from_tty)
 }
 
 /* Pre-defined register groups.  */
-static struct reggroup general_group = { "general", USER_REGGROUP };
-static struct reggroup float_group = { "float", USER_REGGROUP };
-static struct reggroup system_group = { "system", USER_REGGROUP };
-static struct reggroup vector_group = { "vector", USER_REGGROUP };
-static struct reggroup all_group = { "all", USER_REGGROUP };
-static struct reggroup save_group = { "save", INTERNAL_REGGROUP };
-static struct reggroup restore_group = { "restore", INTERNAL_REGGROUP };
-
-struct reggroup *const general_reggroup = &general_group;
-struct reggroup *const float_reggroup = &float_group;
-struct reggroup *const system_reggroup = &system_group;
-struct reggroup *const vector_reggroup = &vector_group;
-struct reggroup *const all_reggroup = &all_group;
-struct reggroup *const save_reggroup = &save_group;
-struct reggroup *const restore_reggroup = &restore_group;
+static const reggroup general_group = { "general", USER_REGGROUP };
+static const reggroup float_group = { "float", USER_REGGROUP };
+static const reggroup system_group = { "system", USER_REGGROUP };
+static const reggroup vector_group = { "vector", USER_REGGROUP };
+static const reggroup all_group = { "all", USER_REGGROUP };
+static const reggroup save_group = { "save", INTERNAL_REGGROUP };
+static const reggroup restore_group = { "restore", INTERNAL_REGGROUP };
+
+const reggroup *const general_reggroup = &general_group;
+const reggroup *const float_reggroup = &float_group;
+const reggroup *const system_reggroup = &system_group;
+const reggroup *const vector_reggroup = &vector_group;
+const reggroup *const all_reggroup = &all_group;
+const reggroup *const save_reggroup = &save_group;
+const reggroup *const restore_reggroup = &restore_group;
 
 void _initialize_reggroup ();
 void
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index 28bd00ff176..ec1d79dfc30 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -28,15 +28,15 @@ struct reggroup;
 enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP };
 
 /* Pre-defined, user visible, register groups.  */
-extern struct reggroup *const general_reggroup;
-extern struct reggroup *const float_reggroup;
-extern struct reggroup *const system_reggroup;
-extern struct reggroup *const vector_reggroup;
-extern struct reggroup *const all_reggroup;
+extern const reggroup *const general_reggroup;
+extern const reggroup *const float_reggroup;
+extern const reggroup *const system_reggroup;
+extern const reggroup *const vector_reggroup;
+extern const reggroup *const all_reggroup;
 
 /* Pre-defined, internal, register groups.  */
-extern struct reggroup *const save_reggroup;
-extern struct reggroup *const restore_reggroup;
+extern const reggroup *const save_reggroup;
+extern const reggroup *const restore_reggroup;
 
 /* Create a new local register group.  */
 extern const reggroup *reggroup_new (const char *name,
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index ab239744393..69f2123dcdb 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1369,7 +1369,7 @@ riscv_print_registers_info (struct gdbarch *gdbarch,
     }
   else
     {
-      struct reggroup *reggroup;
+      const struct reggroup *reggroup;
 
       if (print_all)
 	reggroup = all_reggroup;
-- 
2.25.4


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

* [PATCHv2 14/16] gdb: convert reggroup to a C++ class with constructor, etc
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (12 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 13/16] gdb: make the pre-defined register groups const Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 15/16] gdb: move struct reggroup into reggroups.h header Andrew Burgess
                     ` (2 subsequent siblings)
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Convert the 'struct reggroup' into a real class, with a constructor
and getter methods.

There should be no user visible changes after this commit.
---
 gdb/reggroups.c | 48 ++++++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 2888704f2d2..dfae60773bb 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -32,18 +32,33 @@
 
 struct reggroup
 {
-  const char *name;
-  enum reggroup_type type;
+  /* Create a new register group object.  The NAME is not owned by the new
+     reggroup object, so must outlive the object.  */
+  reggroup (const char *name, enum reggroup_type type)
+    : m_name (name),
+      m_type (type)
+  { /* Nothing.  */ }
+
+  /* Return the name for this register group.  */
+  const char *name () const
+  { return m_name; }
+
+  /* Return the type of this register group.  */
+  enum reggroup_type type () const
+  { return m_type; }
+
+private:
+  /* The name of this register group.  */
+  const char *m_name;
+
+  /* The type of this register group.  */
+  enum reggroup_type m_type;
 };
 
 const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
-  struct reggroup *group = XNEW (struct reggroup);
-
-  group->name = name;
-  group->type = type;
-  return group;
+  return new reggroup (name, type);
 }
 
 /* See reggroups.h.  */
@@ -52,12 +67,9 @@ const reggroup *
 reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 		      enum reggroup_type type)
 {
-  struct reggroup *group = GDBARCH_OBSTACK_ZALLOC (gdbarch,
-						   struct reggroup);
-
-  group->name = gdbarch_obstack_strdup (gdbarch, name);
-  group->type = type;
-  return group;
+  name = gdbarch_obstack_strdup (gdbarch, name);
+  return obstack_new<struct reggroup> (gdbarch_obstack (gdbarch),
+				       name, type);
 }
 
 /* Register group attributes.  */
@@ -65,13 +77,13 @@ reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 const char *
 reggroup_name (const struct reggroup *group)
 {
-  return group->name;
+  return group->name ();
 }
 
 enum reggroup_type
 reggroup_type (const struct reggroup *group)
 {
-  return group->type;
+  return group->type ();
 }
 
 /* A container holding all the register groups for a particular
@@ -194,7 +206,7 @@ reggroup_find (struct gdbarch *gdbarch, const char *name)
 {
   for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
-      if (strcmp (name, reggroup_name (group)) == 0)
+      if (strcmp (name, group->name ()) == 0)
 	return group;
     }
   return NULL;
@@ -212,12 +224,12 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
   for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
     {
       /* Group name.  */
-      const char *name = reggroup_name (group);
+      const char *name = group->name ();
 
       /* Group type.  */
       const char *type;
 
-      switch (reggroup_type (group))
+      switch (group->type ())
 	{
 	case USER_REGGROUP:
 	  type = "user";
-- 
2.25.4


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

* [PATCHv2 15/16] gdb: move struct reggroup into reggroups.h header
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (13 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 14/16] gdb: convert reggroup to a C++ class with constructor, etc Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 12:04   ` [PATCHv2 16/16] gdb: update comments throughout reggroups.{c, h} files Andrew Burgess
  2022-04-06 14:34   ` [PATCHv2 00/16] Default register groups, and general related cleanup Simon Marchi
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

Move 'struct reggroup' into the reggroups.h header.  Remove the
reggroup_name and reggroup_type accessor functions, and just use the
name/type member functions within 'struct reggroup', update all uses
of these removed functions.

There should be no user visible changes after this commit.
---
 gdb/completer.c           |  2 +-
 gdb/infcmd.c              |  2 +-
 gdb/nds32-tdep.c          |  2 +-
 gdb/python/py-registers.c |  3 +--
 gdb/regcache-dump.c       |  3 +--
 gdb/reggroups.c           | 41 ---------------------------------------
 gdb/reggroups.h           | 32 +++++++++++++++++++++++++-----
 gdb/target-descriptions.c |  2 +-
 gdb/tui/tui-regs.c        |  6 +++---
 9 files changed, 36 insertions(+), 57 deletions(-)

diff --git a/gdb/completer.c b/gdb/completer.c
index f4b5917095d..fea3eb9329d 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1821,7 +1821,7 @@ reg_or_group_completer_1 (completion_tracker &tracker,
     {
       for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	{
-	  name = reggroup_name (group);
+	  name = group->name ();
 	  if (strncmp (word, name, len) == 0)
 	    tracker.add_completion (make_unique_xstrdup (name));
 	}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 9abb91f2faa..719bd6888a8 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2301,7 +2301,7 @@ registers_info (const char *addr_exp, int fpregs)
 	    /* Don't bother with a length check.  Should the user
 	       enter a short register group name, go with the first
 	       group that matches.  */
-	    if (strncmp (start, reggroup_name (g), end - start) == 0)
+	    if (strncmp (start, g->name (), end - start) == 0)
 	      {
 		group = g;
 		break;
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 06b129bdd31..e95ad7cc662 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -390,7 +390,7 @@ nds32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   /* The NDS32 reggroup contains registers whose name is prefixed
      by reggroup name.  */
   reg_name = gdbarch_register_name (gdbarch, regnum);
-  group_name = reggroup_name (reggroup);
+  group_name = reggroup->name ();
   return !strncmp (reg_name, group_name, strlen (group_name));
 }
 \f
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index 7a9d2e22403..725cab5d6fb 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -137,8 +137,7 @@ gdbpy_reggroup_to_string (PyObject *self)
   reggroup_object *group = (reggroup_object *) self;
   const reggroup *reggroup = group->reggroup;
 
-  const char *name = reggroup_name (reggroup);
-  return PyUnicode_FromString (name);
+  return PyUnicode_FromString (reggroup->name ());
 }
 
 /* Implement gdb.RegisterGroup.name (self) -> String.
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c
index 409a868be76..0c5da0e241d 100644
--- a/gdb/regcache-dump.c
+++ b/gdb/regcache-dump.c
@@ -196,8 +196,7 @@ class register_dump_groups : public register_dump
 	  {
 	    if (gdbarch_register_reggroup_p (m_gdbarch, regnum, group))
 	      {
-		gdb_printf (file,
-			    "%s%s", sep, reggroup_name (group));
+		gdb_printf (file, "%s%s", sep, group->name ());
 		sep = ",";
 	      }
 	  }
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index dfae60773bb..96d4ae4d1f8 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -28,33 +28,6 @@
 #include "gdbcmd.h"		/* For maintenanceprintlist.  */
 #include "gdbsupport/gdb_obstack.h"
 
-/* Individual register groups.  */
-
-struct reggroup
-{
-  /* Create a new register group object.  The NAME is not owned by the new
-     reggroup object, so must outlive the object.  */
-  reggroup (const char *name, enum reggroup_type type)
-    : m_name (name),
-      m_type (type)
-  { /* Nothing.  */ }
-
-  /* Return the name for this register group.  */
-  const char *name () const
-  { return m_name; }
-
-  /* Return the type of this register group.  */
-  enum reggroup_type type () const
-  { return m_type; }
-
-private:
-  /* The name of this register group.  */
-  const char *m_name;
-
-  /* The type of this register group.  */
-  enum reggroup_type m_type;
-};
-
 const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
@@ -72,20 +45,6 @@ reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name,
 				       name, type);
 }
 
-/* Register group attributes.  */
-
-const char *
-reggroup_name (const struct reggroup *group)
-{
-  return group->name ();
-}
-
-enum reggroup_type
-reggroup_type (const struct reggroup *group)
-{
-  return group->type ();
-}
-
 /* A container holding all the register groups for a particular
    architecture.  */
 
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index ec1d79dfc30..db5625a53bd 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -23,10 +23,36 @@
 #define REGGROUPS_H
 
 struct gdbarch;
-struct reggroup;
 
 enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP };
 
+/* Individual register group.  */
+
+struct reggroup
+{
+  /* Create a new register group object.  The NAME is not owned by the new
+     reggroup object, so must outlive the object.  */
+  reggroup (const char *name, enum reggroup_type type)
+    : m_name (name),
+      m_type (type)
+  { /* Nothing.  */ }
+
+  /* Return the name for this register group.  */
+  const char *name () const
+  { return m_name; }
+
+  /* Return the type of this register group.  */
+  enum reggroup_type type () const
+  { return m_type; }
+
+private:
+  /* The name of this register group.  */
+  const char *m_name;
+
+  /* The type of this register group.  */
+  enum reggroup_type m_type;
+};
+
 /* Pre-defined, user visible, register groups.  */
 extern const reggroup *const general_reggroup;
 extern const reggroup *const float_reggroup;
@@ -50,10 +76,6 @@ extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
 /* Add a register group (with attribute values) to the pre-defined list.  */
 extern void reggroup_add (struct gdbarch *gdbarch, const reggroup *group);
 
-/* Register group attributes.  */
-extern const char *reggroup_name (const struct reggroup *reggroup);
-extern enum reggroup_type reggroup_type (const struct reggroup *reggroup);
-
 /* Return the list of all register groups for GDBARCH.  */
 extern const std::vector<const reggroup *>
 	gdbarch_reggroups (struct gdbarch *gdbarch);
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 33277c3d02d..85954ac2939 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -1012,7 +1012,7 @@ tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
   struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
 
   if (reg != NULL && !reg->group.empty ()
-      && (reg->group == reggroup_name (reggroup)))
+      && (reg->group == reggroup->name ()))
 	return 1;
 
   if (reg != NULL
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index acffc75238a..2ee197fe192 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -216,7 +216,7 @@ tui_data_window::show_register_group (const reggroup *group,
   int regnum, pos;
 
   /* Make a new title showing which group we display.  */
-  title = string_printf ("Register group: %s", reggroup_name (group));
+  title = string_printf ("Register group: %s", group->name ());
 
   /* See how many registers must be displayed.  */
   nr_regs = 0;
@@ -595,7 +595,7 @@ tui_reg_command (const char *args, int from_tty)
 	     group then the switch is made.  */
 	  for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
 	    {
-	      if (strncmp (reggroup_name (group), args, len) == 0)
+	      if (strncmp (group->name (), args, len) == 0)
 		{
 		  if (match != NULL)
 		    error (_("ambiguous register group name '%s'"), args);
@@ -621,7 +621,7 @@ tui_reg_command (const char *args, int from_tty)
 	  if (!first)
 	    gdb_printf (", ");
 	  first = false;
-	  gdb_printf ("%s", reggroup_name (group));
+	  gdb_printf ("%s", group->name ());
 	}
 
       gdb_printf ("\n");
-- 
2.25.4


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

* [PATCHv2 16/16] gdb: update comments throughout reggroups.{c, h} files
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (14 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 15/16] gdb: move struct reggroup into reggroups.h header Andrew Burgess
@ 2022-04-06 12:04   ` Andrew Burgess
  2022-04-06 14:34   ` [PATCHv2 00/16] Default register groups, and general related cleanup Simon Marchi
  16 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Andrew Burgess

This commit updates the comments in the gdb/reggroups.{c,h} files.
Fill in some missing comments, correct a few comments that were not
clear, and where we had comments duplicated between .c and .h files,
update the .c to reference the .h.

No user visible changes after this commit.
---
 gdb/reggroups.c | 11 +++++++++--
 gdb/reggroups.h | 14 ++++++++++++--
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 96d4ae4d1f8..ef5e47e0986 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -28,6 +28,8 @@
 #include "gdbcmd.h"		/* For maintenanceprintlist.  */
 #include "gdbsupport/gdb_obstack.h"
 
+/* See reggroups.h.  */
+
 const reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
@@ -82,9 +84,11 @@ struct reggroups
   std::vector<const struct reggroup *> m_groups;
 };
 
+/* Key used to lookup register group data from a gdbarch.  */
+
 static struct gdbarch_data *reggroups_data;
 
-/* Add GROUP to the list of register groups for GDBARCH.  */
+/* See reggroups.h.  */
 
 void
 reggroup_add (struct gdbarch *gdbarch, const reggroup *group)
@@ -128,7 +132,8 @@ gdbarch_reggroups (struct gdbarch *gdbarch)
   return groups->groups ();
 }
 
-/* Is REGNUM a member of REGGROUP?  */
+/* See reggroups.h.  */
+
 int
 default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 			     const struct reggroup *group)
@@ -207,6 +212,8 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
     }
 }
 
+/* Implement 'maintenance print reggroups' command.  */
+
 static void
 maintenance_print_reggroups (const char *args, int from_tty)
 {
diff --git a/gdb/reggroups.h b/gdb/reggroups.h
index db5625a53bd..8aa9ad8c76f 100644
--- a/gdb/reggroups.h
+++ b/gdb/reggroups.h
@@ -24,7 +24,17 @@
 
 struct gdbarch;
 
-enum reggroup_type { USER_REGGROUP, INTERNAL_REGGROUP };
+/* The different register group types.  */
+enum reggroup_type {
+  /* Used for any register group that should be visible to the user.
+     Architecture specific register groups, as well as most of the default
+     groups will have this type.  */
+  USER_REGGROUP,
+
+  /* Used for a few groups that GDB uses while managing machine state.
+     These groups are mostly hidden from the user.  */
+  INTERNAL_REGGROUP
+};
 
 /* Individual register group.  */
 
@@ -73,7 +83,7 @@ extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
 					     const char *name,
 					     enum reggroup_type type);
 
-/* Add a register group (with attribute values) to the pre-defined list.  */
+/* Add a register group GROUP to the list of register groups for GDBARCH.  */
 extern void reggroup_add (struct gdbarch *gdbarch, const reggroup *group);
 
 /* Return the list of all register groups for GDBARCH.  */
-- 
2.25.4


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

* Re: [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev
  2022-04-05 23:11   ` Lancelot SIX
@ 2022-04-06 12:06     ` Andrew Burgess
  0 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-06 12:06 UTC (permalink / raw)
  To: Lancelot SIX; +Cc: gdb-patches

Lancelot SIX via Gdb-patches <gdb-patches@sourceware.org> writes:

>> diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
>> index b968947fa1c..65ec8241370 100644
>> --- a/gdb/tui/tui-regs.c
>> +++ b/gdb/tui/tui-regs.c
>> @@ -523,10 +523,21 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
>>  static const reggroup *
>>  tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
>>  {
>> -  const reggroup *group = reggroup_next (gdbarch, current_group);
>> -  if (group == NULL)
>> -    group = reggroup_next (gdbarch, NULL);
>> -  return group;
>> +  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
>> +
>> +  if (current_group != nullptr)
>> +    for (int i = 0; i < groups.size (); ++i)
>> +      {
>> +	if (groups[i] == current_group)
>> +	  {
>> +	    if (i + 1 < groups.size ())
>> +	      return groups[i + 1];
>> +	    else
>> +	      return groups.front ();
>> +	  }
>> +      }
>> +
>> +  return groups.front ();
>>  }
>>  
>>  /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
>> @@ -538,10 +549,27 @@ tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
>>  static const reggroup *
>>  tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
>>  {
>> -  const reggroup *group = reggroup_prev (gdbarch, current_group);
>> -  if (group == NULL)
>> -    group = reggroup_prev (gdbarch, NULL);
>> -  return group;
>> +  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
>> +
>> +  if (current_group != nullptr)
>> +    {
>> +      /* Iterate backwards.  */
>> +      for (auto iter = groups.rbegin ();
>> +	   iter != groups.rend ();
>> +	   ++iter)
>> +	{
>> +	  if (*iter == current_group)
>> +	    {
>> +	      ++iter;
>> +	      if (iter == groups.rend ())
>> +		return groups.back ();
>> +	      else
>> +		return *iter;
>> +	    }
>> +	}
>> +    }
>> +
>> +  return groups.back ();
>>  }
>>  
>
> Hi,
>
> It looks strange to have tui_reg_next implemented using iteration over
> indexes while tui_reg_prev is implemented using iterators.  It looks to
> me that both cases are similar enough to use a similar pattern.
>
> Also, the for loop can probably be replaced by a call to std::find which
> the overall thing more concise:
>
>     static const reggroup *
>     tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
>     {
>       const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
>       auto it = std::find (groups.rbegin (), groups.rend (), current_group);
>       it++;
>       if (it >= groups.rend ())
>         return groups.back ();
>       return *it;
>     }
>
> and something similar for tui_reg_next, changing rbegin/rend with
> begin/end and .back with .front.

That looks excellent.  Thanks.  I've included this change (to both _next
and _prev) in the v2 series I just posted.

Thanks,
Andrew


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

* Re: [PATCHv2 01/16] gdb: don't try to use readline before it's initialized
  2022-04-06 12:04   ` [PATCHv2 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
@ 2022-04-06 12:57     ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 12:57 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
> While working on a different patch, I triggered an assertion from the
> initialize_current_architecture code, specifically from one of
> the *_gdbarch_init functions in a *-tdep.c file.  This exposes a
> couple of issues with GDB.
> 
> This is easy enough to reproduce by adding 'gdb_assert (false)' into a
> suitable function.  For example, I added a line into i386_gdbarch_init
> and can see the following issue.
> 
> I start GDB and immediately hit the assert, the output is as you'd
> expect, except for the very last line:
> 
>   $ ./gdb/gdb --data-directory ./gdb/data-directory/
>   ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.
>   A problem internal to GDB has been detected,
>   further debugging may prove unreliable.
>   ----- Backtrace -----
>   ... snip ...
>   ---------------------
>   ../../src.dev-1/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.
>   A problem internal to GDB has been detected,
>   further debugging may prove unreliable.
>   Quit this debugging session? (y or n) ../../src.dev-1/gdb/ser-event.c:212:16: runtime error: member access within null pointer of type 'struct serial'
> 
> Something goes wrong when we try to query the user.  Note, I
> configured GDB with --enable-ubsan, I suspect that without this the
> above "error" would actually just be a crash.
> 
> The backtrace from ser-event.c:212 looks like this:
> 
>   (gdb) bt 10
>   #0  serial_event_clear (event=0x675c020) at ../../src/gdb/ser-event.c:212
>   #1  0x0000000000769456 in invoke_async_signal_handlers () at ../../src/gdb/async-event.c:211
>   #2  0x000000000295049b in gdb_do_one_event () at ../../src/gdbsupport/event-loop.cc:194
>   #3  0x0000000001f015f8 in gdb_readline_wrapper (
>       prompt=0x67135c0 "../../src/gdb/i386-tdep.c:8455: internal-error: i386_gdbarch_init: Assertion `false' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugg"...)
>       at ../../src/gdb/top.c:1141
>   #4  0x0000000002118b64 in defaulted_query(const char *, char, typedef __va_list_tag __va_list_tag *) (
>       ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ", defchar=0 '\000', args=0x7fffffffa6e0)
>       at ../../src/gdb/utils.c:934
>   #5  0x0000000002118f72 in query (ctlstr=0x2e4eb68 "%s\nQuit this debugging session? ")
>       at ../../src/gdb/utils.c:1026
>   #6  0x00000000021170f6 in internal_vproblem(internal_problem *, const char *, int, const char *, typedef __va_list_tag __va_list_tag *) (problem=0x6107bc0 <internal_error_problem>, file=0x2b976c8 "../../src/gdb/i386-tdep.c",
>       line=8455, fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:417
>   #7  0x00000000021175a0 in internal_verror (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455,
>       fmt=0x2b96d7f "%s: Assertion `%s' failed.", ap=0x7fffffffa8e8) at ../../src/gdb/utils.c:485
>   #8  0x00000000029503b3 in internal_error (file=0x2b976c8 "../../src/gdb/i386-tdep.c", line=8455,
>       fmt=0x2b96d7f "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:55
>   #9  0x000000000122d5b6 in i386_gdbarch_init (info=..., arches=0x0) at ../../src/gdb/i386-tdep.c:8455
>   (More stack frames follow...)
> 
> It turns out that the problem is that the async event handler
> mechanism has been invoked, but this has not yet been initialized.
> 
> If we look at gdb_init (in gdb/top.c) we can indeed see the call to
> gdb_init_signals is after the call to initialize_current_architecture.
> 
> If I reorder the calls, moving gdb_init_signals earlier, then the
> initial error is resolved, however, things are still broken.  I now
> see the same "Quit this debugging session? (y or n)" prompt, but when
> I provide an answer and press return GDB immediately crashes.
> 
> So what's going on now?  The next problem is that the call_readline
> field within the current_ui structure is not initialized, and this
> callback is invoked to process the reply I entered.
> 
> The problem is that call_readline is setup as a result of calling
> set_top_level_interpreter, which is called from captured_main_1.
> Unfortunately, set_top_level_interpreter is called after gdb_init is
> called.
> 
> I wondered how to solve this problem for a while, however, I don't
> know if there's an easy "just reorder some lines" solution here.
> Looking through captured_main_1 there seems to be a bunch of
> dependencies between printing various things, parsing config files,
> and setting up the interpreter.  I'm sure there is a solution hiding
> in there somewhere.... I'm just not sure I want to spend any longer
> looking for it.
> 
> So.
> 
> I propose a simpler solution, more of a hack/work-around.  In utils.c
> we already have a function filtered_printing_initialized, this is
> checked in a few places within internal_vproblem.  In some of these
> cases the call gates whether or not GDB will query the user.
> 
> My proposal is to add a new readline_initialized function, which
> checks if the current_ui has had readline initialized yet.  If this is
> not the case then we should not attempt to query the user.
> 
> After this change GDB prints the error message, the backtrace, and
> then aborts (including dumping core).  This actually seems pretty sane
> as, if GDB has not yet made it through the initialization then it
> doesn't make much sense to allow the user to say "no, I don't want to
> quit the debug session" (I think).

I think this is reasonable.  In theory, the internal error could be for
something you don't care about, and you could still want to continue.
But there's also a limit to the far-fetched theoritical scenarios we
must support.  So I think it is ok to say that any internal error during
initialization is fatal.  The patch LGTM.

Simon

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

* Re: [PATCHv2 02/16] gdb: add some const in gdb/reggroups.c
  2022-04-06 12:04   ` [PATCHv2 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
@ 2022-04-06 12:58     ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 12:58 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches



On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
> This commit makes the 'struct reggroup *' argument const for the
> following functions:
> 
>   reggroup_next
>   reggroup_prev
>   reggroup_name
>   reggroup_type
> 
> There are other places that could benefit from const in the
> reggroup.{c,h} files, but these will be changing in further commits.
> 
> There should be no user visible changes after this commit.

LGTM.

Simon

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

* Re: [PATCHv2 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command
  2022-04-06 12:04   ` [PATCHv2 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
@ 2022-04-06 13:02     ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 13:02 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches



On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
> While looking at the 'tui reg' command as part of another patch, I
> spotted a theoretical bug.
> 
> The 'tui reg' command takes the name of a register group, but also
> handles partial register group matches, though the partial match has to
> be unique.  The current command logic goes:
> 
> With the code as currently written, if a target description named a
> register group either 'prev' or 'next' then GDB would see this as an
> ambiguous register name, and refuse to switch groups.
> 
> Naming a register group 'prev' or 'next' seems pretty unlikely, but,
> by adding a single else block we can prevent this problem.
> 
> Now, if there's a 'prev' or 'next' register group, the user will not
> be able to select the group directly, the 'prev' and 'next' names will
> always iterate through the available groups instead.  But at least the
> user could select their groups by iteration, rather than direct
> selection.

This looks ok to me.  All previous patches also look ok, but I didn't
reply to each one, since they are mostly obvious.

Simon

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

* Re: [PATCHv2 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden
  2022-04-06 12:04   ` [PATCHv2 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
@ 2022-04-06 13:13     ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 13:13 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches



On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
> Start GDB like:
> 
>   $ gdb -q executable
>   (gdb) start
>   (gdb) layout src
>   ... tui windows are now displayed ...
>   (gdb) tui reg next
> 
> At this point the data (register) window should be displayed, but will
> contain the message 'Register Values Unavailable', and at the console
> you'll see the message "unknown register group 'next'".
> 
> The same happens with 'tui reg prev' (but the error message is
> slightly different).
> 
> At this point you can continue to use 'tui reg next' and/or 'tui reg
> prev' and you'll keep getting the error message.
> 
> The problem is that when the data (register) window is first
> displayed, it's current register group is nullptr.  As a consequence
> tui_reg_next and tui_reg_prev (tui/tui-regs.c) will always just return
> nullptr, which triggers an error in tui_reg_command.
> 
> In this commit I change tui_reg_next and tui_reg_prev so that they
> instead return the first and last register group respectively if the
> current register group is nullptr.
> 
> So, after this, using 'tui reg next' will (in the above case) show the
> first register group, while 'tui reg prev' will display the last
> register group.

I don't have a strong opinion on this, but my understanding of the
current code is that tui_reg_next / tui_reg_prev expect that if the
reg window is displayed, there is a current group.  So one fix could
also be to make sure the tui_regs_layout call selects an initial
reggroup, and then tui_reg_next / tui_reg_prev would work as expected.

Hmm however, that would give a slightly different behavior.  When the
tui reg window is not shown and you do "tui reg next", which register
group do you want to show?  With your solution, we will show the first
group.  With my proposal, we would show the second.  I think that
showing the first group makes more sense, so I agree with your solution
actually.

But then I wonder if "tui reg prev" should behave the same, show the
first group.  Not really important though, I doubt that anybody will
ever care much about that detail in the behavior of the "tui reg prev"
command.

The patch LGTM.

Simon

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

* Re: [PATCHv2 09/16] gdb: always add the default register groups
  2022-04-06 12:04   ` [PATCHv2 09/16] gdb: always add the default register groups Andrew Burgess
@ 2022-04-06 13:22     ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 13:22 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches



On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
> There's a set of 7 default register groups.  If we don't add any
> gdbarch specific register groups during gdbarch initialisation, then
> when we iterate over the register groups using reggroup_next and
> reggroup_prev we will make use of these 7 default groups.  See the use
> of default_groups in gdb/reggroups.c for details on this.
> 
> However, if the gdbarch adds its own groups during gdbarch
> initialisation, then these groups will be used in preference to the
> default groups.
> 
> A problem arises though if the particular architecture makes use of
> the target description mechanism.  If the default target
> description(s) (i.e. those internal to GDB that are used when the user
> doesn't provide their own) don't mention any additional register
> groups then the default register groups will be used.
> 
> But if the target description does mention additional groups then the
> default groups are not used, and instead, the groups from the target
> description are used.
> 
> The problem with this is that what usually happens is that the target
> description will mention additional groups, e.g. groups for special
> registers.  Most architectures that use target descriptions work
> around this by adding all (or most) of the default register groups in
> all cases.  See i386_add_reggroups, aarch64_add_reggroups,
> riscv_add_reggroups, xtensa_add_reggroups, and others.
> 
> In this patch, my suggestion is that we should just add the default
> register groups for every architecture, always.  This change is in
> gdb/reggroups.c.
> 
> All the remaining changes are me updating the various architectures to
> not add the default groups themselves.
> 
> So, where will this change be visible to the user?  I think the
> following commands will possibly change:
> 
> * info registers / info all-registers:
> 
>   The user can provide a register group to these commands.  For example,
>   on csky, we previously never added the 'vector' group.  Now, as a
>   default group, this will be available, but (presumably) will not
>   contain any registers.  I don't think this is necessarily a bad
>   thing, there's something to be said for having some consistent
>   defaults available.  There are other architectures that didn't add
>   all 7 of the defaults, which will now have gained additional groups.
> 
> * maint print reggroups
> 
>   This prints the set of all available groups.  As a maintenance
>   command I'm less concerned with the output changing here.
>   Obviously, for the architectures that didn't previously add all the
>   defaults, this list just got bigger.
> 
> * maint print register-groups
> 
>   This prints all the registers, and the groups they are in.  If the
>   defaults were not previously being added then a register (obviously)
>   can't appear in one of the default groups.  Now the groups are
>   available then registers might be in more groups than previously.
>   However, this is again a maintenance command, so I'm less concerned
>   about this changing.

That sounds reasonable to me.

> @@ -119,13 +110,44 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
>    struct reggroups *groups
>      = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
>  
> +  /* The same reggroup should not be added multiple times.  */
> +  gdb_assert (groups != nullptr);
> +  for (struct reggroup_el *el = groups->first;
> +       el != nullptr;
> +       el = el->next)
> +    gdb_assert (group != el->group);

The "for" can be on a single line.

Simon

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

* Re: [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev
  2022-04-06 12:04   ` [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
@ 2022-04-06 14:22     ` Simon Marchi
  2022-04-06 14:23       ` Simon Marchi
  0 siblings, 1 reply; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 14:22 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

> @@ -146,62 +146,15 @@ reggroups_init (struct obstack *obstack)
>    return groups;
>  }
>  
> -/* A register group iterator.  */
> -
> -struct reggroup *
> -reggroup_next (struct gdbarch *gdbarch, const struct reggroup *last)
> -{
> -  /* Don't allow this function to be called during architecture
> -     creation.  If there are no groups, use the default groups list.  */
> -  struct reggroups *groups
> -    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
> -  gdb_assert (groups != nullptr);
> -  gdb_assert (groups->size () > 0);
> -
> -  /* Return the first/next reggroup.  */
> -  if (last == nullptr)
> -    return groups->groups ().front ();
> -  for (int i = 0; i < groups->size (); ++i)
> -    {
> -      if (groups->groups ()[i] == last)
> -	{
> -	  if (i + 1 < groups->size ())
> -	    return groups->groups ()[i + 1];
> -	  else
> -	    return nullptr;
> -	}
> -    }
> -
> -  return nullptr;
> -}
> -
>  /* See reggroups.h.  */
> -
> -struct reggroup *
> -reggroup_prev (struct gdbarch *gdbarch, const struct reggroup *curr)
> +const std::vector<const reggroup *>
> +gdbarch_reggroups (struct gdbarch *gdbarch)

Should this return a reference to the existing vector, so it doesn't
make a copy of the vector each time?

> diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
> index b968947fa1c..acffc75238a 100644
> --- a/gdb/tui/tui-regs.c
> +++ b/gdb/tui/tui-regs.c
> @@ -514,34 +514,48 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
>      (void) wstandend (handle);
>  }
>  
> -/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
> -   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
> -   nullptr (e.g. if the tui register window has only just been displayed
> -   and has no current group selected), then the first register group will
> -   be returned.  */
> +/* Helper for "tui reg next", returns the next register group after
> +   CURRENT_GROUP in the register group list for GDBARCH, with wrap around
> +   behaviour.
> +
> +   If CURRENT_GROUP is nullptr (e.g. if the tui register window has only
> +   just been displayed and has no current group selected) or the currently
> +   selected register group can't be found (e.g. if the architecture has
> +   changed since the register window was last updated), then the last
> +   register group will be returned.  */

last or next?  This is for tui_reg_next.

>  
>  static const reggroup *
>  tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
>  {
> -  const reggroup *group = reggroup_next (gdbarch, current_group);
> -  if (group == NULL)
> -    group = reggroup_next (gdbarch, NULL);
> -  return group;
> +  const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
> +  auto it = std::find (groups.begin (), groups.end (), current_group);
> +  if (it != groups.end ())
> +    it++;
> +  if (it == groups.end ())
> +    return groups.front ();
> +  return *it;

My only thought for the conversion to vector is that using an
intrusive_list would be a nice lightweight solution for those next/prev
cases.  You wouldn't have to iterate the vector to find the current
reggroup, to find the one after it.  However, it would probably not
handle the "if the architecture has changed since the register window
was last updated case", where you want to check if the current group is
part of gdbarch's reggroups.  When the current architecture changes
though, I think it should trigger an update of the register window to
show that new architecture's registers so... maybe we don't need this
check?


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

* Re: [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev
  2022-04-06 14:22     ` Simon Marchi
@ 2022-04-06 14:23       ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 14:23 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

>> diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
>> index b968947fa1c..acffc75238a 100644
>> --- a/gdb/tui/tui-regs.c
>> +++ b/gdb/tui/tui-regs.c
>> @@ -514,34 +514,48 @@ tui_data_item_window::rerender (WINDOW *handle, int field_width)
>>      (void) wstandend (handle);
>>  }
>>  
>> -/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
>> -   around behaviour.  Will never return nullptr.  If CURRENT_GROUP is
>> -   nullptr (e.g. if the tui register window has only just been displayed
>> -   and has no current group selected), then the first register group will
>> -   be returned.  */
>> +/* Helper for "tui reg next", returns the next register group after
>> +   CURRENT_GROUP in the register group list for GDBARCH, with wrap around
>> +   behaviour.
>> +
>> +   If CURRENT_GROUP is nullptr (e.g. if the tui register window has only
>> +   just been displayed and has no current group selected) or the currently
>> +   selected register group can't be found (e.g. if the architecture has
>> +   changed since the register window was last updated), then the last
>> +   register group will be returned.  */
> 
> last or next?  This is for tui_reg_next.

Sorry I meant "last or first".

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

* Re: [PATCH 16/16] gdb: update comments throughout reggroups.{c,h} files
  2022-03-31 21:04 ` [PATCH 16/16] gdb: update comments throughout reggroups.{c,h} files Andrew Burgess
@ 2022-04-06 14:28   ` Simon Marchi
  0 siblings, 0 replies; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 14:28 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

> @@ -73,7 +83,7 @@ extern const reggroup *reggroup_gdbarch_new (struct gdbarch *gdbarch,
>  					     const char *name,
>  					     enum reggroup_type type);
>  
> -/* Add a register group (with attribute values) to the pre-defined list.  */
> +/* Add a register group GROUP to the list of register groups for GDBARCH.  */

Just a nit: I would remove the indefinite article "a", since you are now
referring to a specific register group.

Simon

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

* Re: [PATCHv2 00/16] Default register groups, and general related cleanup
  2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
                     ` (15 preceding siblings ...)
  2022-04-06 12:04   ` [PATCHv2 16/16] gdb: update comments throughout reggroups.{c, h} files Andrew Burgess
@ 2022-04-06 14:34   ` Simon Marchi
  2022-04-07 15:16     ` Andrew Burgess
  16 siblings, 1 reply; 48+ messages in thread
From: Simon Marchi @ 2022-04-06 14:34 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
> This work started with this thread:
> 
>   https://sourceware.org/pipermail/gdb-patches/2022-March/187071.html
> 
> In which it was discovered that the ppc targets don't add the default
> register groups during gdbarch initialisation.
> 
> I've run into this problem before, and every time I wonder why the
> default register groups aren't added by default in all cases.
> 
> So, looked at doing just that.
> 
> But the register group management code was feeling a bit crusty, so I
> thought I'd clean it up.
> 
> Then I hit some bugs, which I figured I'd fix.
> 
> Anyway, patch #9 is what I set out to do.  Everything else is me
> trying to improve the register group handling code.
> 
> Changes in v2:
> 
>   - Rebased onto current master, the changes I make to
>     gdb.tui/regs.exp in one of the patches needed some small
>     adjustments given recent tui changes,
> 
>   - Updated patch #11 based on Lancelot's feedback, this looks much
>     better now.

Other than the small nits I pointed out, this all LGTM.  I left a
comment about maybe using intrusive_list instead of std::vector, if that
could simplify things.  But if so, it can be done later / after this
series is merged.

Thanks,

Simon

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

* Re: [PATCHv2 00/16] Default register groups, and general related cleanup
  2022-04-06 14:34   ` [PATCHv2 00/16] Default register groups, and general related cleanup Simon Marchi
@ 2022-04-07 15:16     ` Andrew Burgess
  0 siblings, 0 replies; 48+ messages in thread
From: Andrew Burgess @ 2022-04-07 15:16 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

> On 2022-04-06 08:04, Andrew Burgess via Gdb-patches wrote:
>> This work started with this thread:
>> 
>>   https://sourceware.org/pipermail/gdb-patches/2022-March/187071.html
>> 
>> In which it was discovered that the ppc targets don't add the default
>> register groups during gdbarch initialisation.
>> 
>> I've run into this problem before, and every time I wonder why the
>> default register groups aren't added by default in all cases.
>> 
>> So, looked at doing just that.
>> 
>> But the register group management code was feeling a bit crusty, so I
>> thought I'd clean it up.
>> 
>> Then I hit some bugs, which I figured I'd fix.
>> 
>> Anyway, patch #9 is what I set out to do.  Everything else is me
>> trying to improve the register group handling code.
>> 
>> Changes in v2:
>> 
>>   - Rebased onto current master, the changes I make to
>>     gdb.tui/regs.exp in one of the patches needed some small
>>     adjustments given recent tui changes,
>> 
>>   - Updated patch #11 based on Lancelot's feedback, this looks much
>>     better now.
>
> Other than the small nits I pointed out, this all LGTM.  I left a
> comment about maybe using intrusive_list instead of std::vector, if that
> could simplify things.  But if so, it can be done later / after this
> series is merged.

Thanks for the review.  I addressed the feedback, but left the
std::vector / intrusive_list stuff for now.  This certainly isn't hot
path code, and the vector version just seemed simpler (to me).  But if
you're keen to change it, then I'm not going to object.

Thanks,
Andrew


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

end of thread, other threads:[~2022-04-07 15:16 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-31 21:04 [PATCH 00/16] Default register groups, and general related cleanup Andrew Burgess
2022-03-31 21:04 ` [PATCH 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
2022-03-31 21:04 ` [PATCH 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
2022-03-31 21:04 ` [PATCH 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
2022-04-04 22:35   ` Lancelot SIX
2022-04-05  8:24     ` Andrew Burgess
2022-03-31 21:04 ` [PATCH 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h} Andrew Burgess
2022-03-31 21:04 ` [PATCH 05/16] gdb: use 'const reggroup *' in python/py-registers.c file Andrew Burgess
2022-03-31 21:04 ` [PATCH 06/16] gdb: have reggroup_find return a const Andrew Burgess
2022-03-31 21:04 ` [PATCH 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
2022-03-31 21:04 ` [PATCH 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
2022-03-31 21:04 ` [PATCH 09/16] gdb: always add the default register groups Andrew Burgess
2022-03-31 21:04 ` [PATCH 10/16] gdb: convert reggroups to use a std::vector Andrew Burgess
2022-03-31 21:04 ` [PATCH 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
2022-04-05 23:11   ` Lancelot SIX
2022-04-06 12:06     ` Andrew Burgess
2022-03-31 21:04 ` [PATCH 12/16] gdb: more 'const' in gdb/reggroups.{c,h} Andrew Burgess
2022-03-31 21:04 ` [PATCH 13/16] gdb: make the pre-defined register groups const Andrew Burgess
2022-03-31 21:04 ` [PATCH 14/16] gdb: convert reggroup to a C++ class with constructor, etc Andrew Burgess
2022-03-31 21:04 ` [PATCH 15/16] gdb: move struct reggroup into reggroups.h header Andrew Burgess
2022-03-31 21:04 ` [PATCH 16/16] gdb: update comments throughout reggroups.{c,h} files Andrew Burgess
2022-04-06 14:28   ` Simon Marchi
2022-04-06 12:04 ` [PATCHv2 00/16] Default register groups, and general related cleanup Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 01/16] gdb: don't try to use readline before it's initialized Andrew Burgess
2022-04-06 12:57     ` Simon Marchi
2022-04-06 12:04   ` [PATCHv2 02/16] gdb: add some const in gdb/reggroups.c Andrew Burgess
2022-04-06 12:58     ` Simon Marchi
2022-04-06 12:04   ` [PATCHv2 03/16] gdb: make gdbarch_register_reggroup_p take a const reggroup * Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 04/16] gdb: switch to using 'const reggroup *' in tui-regs.{c, h} Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 05/16] gdb: use 'const reggroup *' in python/py-registers.c file Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 06/16] gdb: have reggroup_find return a const Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 07/16] gdb/tui: avoid theoretical bug with 'tui reg' command Andrew Burgess
2022-04-06 13:02     ` Simon Marchi
2022-04-06 12:04   ` [PATCHv2 08/16] gdb/tui: fix 'tui reg next/prev' command when data window is hidden Andrew Burgess
2022-04-06 13:13     ` Simon Marchi
2022-04-06 12:04   ` [PATCHv2 09/16] gdb: always add the default register groups Andrew Burgess
2022-04-06 13:22     ` Simon Marchi
2022-04-06 12:04   ` [PATCHv2 10/16] gdb: convert reggroups to use a std::vector Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 11/16] gdb: remove reggroup_next and reggroup_prev Andrew Burgess
2022-04-06 14:22     ` Simon Marchi
2022-04-06 14:23       ` Simon Marchi
2022-04-06 12:04   ` [PATCHv2 12/16] gdb: more 'const' in gdb/reggroups.{c,h} Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 13/16] gdb: make the pre-defined register groups const Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 14/16] gdb: convert reggroup to a C++ class with constructor, etc Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 15/16] gdb: move struct reggroup into reggroups.h header Andrew Burgess
2022-04-06 12:04   ` [PATCHv2 16/16] gdb: update comments throughout reggroups.{c, h} files Andrew Burgess
2022-04-06 14:34   ` [PATCHv2 00/16] Default register groups, and general related cleanup Simon Marchi
2022-04-07 15:16     ` Andrew Burgess

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).