Add dwarf2_per_objfile parameter to allocate_piece_closure
[deliverable/binutils-gdb.git] / gdb / reggroups.c
index ea9a9ec921e2fc839b5ea4f8907765c373362cba..83d7b49e330b9424eb93ea6694e52ca68d5407ca 100644 (file)
@@ -1,6 +1,6 @@
 /* Register groupings for GDB, the GNU debugger.
 
-   Copyright 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002-2020 Free Software Foundation, Inc.
 
    Contributed by Red Hat.
 
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include "reggroups.h"
 #include "gdbtypes.h"
-#include "gdb_assert.h"
 #include "regcache.h"
 #include "command.h"
 #include "gdbcmd.h"            /* For maintenanceprintlist.  */
+#include "gdb_obstack.h"
 
 /* Individual register groups.  */
 
@@ -40,12 +39,27 @@ struct reggroup
 struct reggroup *
 reggroup_new (const char *name, enum reggroup_type type)
 {
-  struct reggroup *group = XMALLOC (struct reggroup);
+  struct reggroup *group = XNEW (struct reggroup);
+
   group->name = name;
   group->type = type;
   return group;
 }
 
+/* See reggroups.h.  */
+
+struct 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;
+}
+
 /* Register group attributes.  */
 
 const char *
@@ -60,78 +74,117 @@ reggroup_type (struct reggroup *group)
   return group->type;
 }
 
-/* All the groups for a given architecture.  */
+/* A linked list of groups for the given architecture.  */
+
+struct reggroup_el
+{
+  struct reggroup *group;
+  struct reggroup_el *next;
+};
 
 struct reggroups
 {
-  int nr_group;
-  struct reggroup **group;
+  struct reggroup_el *first;
+  struct reggroup_el **last;
 };
 
 static struct gdbarch_data *reggroups_data;
 
 static void *
-reggroups_init (struct gdbarch *gdbarch)
+reggroups_init (struct obstack *obstack)
 {
-  struct reggroups *groups = XMALLOC (struct reggroups);
-  groups->nr_group = 0;
-  groups->group = NULL;
-  return groups;
-}
+  struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups);
 
-static void
-reggroups_free (struct gdbarch *gdbarch, void *data)
-{
-  struct reggroups *groups = data;
-  xfree (groups->group);
-  xfree (groups);
+  groups->last = &groups->first;
+  return groups;
 }
 
 /* Add a register group (with attribute values) to the pre-defined
-   list.  This function can be called during architecture
-   initialization and hence needs to handle NULL architecture groups.  */
+   list.  */
 
 static void
-add_group (struct reggroups *groups, struct reggroup *group)
+add_group (struct reggroups *groups, struct reggroup *group,
+          struct reggroup_el *el)
 {
   gdb_assert (group != NULL);
-  groups->nr_group++;
-  groups->group = xrealloc (groups->group, (sizeof (struct reggroup *)
-                                           * (groups->nr_group + 1)));
-  groups->group[groups->nr_group - 1] = group;
-  groups->group[groups->nr_group] = NULL;
+  el->group = group;
+  el->next = NULL;
+  (*groups->last) = el;
+  groups->last = &el->next;
 }
 
 void
 reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
 {
-  struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
-  if (groups == NULL)
+  struct reggroups *groups
+    = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data);
+
+  add_group (groups, group,
+            GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
+}
+
+/* The default register groups for an architecture.  */
+
+static struct reggroups default_groups = { NULL, &default_groups.first };
+
+/* A register group iterator.  */
+
+struct reggroup *
+reggroup_next (struct gdbarch *gdbarch, 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);
+  if (groups->first == NULL)
+    groups = &default_groups;
+
+  /* Return the first/next reggroup.  */
+  if (last == NULL)
+    return groups->first->group;
+  for (el = groups->first; el != NULL; el = el->next)
     {
-      /* ULGH, called during architecture initialization.  Patch
-         things up.  */
-      groups = reggroups_init (gdbarch);
-      set_gdbarch_data (gdbarch, reggroups_data, groups);
+      if (el->group == last)
+       {
+         if (el->next != NULL)
+           return el->next->group;
+         else
+           return NULL;
+       }
     }
-  add_group (groups, group);
+  return NULL;
 }
 
-/* The register groups for the current architecture.  Mumble something
-   about the lifetime of the buffer....  */
-
-static struct reggroups *default_groups;
+/* See reggroups.h.  */
 
-struct reggroup * const*
-reggroups (struct gdbarch *gdbarch)
+struct reggroup *
+reggroup_prev (struct gdbarch *gdbarch, struct reggroup *curr)
 {
-  struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
+  struct reggroups *groups;
+  struct reggroup_el *el;
+  struct reggroup *prev;
+
   /* Don't allow this function to be called during architecture
-     creation.  */
+     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->group == NULL)
-    return default_groups->group;
-  else
-    return groups->group;
+  if (groups->first == NULL)
+    groups = &default_groups;
+
+  prev = NULL;
+  for (el = groups->first; el != NULL; el = el->next)
+    {
+      gdb_assert (el->group != NULL);
+      if (el->group == curr)
+       return prev;
+      prev = el->group;
+    }
+  if (curr == NULL)
+    return prev;
+  return NULL;
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -142,16 +195,17 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   int vector_p;
   int float_p;
   int raw_p;
