2002-11-02 Andrew Cagney <cagney@redhat.com>
* reggroups.h, reggroups.c: New files. * regcache.c: Include "reggroups.h". (enum regcache_dump_what): Add `regcache_dump_groups'. (regcache_dump): Contract size of the "Type" column. When specified, dump the register's groups. (maintenance_print_register_groups): New function. (_initialize_regcache): Add command `maint print register-groups'. * Makefile.in (COMMON_OBS): Add reggroups.o (SFILES): Add reggroups.c. (reggroups_h): Define. (regcache.o, gdbarch.o): Update dependencies. (reggroups.o): Specify dependencies. * gdbarch.sh (register_reggroup_p): Add pure multi-arch method. Add opaque declaration for `struct reggroup' in generated .h file. Include "reggroups.h" in generated .c file. gdbarch.h, gdbarch.c: Re-generate.
This commit is contained in:
parent
4caf0990c1
commit
b59ff9d5ff
8 changed files with 459 additions and 27 deletions
|
@ -1,3 +1,22 @@
|
||||||
|
2002-11-02 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
|
* reggroups.h, reggroups.c: New files.
|
||||||
|
* regcache.c: Include "reggroups.h".
|
||||||
|
(enum regcache_dump_what): Add `regcache_dump_groups'.
|
||||||
|
(regcache_dump): Contract size of the "Type" column. When
|
||||||
|
specified, dump the register's groups.
|
||||||
|
(maintenance_print_register_groups): New function.
|
||||||
|
(_initialize_regcache): Add command `maint print register-groups'.
|
||||||
|
* Makefile.in (COMMON_OBS): Add reggroups.o
|
||||||
|
(SFILES): Add reggroups.c.
|
||||||
|
(reggroups_h): Define.
|
||||||
|
(regcache.o, gdbarch.o): Update dependencies.
|
||||||
|
(reggroups.o): Specify dependencies.
|
||||||
|
* gdbarch.sh (register_reggroup_p): Add pure multi-arch method.
|
||||||
|
Add opaque declaration for `struct reggroup' in generated .h file.
|
||||||
|
Include "reggroups.h" in generated .c file.
|
||||||
|
gdbarch.h, gdbarch.c: Re-generate.
|
||||||
|
|
||||||
2002-11-02 Andrew Cagney <cagney@redhat.com>
|
2002-11-02 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
* regcache.h (deprecated_read_register_gen): Rename
|
* regcache.h (deprecated_read_register_gen): Rename
|
||||||
|
|
|
@ -550,7 +550,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
|
||||||
nlmread.c \
|
nlmread.c \
|
||||||
objfiles.c osabi.c \
|
objfiles.c osabi.c \
|
||||||
p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
|
p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
|
||||||
regcache.c remote.c \
|
regcache.c reggroups.c remote.c \
|
||||||
scm-exp.c scm-lang.c scm-valprint.c serial.c ser-unix.c source.c \
|
scm-exp.c scm-lang.c scm-valprint.c serial.c ser-unix.c source.c \
|
||||||
stabsread.c stack.c std-regs.c symfile.c symmisc.c symtab.c \
|
stabsread.c stack.c std-regs.c symfile.c symmisc.c symtab.c \
|
||||||
target.c thread.c top.c tracepoint.c typeprint.c \
|
target.c thread.c top.c tracepoint.c typeprint.c \
|
||||||
|
@ -698,6 +698,7 @@ ppc_tdep_h = ppc-tdep.h $(osabi_h)
|
||||||
ppcnbsd_tdep_h = ppcnbsd-tdep.h
|
ppcnbsd_tdep_h = ppcnbsd-tdep.h
|
||||||
proc_utils_h = proc-utils.h
|
proc_utils_h = proc-utils.h
|
||||||
regcache_h = regcache.h
|
regcache_h = regcache.h
|
||||||
|
reggroups_h = reggroups.h
|
||||||
remote_utils_h = remote-utils.h $(target_h)
|
remote_utils_h = remote-utils.h $(target_h)
|
||||||
remote_h = remote.h
|
remote_h = remote.h
|
||||||
scm_lang_h = scm-lang.h $(scm_tags_h)
|
scm_lang_h = scm-lang.h $(scm_tags_h)
|
||||||
|
@ -854,7 +855,8 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
|
||||||
nlmread.o serial.o mdebugread.o top.o utils.o \
|
nlmread.o serial.o mdebugread.o top.o utils.o \
|
||||||
ui-file.o \
|
ui-file.o \
|
||||||
frame.o doublest.o \
|
frame.o doublest.o \
|
||||||
gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o
|
gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \
|
||||||
|
reggroups.o
|
||||||
|
|
||||||
OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
|
OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
|
||||||
|
|
||||||
|
@ -1685,7 +1687,7 @@ gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
|
||||||
$(gdb_string_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
|
$(gdb_string_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
|
||||||
$(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(gdbthread_h) \
|
$(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(gdbthread_h) \
|
||||||
$(annotate_h) $(symfile_h) $(value_h) $(symcat_h) $(floatformat_h) \
|
$(annotate_h) $(symfile_h) $(value_h) $(symcat_h) $(floatformat_h) \
|
||||||
$(gdb_assert_h) $(gdb_string_h) $(gdb_events_h)
|
$(gdb_assert_h) $(gdb_string_h) $(gdb_events_h) $(reggroups_h)
|
||||||
gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
|
gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
|
||||||
$(symfile_h) $(objfiles_h) $(gdbtypes_h) $(expression_h) \
|
$(symfile_h) $(objfiles_h) $(gdbtypes_h) $(expression_h) \
|
||||||
$(language_h) $(target_h) $(value_h) $(demangle_h) $(complaints_h) \
|
$(language_h) $(target_h) $(value_h) $(demangle_h) $(complaints_h) \
|
||||||
|
@ -2003,8 +2005,10 @@ procfs.o: procfs.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
|
||||||
ptx4-nat.o: ptx4-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h) \
|
ptx4-nat.o: ptx4-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h) \
|
||||||
$(gregset_h)
|
$(gregset_h)
|
||||||
regcache.o: regcache.c $(defs_h) $(inferior_h) $(target_h) $(gdbarch_h) \
|
regcache.o: regcache.c $(defs_h) $(inferior_h) $(target_h) $(gdbarch_h) \
|
||||||
$(gdbcmd_h) $(regcache_h) $(gdb_assert_h) $(gdb_string_h) \
|
$(gdbcmd_h) $(regcache_h) $(reggroups_h) $(gdb_assert_h) \
|
||||||
$(gdbcmd_h)
|
$(gdb_string_h) $(gdbcmd_h)
|
||||||
|
reggroups.o: reggroups.c $(defs_h) $(reggroups_h) $(gdbtypes_h) \
|
||||||
|
$(gdb_assert_h) $(regcache_h) $(command_h) $(gdbcmd_h)
|
||||||
remote-array.o: remote-array.c $(defs_h) $(gdbcore_h) $(target_h) \
|
remote-array.o: remote-array.c $(defs_h) $(gdbcore_h) $(target_h) \
|
||||||
$(gdb_string_h) $(command_h) $(serial_h) $(monitor_h) \
|
$(gdb_string_h) $(command_h) $(serial_h) $(monitor_h) \
|
||||||
$(remote_utils_h) $(inferior_h) $(version_h) $(regcache_h)
|
$(remote_utils_h) $(inferior_h) $(version_h) $(regcache_h)
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "gdb-events.h"
|
#include "gdb-events.h"
|
||||||
|
#include "reggroups.h"
|
||||||
|
|
||||||
/* Static function declarations */
|
/* Static function declarations */
|
||||||
|
|
||||||
|
@ -274,6 +275,7 @@ struct gdbarch
|
||||||
gdbarch_address_class_type_flags_ftype *address_class_type_flags;
|
gdbarch_address_class_type_flags_ftype *address_class_type_flags;
|
||||||
gdbarch_address_class_type_flags_to_name_ftype *address_class_type_flags_to_name;
|
gdbarch_address_class_type_flags_to_name_ftype *address_class_type_flags_to_name;
|
||||||
gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags;
|
gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags;
|
||||||
|
gdbarch_register_reggroup_p_ftype *register_reggroup_p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -437,6 +439,7 @@ struct gdbarch startup_gdbarch =
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
default_register_reggroup_p,
|
||||||
/* startup_gdbarch() */
|
/* startup_gdbarch() */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -568,6 +571,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
|
||||||
current_gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special;
|
current_gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special;
|
||||||
current_gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
|
current_gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special;
|
||||||
current_gdbarch->name_of_malloc = "malloc";
|
current_gdbarch->name_of_malloc = "malloc";
|
||||||
|
current_gdbarch->register_reggroup_p = default_register_reggroup_p;
|
||||||
/* gdbarch_alloc() */
|
/* gdbarch_alloc() */
|
||||||
|
|
||||||
return current_gdbarch;
|
return current_gdbarch;
|
||||||
|
@ -819,6 +823,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||||
/* Skip verify of address_class_type_flags, has predicate */
|
/* Skip verify of address_class_type_flags, has predicate */
|
||||||
/* Skip verify of address_class_type_flags_to_name, has predicate */
|
/* Skip verify of address_class_type_flags_to_name, has predicate */
|
||||||
/* Skip verify of address_class_name_to_type_flags, has predicate */
|
/* Skip verify of address_class_name_to_type_flags, has predicate */
|
||||||
|
if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
|
||||||
|
&& (gdbarch->register_reggroup_p == default_register_reggroup_p))
|
||||||
|
fprintf_unfiltered (log, "\n\tregister_reggroup_p");
|
||||||
buf = ui_file_xstrdup (log, &dummy);
|
buf = ui_file_xstrdup (log, &dummy);
|
||||||
make_cleanup (xfree, buf);
|
make_cleanup (xfree, buf);
|
||||||
if (strlen (buf) > 0)
|
if (strlen (buf) > 0)
|
||||||
|
@ -851,6 +858,10 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
|
"gdbarch_dump: in_function_epilogue_p = 0x%08lx\n",
|
||||||
(long) current_gdbarch->in_function_epilogue_p);
|
(long) current_gdbarch->in_function_epilogue_p);
|
||||||
|
if (GDB_MULTI_ARCH)
|
||||||
|
fprintf_unfiltered (file,
|
||||||
|
"gdbarch_dump: register_reggroup_p = 0x%08lx\n",
|
||||||
|
(long) current_gdbarch->register_reggroup_p);
|
||||||
if (GDB_MULTI_ARCH)
|
if (GDB_MULTI_ARCH)
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: pseudo_register_read = 0x%08lx\n",
|
"gdbarch_dump: pseudo_register_read = 0x%08lx\n",
|
||||||
|
@ -5186,6 +5197,25 @@ set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch,
|
||||||
gdbarch->address_class_name_to_type_flags = address_class_name_to_type_flags;
|
gdbarch->address_class_name_to_type_flags = address_class_name_to_type_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdbarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup)
|
||||||
|
{
|
||||||
|
gdb_assert (gdbarch != NULL);
|
||||||
|
if (gdbarch->register_reggroup_p == 0)
|
||||||
|
internal_error (__FILE__, __LINE__,
|
||||||
|
"gdbarch: gdbarch_register_reggroup_p invalid");
|
||||||
|
if (gdbarch_debug >= 2)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "gdbarch_register_reggroup_p called\n");
|
||||||
|
return gdbarch->register_reggroup_p (gdbarch, regnum, reggroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch,
|
||||||
|
gdbarch_register_reggroup_p_ftype register_reggroup_p)
|
||||||
|
{
|
||||||
|
gdbarch->register_reggroup_p = register_reggroup_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Keep a registry of per-architecture data-pointers required by GDB
|
/* Keep a registry of per-architecture data-pointers required by GDB
|
||||||
modules. */
|
modules. */
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct value;
|
||||||
struct objfile;
|
struct objfile;
|
||||||
struct minimal_symbol;
|
struct minimal_symbol;
|
||||||
struct regcache;
|
struct regcache;
|
||||||
|
struct reggroup;
|
||||||
|
|
||||||
extern struct gdbarch *current_gdbarch;
|
extern struct gdbarch *current_gdbarch;
|
||||||
|
|
||||||
|
@ -2660,6 +2661,12 @@ typedef int (gdbarch_address_class_name_to_type_flags_ftype) (struct gdbarch *gd
|
||||||
extern int gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, char *name, int *type_flags_ptr);
|
extern int gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, char *name, int *type_flags_ptr);
|
||||||
extern void set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags);
|
extern void set_gdbarch_address_class_name_to_type_flags (struct gdbarch *gdbarch, gdbarch_address_class_name_to_type_flags_ftype *address_class_name_to_type_flags);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
extern void set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, gdbarch_register_reggroup_p_ftype *register_reggroup_p);
|
||||||
|
|
||||||
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
|
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -667,6 +667,8 @@ v::HAVE_NONSTEPPABLE_WATCHPOINT:int:have_nonsteppable_watchpoint::::0:0::0
|
||||||
F:2:ADDRESS_CLASS_TYPE_FLAGS:int:address_class_type_flags:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class
|
F:2:ADDRESS_CLASS_TYPE_FLAGS:int:address_class_type_flags:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class
|
||||||
M:2:ADDRESS_CLASS_TYPE_FLAGS_TO_NAME:char *:address_class_type_flags_to_name:int type_flags:type_flags:
|
M:2:ADDRESS_CLASS_TYPE_FLAGS_TO_NAME:char *:address_class_type_flags_to_name:int type_flags:type_flags:
|
||||||
M:2:ADDRESS_CLASS_NAME_TO_TYPE_FLAGS:int:address_class_name_to_type_flags:char *name, int *type_flags_ptr:name, type_flags_ptr
|
M:2:ADDRESS_CLASS_NAME_TO_TYPE_FLAGS:int:address_class_name_to_type_flags:char *name, int *type_flags_ptr:name, type_flags_ptr
|
||||||
|
# Is a register in a group
|
||||||
|
m:::int:register_reggroup_p:int regnum, struct reggroup *reggroup:regnum, reggroup:::default_register_reggroup_p
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,6 +780,7 @@ struct value;
|
||||||
struct objfile;
|
struct objfile;
|
||||||
struct minimal_symbol;
|
struct minimal_symbol;
|
||||||
struct regcache;
|
struct regcache;
|
||||||
|
struct reggroup;
|
||||||
|
|
||||||
extern struct gdbarch *current_gdbarch;
|
extern struct gdbarch *current_gdbarch;
|
||||||
|
|
||||||
|
@ -1253,6 +1256,7 @@ cat <<EOF
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "gdb-events.h"
|
#include "gdb-events.h"
|
||||||
|
#include "reggroups.h"
|
||||||
|
|
||||||
/* Static function declarations */
|
/* Static function declarations */
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "gdbarch.h"
|
#include "gdbarch.h"
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
|
#include "reggroups.h"
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "gdbcmd.h" /* For maintenanceprintlist. */
|
#include "gdbcmd.h" /* For maintenanceprintlist. */
|
||||||
|
@ -1479,7 +1480,7 @@ dump_endian_bytes (struct ui_file *file, enum bfd_endian endian,
|
||||||
|
|
||||||
enum regcache_dump_what
|
enum regcache_dump_what
|
||||||
{
|
{
|
||||||
regcache_dump_none, regcache_dump_raw, regcache_dump_cooked
|
regcache_dump_none, regcache_dump_raw, regcache_dump_cooked, regcache_dump_groups
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1487,6 +1488,8 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
|
||||||
enum regcache_dump_what what_to_dump)
|
enum regcache_dump_what what_to_dump)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
|
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
|
||||||
|
struct gdbarch *gdbarch = regcache->descr->gdbarch;
|
||||||
|
struct reggroup *const *groups = reggroups (gdbarch);
|
||||||
int regnum;
|
int regnum;
|
||||||
int footnote_nr = 0;
|
int footnote_nr = 0;
|
||||||
int footnote_register_size = 0;
|
int footnote_register_size = 0;
|
||||||
|
@ -1593,13 +1596,14 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type. */
|
/* Type. */
|
||||||
|
{
|
||||||
|
const char *t;
|
||||||
if (regnum < 0)
|
if (regnum < 0)
|
||||||
fprintf_unfiltered (file, " %-20s", "Type");
|
t = "Type";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static const char blt[] = "builtin_type";
|
static const char blt[] = "builtin_type";
|
||||||
const char *t = TYPE_NAME (register_type (regcache->descr->gdbarch,
|
t = TYPE_NAME (register_type (regcache->descr->gdbarch, regnum));
|
||||||
regnum));
|
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
{
|
{
|
||||||
char *n;
|
char *n;
|
||||||
|
@ -1612,8 +1616,12 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
|
||||||
/* Chop a leading builtin_type. */
|
/* Chop a leading builtin_type. */
|
||||||
if (strncmp (t, blt, strlen (blt)) == 0)
|
if (strncmp (t, blt, strlen (blt)) == 0)
|
||||||
t += strlen (blt);
|
t += strlen (blt);
|
||||||
fprintf_unfiltered (file, " %-20s", t);
|
|
||||||
}
|
}
|
||||||
|
fprintf_unfiltered (file, " %-15s", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leading space always present. */
|
||||||
|
fprintf_unfiltered (file, " ");
|
||||||
|
|
||||||
/* Value, raw. */
|
/* Value, raw. */
|
||||||
if (what_to_dump == regcache_dump_raw)
|
if (what_to_dump == regcache_dump_raw)
|
||||||
|
@ -1647,6 +1655,26 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Group members. */
|
||||||
|
if (what_to_dump == regcache_dump_groups)
|
||||||
|
{
|
||||||
|
if (regnum < 0)
|
||||||
|
fprintf_unfiltered (file, "Groups");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *sep = "";
|
||||||
|
for (i = 0; groups[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
if (gdbarch_register_reggroup_p (gdbarch, regnum, groups[i]))
|
||||||
|
{
|
||||||
|
fprintf_unfiltered (file, "%s%s", sep, reggroup_name (groups[i]));
|
||||||
|
sep = ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fprintf_unfiltered (file, "\n");
|
fprintf_unfiltered (file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1696,6 +1724,12 @@ maintenance_print_cooked_registers (char *args, int from_tty)
|
||||||
regcache_print (args, regcache_dump_cooked);
|
regcache_print (args, regcache_dump_cooked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maintenance_print_register_groups (char *args, int from_tty)
|
||||||
|
{
|
||||||
|
regcache_print (args, regcache_dump_groups);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_initialize_regcache (void)
|
_initialize_regcache (void)
|
||||||
{
|
{
|
||||||
|
@ -1726,6 +1760,11 @@ Takes an optional file parameter.",
|
||||||
add_cmd ("cooked-registers", class_maintenance,
|
add_cmd ("cooked-registers", class_maintenance,
|
||||||
maintenance_print_cooked_registers,
|
maintenance_print_cooked_registers,
|
||||||
"Print the internal register configuration including cooked values.\
|
"Print the internal register configuration including cooked values.\
|
||||||
|
Takes an optional file parameter.",
|
||||||
|
&maintenanceprintlist);
|
||||||
|
add_cmd ("register-groups", class_maintenance,
|
||||||
|
maintenance_print_register_groups,
|
||||||
|
"Print the internal register configuration including each register's group.\
|
||||||
Takes an optional file parameter.",
|
Takes an optional file parameter.",
|
||||||
&maintenanceprintlist);
|
&maintenanceprintlist);
|
||||||
|
|
||||||
|
|
268
gdb/reggroups.c
Normal file
268
gdb/reggroups.c
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
/* Register groupings for GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Contributed by Red Hat.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "reggroups.h"
|
||||||
|
#include "gdbtypes.h"
|
||||||
|
#include "gdb_assert.h"
|
||||||
|
#include "regcache.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "gdbcmd.h" /* For maintenanceprintlist. */
|
||||||
|
|
||||||
|
/* Individual register groups. */
|
||||||
|
|
||||||
|
struct reggroup
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
enum reggroup_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reggroup *
|
||||||
|
reggroup_new (const char *name, enum reggroup_type type)
|
||||||
|
{
|
||||||
|
struct reggroup *group = XMALLOC (struct reggroup);
|
||||||
|
group->name = name;
|
||||||
|
group->type = type;
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register group attributes. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
reggroup_name (struct reggroup *group)
|
||||||
|
{
|
||||||
|
return group->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum reggroup_type
|
||||||
|
reggroup_type (struct reggroup *group)
|
||||||
|
{
|
||||||
|
return group->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All the groups for a given architecture. */
|
||||||
|
|
||||||
|
struct reggroups
|
||||||
|
{
|
||||||
|
int nr_group;
|
||||||
|
struct reggroup **group;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gdbarch_data *reggroups_data;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
reggroups_init (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
struct reggroups *groups = XMALLOC (struct reggroups);
|
||||||
|
groups->nr_group = 0;
|
||||||
|
groups->group = NULL;
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reggroups_free (struct gdbarch *gdbarch, void *data)
|
||||||
|
{
|
||||||
|
struct reggroups *groups = data;
|
||||||
|
xfree (groups->group);
|
||||||
|
xfree (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. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_group (struct reggroups *groups, struct reggroup *group)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
|
||||||
|
{
|
||||||
|
struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
|
||||||
|
if (groups == NULL)
|
||||||
|
{
|
||||||
|
/* ULGH, called during architecture initialization. Patch
|
||||||
|
things up. */
|
||||||
|
groups = reggroups_init (gdbarch);
|
||||||
|
set_gdbarch_data (gdbarch, reggroups_data, groups);
|
||||||
|
}
|
||||||
|
add_group (groups, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The register groups for the current architecture. Mumble something
|
||||||
|
about the lifetime of the buffer.... */
|
||||||
|
|
||||||
|
static struct reggroups *default_groups;
|
||||||
|
|
||||||
|
struct reggroup * const*
|
||||||
|
reggroups (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
|
||||||
|
/* Don't allow this function to be called during architecture
|
||||||
|
creation. */
|
||||||
|
gdb_assert (groups != NULL);
|
||||||
|
if (groups->group == NULL)
|
||||||
|
return default_groups->group;
|
||||||
|
else
|
||||||
|
return groups->group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is REGNUM a member of REGGROUP? */
|
||||||
|
int
|
||||||
|
default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
|
||||||
|
struct reggroup *group)
|
||||||
|
{
|
||||||
|
int vector_p;
|
||||||
|
int float_p;
|
||||||
|
int raw_p;
|
||||||
|
if (REGISTER_NAME (regnum) == NULL
|
||||||
|
|| *REGISTER_NAME (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;
|
||||||
|
raw_p = regnum < gdbarch_num_regs (gdbarch);
|
||||||
|
if (group == float_reggroup)
|
||||||
|
return float_p;
|
||||||
|
if (group == vector_reggroup)
|
||||||
|
return vector_p;
|
||||||
|
if (group == general_reggroup)
|
||||||
|
return (!vector_p && !float_p);
|
||||||
|
if (group == save_reggroup || group == restore_reggroup)
|
||||||
|
return raw_p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Group name. */
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
if (i < 0)
|
||||||
|
name = "Group";
|
||||||
|
else
|
||||||
|
name = reggroup_name (groups[i]);
|
||||||
|
fprintf_unfiltered (file, " %-10s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Group type. */
|
||||||
|
{
|
||||||
|
const char *type;
|
||||||
|
if (i < 0)
|
||||||
|
type = "Type";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (reggroup_type (groups[i]))
|
||||||
|
{
|
||||||
|
case USER_REGGROUP:
|
||||||
|
type = "user";
|
||||||
|
break;
|
||||||
|
case INTERNAL_REGGROUP:
|
||||||
|
type = "internal";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
internal_error (__FILE__, __LINE__, "bad switch");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf_unfiltered (file, " %-10s", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: If you change this, be sure to also update the
|
||||||
|
documentation. */
|
||||||
|
|
||||||
|
fprintf_unfiltered (file, "\n");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (groups[i] != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maintenance_print_reggroups (char *args, int from_tty)
|
||||||
|
{
|
||||||
|
if (args == NULL)
|
||||||
|
reggroups_dump (current_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
void
|
||||||
|
_initialize_reggroup (void)
|
||||||
|
{
|
||||||
|
reggroups_data = register_gdbarch_data (reggroups_init, reggroups_free);
|
||||||
|
|
||||||
|
/* 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_cmd ("reggroups", class_maintenance,
|
||||||
|
maintenance_print_reggroups, "\
|
||||||
|
Print the internal register group names.\n\
|
||||||
|
Takes an optional file parameter.",
|
||||||
|
&maintenanceprintlist);
|
||||||
|
|
||||||
|
}
|
61
gdb/reggroups.h
Normal file
61
gdb/reggroups.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* Register groupings for GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Contributed by Red Hat.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef REGGROUPS_H
|
||||||
|
#define REGGROUPS_H
|
||||||
|
|
||||||
|
struct gdbarch;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Pre-defined, internal, register groups. */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Add a register group (with attribute values) to the pre-defined list. */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* The register groups for the current architecture. */
|
||||||
|
extern struct reggroup *const *reggroups (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
/* Is REGNUM a member of REGGROUP? */
|
||||||
|
extern int default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
|
||||||
|
struct reggroup *reggroup);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue