1/* Register groupings for GDB, the GNU debugger. 2 3 Copyright (C) 2002-2020 Free Software Foundation, Inc. 4 5 Contributed by Red Hat. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22#include "defs.h" 23#include "arch-utils.h" 24#include "reggroups.h" 25#include "gdbtypes.h" 26#include "regcache.h" 27#include "command.h" 28#include "gdbcmd.h" /* For maintenanceprintlist. */ 29#include "gdb_obstack.h" 30 31/* Individual register groups. */ 32 33struct reggroup 34{ 35 const char *name; 36 enum reggroup_type type; 37}; 38 39struct reggroup * 40reggroup_new (const char *name, enum reggroup_type type) 41{ 42 struct reggroup *group = XNEW (struct reggroup); 43 44 group->name = name; 45 group->type = type; 46 return group; 47} 48 49/* See reggroups.h. */ 50 51struct reggroup * 52reggroup_gdbarch_new (struct gdbarch *gdbarch, const char *name, 53 enum reggroup_type type) 54{ 55 struct reggroup *group = GDBARCH_OBSTACK_ZALLOC (gdbarch, 56 struct reggroup); 57 58 group->name = gdbarch_obstack_strdup (gdbarch, name); 59 group->type = type; 60 return group; 61} 62 63/* Register group attributes. */ 64 65const char * 66reggroup_name (struct reggroup *group) 67{ 68 return group->name; 69} 70 71enum reggroup_type 72reggroup_type (struct reggroup *group) 73{ 74 return group->type; 75} 76 77/* A linked list of groups for the given architecture. */ 78 79struct reggroup_el 80{ 81 struct reggroup *group; 82 struct reggroup_el *next; 83}; 84 85struct reggroups 86{ 87 struct reggroup_el *first; 88 struct reggroup_el **last; 89}; 90 91static struct gdbarch_data *reggroups_data; 92 93static void * 94reggroups_init (struct obstack *obstack) 95{ 96 struct reggroups *groups = OBSTACK_ZALLOC (obstack, struct reggroups); 97 98 groups->last = &groups->first; 99 return groups; 100} 101 102/* Add a register group (with attribute values) to the pre-defined 103 list. */ 104 105static void 106add_group (struct reggroups *groups, struct reggroup *group, 107 struct reggroup_el *el) 108{ 109 gdb_assert (group != NULL); 110 el->group = group; 111 el->next = NULL; 112 (*groups->last) = el; 113 groups->last = &el->next; 114} 115 116void 117reggroup_add (struct gdbarch *gdbarch, struct reggroup *group) 118{ 119 struct reggroups *groups 120 = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data); 121 122 add_group (groups, group, 123 GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el)); 124} 125 126/* The default register groups for an architecture. */ 127 128static struct reggroups default_groups = { NULL, &default_groups.first }; 129 130/* A register group iterator. */ 131 132struct reggroup * 133reggroup_next (struct gdbarch *gdbarch, struct reggroup *last) 134{ 135 struct reggroups *groups; 136 struct reggroup_el *el; 137 138 /* Don't allow this function to be called during architecture 139 creation. If there are no groups, use the default groups list. */ 140 groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data); 141 gdb_assert (groups != NULL); 142 if (groups->first == NULL) 143 groups = &default_groups; 144 145 /* Return the first/next reggroup. */ 146 if (last == NULL) 147 return groups->first->group; 148 for (el = groups->first; el != NULL; el = el->next) 149 { 150 if (el->group == last) 151 { 152 if (el->next != NULL) 153 return el->next->group; 154 else 155 return NULL; 156 } 157 } 158 return NULL; 159} 160 161/* See reggroups.h. */ 162 163struct reggroup * 164reggroup_prev (struct gdbarch *gdbarch, struct reggroup *curr) 165{ 166 struct reggroups *groups; 167 struct reggroup_el *el; 168 struct reggroup *prev; 169 170 /* Don't allow this function to be called during architecture 171 creation. If there are no groups, use the default groups list. */ 172 groups = (struct reggroups *) gdbarch_data (gdbarch, reggroups_data); 173 gdb_assert (groups != NULL); 174 if (groups->first == NULL) 175 groups = &default_groups; 176 177 prev = NULL; 178 for (el = groups->first; el != NULL; el = el->next) 179 { 180 gdb_assert (el->group != NULL); 181 if (el->group == curr) 182 return prev; 183 prev = el->group; 184 } 185 if (curr == NULL) 186 return prev; 187 return NULL; 188} 189 190/* Is REGNUM a member of REGGROUP? */ 191int 192default_register_reggroup_p (struct gdbarch *gdbarch, int regnum, 193 struct reggroup *group) 194{ 195 int vector_p; 196 int float_p; 197 int raw_p; 198 199 if (gdbarch_register_name (gdbarch, regnum) == NULL 200 || *gdbarch_register_name (gdbarch, regnum) == '\0') 201 return 0; 202 if (group == all_reggroup) 203 return 1; 204 vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); 205 float_p = (register_type (gdbarch, regnum)->code () == TYPE_CODE_FLT 206 || (register_type (gdbarch, regnum)->code () 207 == TYPE_CODE_DECFLOAT)); 208 raw_p = regnum < gdbarch_num_regs (gdbarch); 209 if (group == float_reggroup) 210 return float_p; 211 if (group == vector_reggroup) 212 return vector_p; 213 if (group == general_reggroup) 214 return (!vector_p && !float_p); 215 if (group == save_reggroup || group == restore_reggroup) 216 return raw_p; 217 return 0; 218} 219 220/* See reggroups.h. */ 221 222reggroup * 223reggroup_find (struct gdbarch *gdbarch, const char *name) 224{ 225 struct reggroup *group; 226 227 for (group = reggroup_next (gdbarch, NULL); 228 group != NULL; 229 group = reggroup_next (gdbarch, group)) 230 { 231 if (strcmp (name, reggroup_name (group)) == 0) 232 return group; 233 } 234 return NULL; 235} 236 237/* Dump out a table of register groups for the current architecture. */ 238 239static void 240reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file) 241{ 242 struct reggroup *group = NULL; 243 244 do 245 { 246 /* Group name. */ 247 { 248 const char *name; 249 250 if (group == NULL) 251 name = "Group"; 252 else 253 name = reggroup_name (group); 254 fprintf_unfiltered (file, " %-10s", name); 255 } 256 257 /* Group type. */ 258 { 259 const char *type; 260 261 if (group == NULL) 262 type = "Type"; 263 else 264 { 265 switch (reggroup_type (group)) 266 { 267 case USER_REGGROUP: 268 type = "user"; 269 break; 270 case INTERNAL_REGGROUP: 271 type = "internal"; 272 break; 273 default: 274 internal_error (__FILE__, __LINE__, _("bad switch")); 275 } 276 } 277 fprintf_unfiltered (file, " %-10s", type); 278 } 279 280 /* Note: If you change this, be sure to also update the 281 documentation. */ 282 283 fprintf_unfiltered (file, "\n"); 284 285 group = reggroup_next (gdbarch, group); 286 } 287 while (group != NULL); 288} 289 290static void 291maintenance_print_reggroups (const char *args, int from_tty) 292{ 293 struct gdbarch *gdbarch = get_current_arch (); 294 295 if (args == NULL) 296 reggroups_dump (gdbarch, gdb_stdout); 297 else 298 { 299 stdio_file file; 300 301 if (!file.open (args, "w")) 302 perror_with_name (_("maintenance print reggroups")); 303 reggroups_dump (gdbarch, &file); 304 } 305} 306 307/* Pre-defined register groups. */ 308static struct reggroup general_group = { "general", USER_REGGROUP }; 309static struct reggroup float_group = { "float", USER_REGGROUP }; 310static struct reggroup system_group = { "system", USER_REGGROUP }; 311static struct reggroup vector_group = { "vector", USER_REGGROUP }; 312static struct reggroup all_group = { "all", USER_REGGROUP }; 313static struct reggroup save_group = { "save", INTERNAL_REGGROUP }; 314static struct reggroup restore_group = { "restore", INTERNAL_REGGROUP }; 315 316struct reggroup *const general_reggroup = &general_group; 317struct reggroup *const float_reggroup = &float_group; 318struct reggroup *const system_reggroup = &system_group; 319struct reggroup *const vector_reggroup = &vector_group; 320struct reggroup *const all_reggroup = &all_group; 321struct reggroup *const save_reggroup = &save_group; 322struct reggroup *const restore_reggroup = &restore_group; 323 324void _initialize_reggroup (); 325void 326_initialize_reggroup () 327{ 328 reggroups_data = gdbarch_data_register_pre_init (reggroups_init); 329 330 /* The pre-defined list of groups. */ 331 add_group (&default_groups, general_reggroup, XNEW (struct reggroup_el)); 332 add_group (&default_groups, float_reggroup, XNEW (struct reggroup_el)); 333 add_group (&default_groups, system_reggroup, XNEW (struct reggroup_el)); 334 add_group (&default_groups, vector_reggroup, XNEW (struct reggroup_el)); 335 add_group (&default_groups, all_reggroup, XNEW (struct reggroup_el)); 336 add_group (&default_groups, save_reggroup, XNEW (struct reggroup_el)); 337 add_group (&default_groups, restore_reggroup, XNEW (struct reggroup_el)); 338 339 add_cmd ("reggroups", class_maintenance, 340 maintenance_print_reggroups, _("\ 341Print the internal register group names.\n\ 342Takes an optional file parameter."), 343 &maintenanceprintlist); 344 345} 346