-  if (REGISTER_NAME (regnum) == NULL
-      || *REGISTER_NAME (regnum) == '\0')
+
+  if (gdbarch_register_name (gdbarch, regnum) == NULL
+      || *gdbarch_register_name (gdbarch, regnum) == '\0')
     return 0;
   if (group == all_reggroup)
     return 1;
   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
-  float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
-  /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
-     (gdbarch), as not all architectures are multi-arch.  */
-  raw_p = regnum < NUM_REGS;
+  float_p = (register_type (gdbarch, regnum)->code () == TYPE_CODE_FLT
+            || (register_type (gdbarch, regnum)->code ()
+                == TYPE_CODE_DECFLOAT));
+  raw_p = regnum < gdbarch_num_regs (gdbarch);
   if (group == float_reggroup)
     return float_p;
   if (group == vector_reggroup)
@@ -163,33 +217,52 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   return 0;   
 }
 
+/* See reggroups.h.  */
+
+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))
+    {
+      if (strcmp (name, reggroup_name (group)) == 0)
+       return group;
+    }
+  return NULL;
+}
+
 /* Dump out a table of register groups for the current architecture.  */
 
 static void
 reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct reggroup *const *groups = reggroups (gdbarch);
-  int i = -1;
+  struct reggroup *group = NULL;
+
   do
     {
       /* Group name.  */
       {
        const char *name;
-       if (i < 0)
+
+       if (group == NULL)
          name = "Group";
        else
-         name = reggroup_name (groups[i]);
+         name = reggroup_name (group);
        fprintf_unfiltered (file, " %-10s", name);
       }
       
       /* Group type.  */
       {
        const char *type;
-       if (i < 0)
+
+       if (group == NULL)
          type = "Type";
        else
          {
-           switch (reggroup_type (groups[i]))
+           switch (reggroup_type (group))
              {
              case USER_REGGROUP:
                type = "user";
@@ -198,7 +271,7 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
                type = "internal";
                break;
              default:
-               internal_error (__FILE__, __LINE__, "bad switch");
+               internal_error (__FILE__, __LINE__, _("bad switch"));
              }
          }
        fprintf_unfiltered (file, " %-10s", type);
@@ -208,23 +281,26 @@ reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
          documentation.  */
       
       fprintf_unfiltered (file, "\n");
-      i++;
+
+      group = reggroup_next (gdbarch, group);
     }
-  while (groups[i] != NULL);
+  while (group != NULL);
 }
 
 static void
-maintenance_print_reggroups (char *args, int from_tty)
+maintenance_print_reggroups (const char *args, int from_tty)
 {
+  struct gdbarch *gdbarch = get_current_arch ();
+
   if (args == NULL)
-    reggroups_dump (current_gdbarch, gdb_stdout);
+    reggroups_dump (gdbarch, gdb_stdout);
   else
     {
-      struct ui_file *file = gdb_fopen (args, "w");
-      if (file == NULL)
-       perror_with_name ("maintenance print reggroups");
-      reggroups_dump (current_gdbarch, file);    
-      ui_file_delete (file);
+      stdio_file file;
+
+      if (!file.open (args, "w"))
+       perror_with_name (_("maintenance print reggroups"));
+      reggroups_dump (gdbarch, &file);
     }
 }
 
@@ -245,28 +321,25 @@ struct reggroup *const all_reggroup = &all_group;
 struct reggroup *const save_reggroup = &save_group;
 struct reggroup *const restore_reggroup = &restore_group;
 
-extern initialize_file_ftype _initialize_reggroup; /* -Wmissing-prototypes */
-
+void _initialize_reggroup ();
 void
-_initialize_reggroup (void)
+_initialize_reggroup ()
 {
-  reggroups_data = register_gdbarch_data (reggroups_init, reggroups_free);
+  reggroups_data = gdbarch_data_register_pre_init (reggroups_init);
 
   /* The pre-defined list of groups.  */
-  default_groups = reggroups_init (NULL);
-  add_group (default_groups, general_reggroup);
-  add_group (default_groups, float_reggroup);
-  add_group (default_groups, system_reggroup);
-  add_group (default_groups, vector_reggroup);
-  add_group (default_groups, all_reggroup);
-  add_group (default_groups, save_reggroup);
-  add_group (default_groups, restore_reggroup);
-
+  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, "\
+          maintenance_print_reggroups, _("\
 Print the internal register group names.\n\
-Takes an optional file parameter.",
+Takes an optional file parameter."),
           &maintenanceprintlist);
 
 }
This page took 0.028173 seconds and 4 git commands to generate.