xref: /dflybsd-src/contrib/gdb-7/gdb/reggroups.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Register groupings for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 2002-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    Contributed by Red Hat.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "arch-utils.h"
245796c8dcSSimon Schubert #include "reggroups.h"
255796c8dcSSimon Schubert #include "gdbtypes.h"
265796c8dcSSimon Schubert #include "gdb_assert.h"
275796c8dcSSimon Schubert #include "regcache.h"
285796c8dcSSimon Schubert #include "command.h"
295796c8dcSSimon Schubert #include "gdbcmd.h"		/* For maintenanceprintlist.  */
305796c8dcSSimon Schubert 
315796c8dcSSimon Schubert /* Individual register groups.  */
325796c8dcSSimon Schubert 
335796c8dcSSimon Schubert struct reggroup
345796c8dcSSimon Schubert {
355796c8dcSSimon Schubert   const char *name;
365796c8dcSSimon Schubert   enum reggroup_type type;
375796c8dcSSimon Schubert };
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert struct reggroup *
reggroup_new(const char * name,enum reggroup_type type)405796c8dcSSimon Schubert reggroup_new (const char *name, enum reggroup_type type)
415796c8dcSSimon Schubert {
425796c8dcSSimon Schubert   struct reggroup *group = XMALLOC (struct reggroup);
43cf7f2e2dSJohn Marino 
445796c8dcSSimon Schubert   group->name = name;
455796c8dcSSimon Schubert   group->type = type;
465796c8dcSSimon Schubert   return group;
475796c8dcSSimon Schubert }
485796c8dcSSimon Schubert 
495796c8dcSSimon Schubert /* Register group attributes.  */
505796c8dcSSimon Schubert 
515796c8dcSSimon Schubert const char *
reggroup_name(struct reggroup * group)525796c8dcSSimon Schubert reggroup_name (struct reggroup *group)
535796c8dcSSimon Schubert {
545796c8dcSSimon Schubert   return group->name;
555796c8dcSSimon Schubert }
565796c8dcSSimon Schubert 
575796c8dcSSimon Schubert enum reggroup_type
reggroup_type(struct reggroup * group)585796c8dcSSimon Schubert reggroup_type (struct reggroup *group)
595796c8dcSSimon Schubert {
605796c8dcSSimon Schubert   return group->type;
615796c8dcSSimon Schubert }
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert /* A linked list of groups for the given architecture.  */
645796c8dcSSimon Schubert 
655796c8dcSSimon Schubert struct reggroup_el
665796c8dcSSimon Schubert {
675796c8dcSSimon Schubert   struct reggroup *group;
685796c8dcSSimon Schubert   struct reggroup_el *next;
695796c8dcSSimon Schubert };
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert struct reggroups
725796c8dcSSimon Schubert {
735796c8dcSSimon Schubert   struct reggroup_el *first;
745796c8dcSSimon Schubert   struct reggroup_el **last;
755796c8dcSSimon Schubert };
765796c8dcSSimon Schubert 
775796c8dcSSimon Schubert static struct gdbarch_data *reggroups_data;
785796c8dcSSimon Schubert 
795796c8dcSSimon Schubert static void *
reggroups_init(struct gdbarch * gdbarch)805796c8dcSSimon Schubert reggroups_init (struct gdbarch *gdbarch)
815796c8dcSSimon Schubert {
825796c8dcSSimon Schubert   struct reggroups *groups = GDBARCH_OBSTACK_ZALLOC (gdbarch,
835796c8dcSSimon Schubert 						     struct reggroups);
84cf7f2e2dSJohn Marino 
855796c8dcSSimon Schubert   groups->last = &groups->first;
865796c8dcSSimon Schubert   return groups;
875796c8dcSSimon Schubert }
885796c8dcSSimon Schubert 
895796c8dcSSimon Schubert /* Add a register group (with attribute values) to the pre-defined
905796c8dcSSimon Schubert    list.  */
915796c8dcSSimon Schubert 
925796c8dcSSimon Schubert static void
add_group(struct reggroups * groups,struct reggroup * group,struct reggroup_el * el)935796c8dcSSimon Schubert add_group (struct reggroups *groups, struct reggroup *group,
945796c8dcSSimon Schubert 	   struct reggroup_el *el)
955796c8dcSSimon Schubert {
965796c8dcSSimon Schubert   gdb_assert (group != NULL);
975796c8dcSSimon Schubert   el->group = group;
985796c8dcSSimon Schubert   el->next = NULL;
995796c8dcSSimon Schubert   (*groups->last) = el;
1005796c8dcSSimon Schubert   groups->last = &el->next;
1015796c8dcSSimon Schubert }
1025796c8dcSSimon Schubert 
1035796c8dcSSimon Schubert void
reggroup_add(struct gdbarch * gdbarch,struct reggroup * group)1045796c8dcSSimon Schubert reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
1055796c8dcSSimon Schubert {
1065796c8dcSSimon Schubert   struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
1075796c8dcSSimon Schubert 
1085796c8dcSSimon Schubert   if (groups == NULL)
1095796c8dcSSimon Schubert     {
1105796c8dcSSimon Schubert       /* ULGH, called during architecture initialization.  Patch
1115796c8dcSSimon Schubert          things up.  */
1125796c8dcSSimon Schubert       groups = reggroups_init (gdbarch);
1135796c8dcSSimon Schubert       deprecated_set_gdbarch_data (gdbarch, reggroups_data, groups);
1145796c8dcSSimon Schubert     }
1155796c8dcSSimon Schubert   add_group (groups, group,
1165796c8dcSSimon Schubert 	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
1175796c8dcSSimon Schubert }
1185796c8dcSSimon Schubert 
1195796c8dcSSimon Schubert /* The default register groups for an architecture.  */
1205796c8dcSSimon Schubert 
1215796c8dcSSimon Schubert static struct reggroups default_groups = { NULL, &default_groups.first };
1225796c8dcSSimon Schubert 
1235796c8dcSSimon Schubert /* A register group iterator.  */
1245796c8dcSSimon Schubert 
1255796c8dcSSimon Schubert struct reggroup *
reggroup_next(struct gdbarch * gdbarch,struct reggroup * last)1265796c8dcSSimon Schubert reggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
1275796c8dcSSimon Schubert {
1285796c8dcSSimon Schubert   struct reggroups *groups;
1295796c8dcSSimon Schubert   struct reggroup_el *el;
1305796c8dcSSimon Schubert 
1315796c8dcSSimon Schubert   /* Don't allow this function to be called during architecture
1325796c8dcSSimon Schubert      creation.  If there are no groups, use the default groups list.  */
1335796c8dcSSimon Schubert   groups = gdbarch_data (gdbarch, reggroups_data);
1345796c8dcSSimon Schubert   gdb_assert (groups != NULL);
1355796c8dcSSimon Schubert   if (groups->first == NULL)
1365796c8dcSSimon Schubert     groups = &default_groups;
1375796c8dcSSimon Schubert 
1385796c8dcSSimon Schubert   /* Return the first/next reggroup.  */
1395796c8dcSSimon Schubert   if (last == NULL)
1405796c8dcSSimon Schubert     return groups->first->group;
1415796c8dcSSimon Schubert   for (el = groups->first; el != NULL; el = el->next)
1425796c8dcSSimon Schubert     {
1435796c8dcSSimon Schubert       if (el->group == last)
1445796c8dcSSimon Schubert 	{
1455796c8dcSSimon Schubert 	  if (el->next != NULL)
1465796c8dcSSimon Schubert 	    return el->next->group;
1475796c8dcSSimon Schubert 	  else
1485796c8dcSSimon Schubert 	    return NULL;
1495796c8dcSSimon Schubert 	}
1505796c8dcSSimon Schubert     }
1515796c8dcSSimon Schubert   return NULL;
1525796c8dcSSimon Schubert }
1535796c8dcSSimon Schubert 
1545796c8dcSSimon Schubert /* Is REGNUM a member of REGGROUP?  */
1555796c8dcSSimon Schubert int
default_register_reggroup_p(struct gdbarch * gdbarch,int regnum,struct reggroup * group)1565796c8dcSSimon Schubert default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
1575796c8dcSSimon Schubert 			     struct reggroup *group)
1585796c8dcSSimon Schubert {
1595796c8dcSSimon Schubert   int vector_p;
1605796c8dcSSimon Schubert   int float_p;
1615796c8dcSSimon Schubert   int raw_p;
1625796c8dcSSimon Schubert 
1635796c8dcSSimon Schubert   if (gdbarch_register_name (gdbarch, regnum) == NULL
1645796c8dcSSimon Schubert       || *gdbarch_register_name (gdbarch, regnum) == '\0')
1655796c8dcSSimon Schubert     return 0;
1665796c8dcSSimon Schubert   if (group == all_reggroup)
1675796c8dcSSimon Schubert     return 1;
1685796c8dcSSimon Schubert   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
1695796c8dcSSimon Schubert   float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
1705796c8dcSSimon Schubert   raw_p = regnum < gdbarch_num_regs (gdbarch);
1715796c8dcSSimon Schubert   if (group == float_reggroup)
1725796c8dcSSimon Schubert     return float_p;
1735796c8dcSSimon Schubert   if (group == vector_reggroup)
1745796c8dcSSimon Schubert     return vector_p;
1755796c8dcSSimon Schubert   if (group == general_reggroup)
1765796c8dcSSimon Schubert     return (!vector_p && !float_p);
1775796c8dcSSimon Schubert   if (group == save_reggroup || group == restore_reggroup)
1785796c8dcSSimon Schubert     return raw_p;
1795796c8dcSSimon Schubert   return 0;
1805796c8dcSSimon Schubert }
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert /* Dump out a table of register groups for the current architecture.  */
1835796c8dcSSimon Schubert 
1845796c8dcSSimon Schubert static void
reggroups_dump(struct gdbarch * gdbarch,struct ui_file * file)1855796c8dcSSimon Schubert reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
1865796c8dcSSimon Schubert {
1875796c8dcSSimon Schubert   struct reggroup *group = NULL;
1885796c8dcSSimon Schubert 
1895796c8dcSSimon Schubert   do
1905796c8dcSSimon Schubert     {
1915796c8dcSSimon Schubert       /* Group name.  */
1925796c8dcSSimon Schubert       {
1935796c8dcSSimon Schubert 	const char *name;
194cf7f2e2dSJohn Marino 
1955796c8dcSSimon Schubert 	if (group == NULL)
1965796c8dcSSimon Schubert 	  name = "Group";
1975796c8dcSSimon Schubert 	else
1985796c8dcSSimon Schubert 	  name = reggroup_name (group);
1995796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %-10s", name);
2005796c8dcSSimon Schubert       }
2015796c8dcSSimon Schubert 
2025796c8dcSSimon Schubert       /* Group type.  */
2035796c8dcSSimon Schubert       {
2045796c8dcSSimon Schubert 	const char *type;
205cf7f2e2dSJohn Marino 
2065796c8dcSSimon Schubert 	if (group == NULL)
2075796c8dcSSimon Schubert 	  type = "Type";
2085796c8dcSSimon Schubert 	else
2095796c8dcSSimon Schubert 	  {
2105796c8dcSSimon Schubert 	    switch (reggroup_type (group))
2115796c8dcSSimon Schubert 	      {
2125796c8dcSSimon Schubert 	      case USER_REGGROUP:
2135796c8dcSSimon Schubert 		type = "user";
2145796c8dcSSimon Schubert 		break;
2155796c8dcSSimon Schubert 	      case INTERNAL_REGGROUP:
2165796c8dcSSimon Schubert 		type = "internal";
2175796c8dcSSimon Schubert 		break;
2185796c8dcSSimon Schubert 	      default:
2195796c8dcSSimon Schubert 		internal_error (__FILE__, __LINE__, _("bad switch"));
2205796c8dcSSimon Schubert 	      }
2215796c8dcSSimon Schubert 	  }
2225796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %-10s", type);
2235796c8dcSSimon Schubert       }
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert       /* Note: If you change this, be sure to also update the
2265796c8dcSSimon Schubert          documentation.  */
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert       fprintf_unfiltered (file, "\n");
2295796c8dcSSimon Schubert 
2305796c8dcSSimon Schubert       group = reggroup_next (gdbarch, group);
2315796c8dcSSimon Schubert     }
2325796c8dcSSimon Schubert   while (group != NULL);
2335796c8dcSSimon Schubert }
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert static void
maintenance_print_reggroups(char * args,int from_tty)2365796c8dcSSimon Schubert maintenance_print_reggroups (char *args, int from_tty)
2375796c8dcSSimon Schubert {
2385796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_current_arch ();
2395796c8dcSSimon Schubert 
2405796c8dcSSimon Schubert   if (args == NULL)
2415796c8dcSSimon Schubert     reggroups_dump (gdbarch, gdb_stdout);
2425796c8dcSSimon Schubert   else
2435796c8dcSSimon Schubert     {
2445796c8dcSSimon Schubert       struct cleanup *cleanups;
2455796c8dcSSimon Schubert       struct ui_file *file = gdb_fopen (args, "w");
246cf7f2e2dSJohn Marino 
2475796c8dcSSimon Schubert       if (file == NULL)
2485796c8dcSSimon Schubert 	perror_with_name (_("maintenance print reggroups"));
2495796c8dcSSimon Schubert       cleanups = make_cleanup_ui_file_delete (file);
2505796c8dcSSimon Schubert       reggroups_dump (gdbarch, file);
2515796c8dcSSimon Schubert       do_cleanups (cleanups);
2525796c8dcSSimon Schubert     }
2535796c8dcSSimon Schubert }
2545796c8dcSSimon Schubert 
2555796c8dcSSimon Schubert /* Pre-defined register groups.  */
2565796c8dcSSimon Schubert static struct reggroup general_group = { "general", USER_REGGROUP };
2575796c8dcSSimon Schubert static struct reggroup float_group = { "float", USER_REGGROUP };
2585796c8dcSSimon Schubert static struct reggroup system_group = { "system", USER_REGGROUP };
2595796c8dcSSimon Schubert static struct reggroup vector_group = { "vector", USER_REGGROUP };
2605796c8dcSSimon Schubert static struct reggroup all_group = { "all", USER_REGGROUP };
2615796c8dcSSimon Schubert static struct reggroup save_group = { "save", INTERNAL_REGGROUP };
2625796c8dcSSimon Schubert static struct reggroup restore_group = { "restore", INTERNAL_REGGROUP };
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert struct reggroup *const general_reggroup = &general_group;
2655796c8dcSSimon Schubert struct reggroup *const float_reggroup = &float_group;
2665796c8dcSSimon Schubert struct reggroup *const system_reggroup = &system_group;
2675796c8dcSSimon Schubert struct reggroup *const vector_reggroup = &vector_group;
2685796c8dcSSimon Schubert struct reggroup *const all_reggroup = &all_group;
2695796c8dcSSimon Schubert struct reggroup *const save_reggroup = &save_group;
2705796c8dcSSimon Schubert struct reggroup *const restore_reggroup = &restore_group;
2715796c8dcSSimon Schubert 
2725796c8dcSSimon Schubert extern initialize_file_ftype _initialize_reggroup; /* -Wmissing-prototypes */
2735796c8dcSSimon Schubert 
2745796c8dcSSimon Schubert void
_initialize_reggroup(void)2755796c8dcSSimon Schubert _initialize_reggroup (void)
2765796c8dcSSimon Schubert {
2775796c8dcSSimon Schubert   reggroups_data = gdbarch_data_register_post_init (reggroups_init);
2785796c8dcSSimon Schubert 
2795796c8dcSSimon Schubert   /* The pre-defined list of groups.  */
2805796c8dcSSimon Schubert   add_group (&default_groups, general_reggroup, XMALLOC (struct reggroup_el));
2815796c8dcSSimon Schubert   add_group (&default_groups, float_reggroup, XMALLOC (struct reggroup_el));
2825796c8dcSSimon Schubert   add_group (&default_groups, system_reggroup, XMALLOC (struct reggroup_el));
2835796c8dcSSimon Schubert   add_group (&default_groups, vector_reggroup, XMALLOC (struct reggroup_el));
2845796c8dcSSimon Schubert   add_group (&default_groups, all_reggroup, XMALLOC (struct reggroup_el));
2855796c8dcSSimon Schubert   add_group (&default_groups, save_reggroup, XMALLOC (struct reggroup_el));
2865796c8dcSSimon Schubert   add_group (&default_groups, restore_reggroup, XMALLOC (struct reggroup_el));
2875796c8dcSSimon Schubert 
2885796c8dcSSimon Schubert   add_cmd ("reggroups", class_maintenance,
2895796c8dcSSimon Schubert 	   maintenance_print_reggroups, _("\
2905796c8dcSSimon Schubert Print the internal register group names.\n\
2915796c8dcSSimon Schubert Takes an optional file parameter."),
2925796c8dcSSimon Schubert 	   &maintenanceprintlist);
2935796c8dcSSimon Schubert 
2945796c8dcSSimon Schubert }
295