From eb8bc2821737a21e228c59dfce228e03cb7586a8 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Mon, 7 Jul 2003 14:36:58 +0000 Subject: [PATCH] 2003-07-07 Andrew Cagney * expprint.c: Include "user-regs.h" instead of "frame.h". (print_subexp): Use user_reg_map_regnum_to_name, instead of frame_map_regnum_to_name. * frame.c: Include "user-regs.h" instead of "builtin-regs.h". (frame_map_name_to_regnum): Simplify, call user_reg_map_name_to_regnum. (frame_map_regnum_to_name): Simplify, call user_reg_map_regnum_to_name. (frame_register_unwind): Update. * std-regs.c: Include "user-regs.h" instead of "builtin-regs.h". (_initialize_frame_reg): Call user_reg_add_builtin. * findvar.c: Include "user-regs.h" instead of "builtin-regs.h". (value_of_register): Use value_of_user_reg. * eval.c (evaluate_subexp_standard): Update. * parse.c (write_dollar_variable): Update. * d10v-tdep.c (d10v_print_registers_info): Update. * infcmd.c (registers_info): Update. * Makefile.in (SFILES): Delete "builtin-regs.c", add "user-regs.c". (builtin_regs_h): Delete macro. (user_regs_h): Define. (COMMON_OBS): Delete "builtin-regs.o", add "user-regs.o". (builtin-regs.o): Delete target. (user-regs.o): Specify dependencies. (expprint.o): Update dependencies. (findvar.o): Update dependencies. (frame.o): Update dependencies. (std-regs.o): Update dependencies. --- gdb/ChangeLog | 30 ++++++++ gdb/Makefile.in | 22 +++--- gdb/builtin-regs.c | 86 --------------------- gdb/builtin-regs.h | 39 ---------- gdb/d10v-tdep.c | 6 +- gdb/eval.c | 2 +- gdb/expprint.c | 6 +- gdb/findvar.c | 6 +- gdb/frame.c | 39 ++-------- gdb/frame.h | 6 +- gdb/infcmd.c | 3 +- gdb/parse.c | 3 +- gdb/std-regs.c | 12 +-- gdb/user-regs.c | 186 +++++++++++++++++++++++++++++++++++++++++++++ gdb/user-regs.h | 70 +++++++++++++++++ 15 files changed, 329 insertions(+), 187 deletions(-) delete mode 100644 gdb/builtin-regs.c delete mode 100644 gdb/builtin-regs.h create mode 100644 gdb/user-regs.c create mode 100644 gdb/user-regs.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index daf3c13198..e3f6e38288 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,33 @@ +2003-07-07 Andrew Cagney + + * expprint.c: Include "user-regs.h" instead of "frame.h". + (print_subexp): Use user_reg_map_regnum_to_name, instead of + frame_map_regnum_to_name. + * frame.c: Include "user-regs.h" instead of "builtin-regs.h". + (frame_map_name_to_regnum): Simplify, call + user_reg_map_name_to_regnum. + (frame_map_regnum_to_name): Simplify, call + user_reg_map_regnum_to_name. + (frame_register_unwind): Update. + * std-regs.c: Include "user-regs.h" instead of "builtin-regs.h". + (_initialize_frame_reg): Call user_reg_add_builtin. + * findvar.c: Include "user-regs.h" instead of "builtin-regs.h". + (value_of_register): Use value_of_user_reg. + * eval.c (evaluate_subexp_standard): Update. + * parse.c (write_dollar_variable): Update. + * d10v-tdep.c (d10v_print_registers_info): Update. + * infcmd.c (registers_info): Update. + * Makefile.in (SFILES): Delete "builtin-regs.c", add "user-regs.c". + (builtin_regs_h): Delete macro. + (user_regs_h): Define. + (COMMON_OBS): Delete "builtin-regs.o", add "user-regs.o". + (builtin-regs.o): Delete target. + (user-regs.o): Specify dependencies. + (expprint.o): Update dependencies. + (findvar.o): Update dependencies. + (frame.o): Update dependencies. + (std-regs.o): Update dependencies. + 2003-07-06 Christopher Faylor * win32-nat.c (solib_symbols_add): Use one variable for all section diff --git a/gdb/Makefile.in b/gdb/Makefile.in index e0f80b8e13..28f8583b27 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -510,7 +510,7 @@ TARGET_FLAGS_TO_PASS = \ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ ax-general.c ax-gdb.c \ - bcache.c block.c blockframe.c breakpoint.c buildsym.c builtin-regs.c \ + bcache.c block.c blockframe.c breakpoint.c buildsym.c \ c-exp.y c-lang.c c-typeprint.c c-valprint.c \ charset.c cli-out.c coffread.c coff-pe-read.c \ complaints.c completer.c corefile.c \ @@ -554,6 +554,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h \ tui/tui-file.h tui/tui-file.c tui/tui-out.c tui/tui-hooks.c \ ui-out.c utils.c ui-file.h ui-file.c \ + user-regs.c \ valarith.c valops.c valprint.c values.c varobj.c \ wrapper.c @@ -618,7 +619,6 @@ bcache_h = bcache.h block_h = block.h breakpoint_h = breakpoint.h $(frame_h) $(value_h) $(gdb_events_h) buildsym_h = buildsym.h -builtin_regs_h = builtin-regs.h c_lang_h = c-lang.h $(value_h) $(macroexp_h) call_cmds_h = call-cmds.h ch_lang_h = ch-lang.h @@ -749,6 +749,7 @@ tracepoint_h = tracepoint.h typeprint_h = typeprint.h ui_file_h = ui-file.h ui_out_h = ui-out.h +user_regs_h = user-regs.h valprint_h = valprint.h value_h = value.h $(doublest_h) $(frame_h) $(symtab_h) $(gdbtypes_h) $(expression_h) varobj_h = varobj.h $(symtab_h) $(gdbtypes_h) @@ -862,7 +863,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \ event-loop.o event-top.o inf-loop.o completer.o \ gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o $(DEPFILES) \ memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \ - builtin-regs.o std-regs.o \ + std-regs.o \ signals.o \ kod.o kod-cisco.o \ gdb-events.o \ @@ -882,6 +883,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \ c-valprint.o cp-valprint.o f-valprint.o m2-valprint.o \ nlmread.o serial.o mdebugread.o top.o utils.o \ ui-file.o \ + user-regs.o \ frame.o frame-unwind.o doublest.o \ frame-base.o \ gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \ @@ -1597,8 +1599,6 @@ buildsym.o: buildsym.c $(defs_h) $(bfd_h) $(gdb_obstack_h) $(symtab_h) \ $(complaints_h) $(gdb_string_h) $(expression_h) $(language_h) \ $(bcache_h) $(filenames_h) $(macrotab_h) $(demangle_h) $(buildsym_h) \ $(stabsread_h) $(block_h) $(cp_support_h) $(dictionary_h) -builtin-regs.o: builtin-regs.c $(defs_h) $(builtin_regs_h) $(gdbtypes_h) \ - $(gdb_string_h) $(gdb_assert_h) c-lang.o: c-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \ $(parser_defs_h) $(language_h) $(c_lang_h) $(valprint_h) \ $(macroscope_h) $(gdb_assert_h) $(charset_h) $(gdb_string_h) \ @@ -1728,8 +1728,8 @@ exec.o: exec.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) $(gdbcmd_h) \ $(gdb_string_h) $(gdbcore_h) $(gdb_stat_h) $(xcoffsolib_h) \ $(readline_h) expprint.o: expprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \ - $(value_h) $(language_h) $(parser_defs_h) $(target_h) $(gdb_string_h) \ - $(block_h) + $(value_h) $(language_h) $(parser_defs_h) $(user_regs_h) $(target_h) \ + $(gdb_string_h) $(block_h) f-lang.o: f-lang.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(expression_h) $(parser_defs_h) $(language_h) $(f_lang_h) \ $(valprint_h) $(value_h) @@ -1744,12 +1744,12 @@ fbsd-proc.o: fbsd-proc.c $(defs_h) $(gdbcore_h) $(inferior_h) \ findvar.o: findvar.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(frame_h) \ $(value_h) $(gdbcore_h) $(inferior_h) $(target_h) $(gdb_string_h) \ $(gdb_assert_h) $(floatformat_h) $(symfile_h) $(regcache_h) \ - $(builtin_regs_h) $(block_h) + $(user_regs_h) $(block_h) fork-child.o: fork-child.c $(defs_h) $(gdb_string_h) $(frame_h) \ $(inferior_h) $(target_h) $(gdb_wait_h) $(gdb_vfork_h) $(gdbcore_h) \ $(terminal_h) $(gdbthread_h) $(command_h) frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \ - $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(builtin_regs_h) \ + $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(user_regs_h) \ $(gdb_obstack_h) $(dummy_frame_h) $(sentinel_frame_h) $(gdbcore_h) \ $(annotate_h) $(language_h) $(frame_unwind_h) $(frame_base_h) \ $(command_h) $(gdbcmd_h) @@ -2288,7 +2288,7 @@ stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \ $(gdb_assert_h) $(dictionary_h) standalone.o: standalone.c $(gdb_stat_h) $(defs_h) $(symtab_h) $(frame_h) \ $(inferior_h) $(gdb_wait_h) -std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) $(gdbtypes_h) \ +std-regs.o: std-regs.c $(defs_h) $(user_regs_h) $(frame_h) $(gdbtypes_h) \ $(value_h) $(gdb_string_h) stop-gdb.o: stop-gdb.c $(defs_h) sun3-nat.o: sun3-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h) @@ -2342,6 +2342,8 @@ typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \ ui-file.o: ui-file.c $(defs_h) $(ui_file_h) $(gdb_string_h) ui-out.o: ui-out.c $(defs_h) $(gdb_string_h) $(expression_h) $(language_h) \ $(ui_out_h) $(gdb_assert_h) +user-regs.o: user-regs.c $(defs_h) $(user_regs_h) $(gdbtypes_h) \ + $(gdb_string_h) $(gdb_assert_h) $(frame_h) utils.o: utils.c $(config_h) $(defs_h) $(gdb_assert_h) $(gdb_string_h) \ $(event_top_h) $(gdbcmd_h) $(serial_h) $(bfd_h) $(target_h) \ $(demangle_h) $(expression_h) $(language_h) $(annotate_h) \ diff --git a/gdb/builtin-regs.c b/gdb/builtin-regs.c deleted file mode 100644 index 07e5fcca58..0000000000 --- a/gdb/builtin-regs.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Builtin registers, 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 "builtin-regs.h" -#include "gdbtypes.h" -#include "gdb_string.h" -#include "gdb_assert.h" - -/* Implement builtin register types. Builtin registers have regnum's - that live above of the range [0 .. NUM_REGS + NUM_PSEUDO_REGS) - (which is controlled by the target). The target should never see a - builtin register's regnum value. */ - -/* An array of builtin registers. Always append, never delete. By - doing this, the relative regnum (offset from NUM_REGS + - NUM_PSEUDO_REGS) assigned to each builtin register never changes. */ - -struct builtin_reg -{ - const char *name; - struct value *(*value) (struct frame_info * frame); -}; - -static struct builtin_reg *builtin_regs; -int nr_builtin_regs; - -void -add_builtin_reg (const char *name, struct value *(*value) (struct frame_info * frame)) -{ - nr_builtin_regs++; - builtin_regs = xrealloc (builtin_regs, - nr_builtin_regs * sizeof (builtin_regs[0])); - builtin_regs[nr_builtin_regs - 1].name = name; - builtin_regs[nr_builtin_regs - 1].value = value; -} - -int -builtin_reg_map_name_to_regnum (const char *name, int len) -{ - int reg; - for (reg = 0; reg < nr_builtin_regs; reg++) - { - if (len == strlen (builtin_regs[reg].name) - && strncmp (builtin_regs[reg].name, name, len) == 0) - return NUM_REGS + NUM_PSEUDO_REGS + reg; - } - return -1; -} - -const char * -builtin_reg_map_regnum_to_name (int regnum) -{ - int reg = regnum - (NUM_REGS + NUM_PSEUDO_REGS); - if (reg < 0 || reg >= nr_builtin_regs) - return NULL; - return builtin_regs[reg].name; -} - -struct value * -value_of_builtin_reg (int regnum, struct frame_info *frame) -{ - int reg = regnum - (NUM_REGS + NUM_PSEUDO_REGS); - gdb_assert (reg >= 0 && reg < nr_builtin_regs); - return builtin_regs[reg].value (frame); -} diff --git a/gdb/builtin-regs.h b/gdb/builtin-regs.h deleted file mode 100644 index 631903ab9f..0000000000 --- a/gdb/builtin-regs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Builtin registers, 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 BUILTIN_REGS_H -#define BUILTIN_REGS_H - -struct frame_info; - -extern int builtin_reg_map_name_to_regnum (const char *str, int len); - -extern const char *builtin_reg_map_regnum_to_name (int regnum); - -extern struct value *value_of_builtin_reg (int regnum, - struct frame_info *frame); - -extern void add_builtin_reg (const char *name, - struct value *(value) (struct frame_info * frame)); - -#endif diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index 8a6df8e919..135a0dd401 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -797,9 +797,9 @@ d10v_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, ULONGEST pc, psw, rpt_s, rpt_e, rpt_c; frame_read_unsigned_register (frame, D10V_PC_REGNUM, &pc); frame_read_unsigned_register (frame, PSW_REGNUM, &psw); - frame_read_unsigned_register (frame, frame_map_name_to_regnum ("rpt_s", -1), &rpt_s); - frame_read_unsigned_register (frame, frame_map_name_to_regnum ("rpt_e", -1), &rpt_e); - frame_read_unsigned_register (frame, frame_map_name_to_regnum ("rpt_c", -1), &rpt_c); + frame_read_unsigned_register (frame, frame_map_name_to_regnum (frame, "rpt_s", -1), &rpt_s); + frame_read_unsigned_register (frame, frame_map_name_to_regnum (frame, "rpt_e", -1), &rpt_e); + frame_read_unsigned_register (frame, frame_map_name_to_regnum (frame, "rpt_c", -1), &rpt_c); fprintf_filtered (file, "PC=%04lx (0x%lx) PSW=%04lx RPT_S=%04lx RPT_E=%04lx RPT_C=%04lx\n", (long) pc, (long) d10v_make_iaddr (pc), (long) psw, (long) rpt_s, (long) rpt_e, (long) rpt_c); diff --git a/gdb/eval.c b/gdb/eval.c index c266cd1e33..914a552070 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -454,7 +454,7 @@ evaluate_subexp_standard (struct type *expect_type, (*pos) += 2; if (val == NULL) error ("Value of register %s not available.", - frame_map_regnum_to_name (regno)); + frame_map_regnum_to_name (get_selected_frame (), regno)); else return val; } diff --git a/gdb/expprint.c b/gdb/expprint.c index d0e940b382..bbc63e7395 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -27,7 +27,7 @@ #include "value.h" #include "language.h" #include "parser-defs.h" -#include "frame.h" /* For frame_map_regnum_to_name. */ +#include "user-regs.h" /* For user_reg_map_regnum_to_name. */ #include "target.h" #include "gdb_string.h" #include "block.h" @@ -126,8 +126,10 @@ print_subexp (register struct expression *exp, register int *pos, case OP_REGISTER: { int regnum = longest_to_int (exp->elts[pc + 1].longconst); + const char *name = user_reg_map_regnum_to_name (current_gdbarch, + regnum); (*pos) += 2; - fprintf_filtered (stream, "$%s", frame_map_regnum_to_name (regnum)); + fprintf_filtered (stream, "$%s", name); return; } diff --git a/gdb/findvar.c b/gdb/findvar.c index 933146a78b..2e6a858ab6 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -34,7 +34,7 @@ #include "floatformat.h" #include "symfile.h" /* for overlay functions */ #include "regcache.h" -#include "builtin-regs.h" +#include "user-regs.h" #include "block.h" /* Basic byte-swapping routines. GDB has needed these for a long time... @@ -263,10 +263,10 @@ value_of_register (int regnum, struct frame_info *frame) char raw_buffer[MAX_REGISTER_SIZE]; enum lval_type lval; - /* Builtin registers lie completly outside of the range of normal + /* User registers lie completly outside of the range of normal registers. Catch them early so that the target never sees them. */ if (regnum >= NUM_REGS + NUM_PSEUDO_REGS) - return value_of_builtin_reg (regnum, frame); + return value_of_user_reg (regnum, frame); frame_register (frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer); diff --git a/gdb/frame.c b/gdb/frame.c index b241cc40ff..3793a068ca 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -28,7 +28,7 @@ #include "regcache.h" #include "gdb_assert.h" #include "gdb_string.h" -#include "builtin-regs.h" +#include "user-regs.h" #include "gdb_obstack.h" #include "dummy-frame.h" #include "sentinel-frame.h" @@ -497,7 +497,7 @@ frame_register_unwind (struct frame_info *frame, int regnum, { fprintf_unfiltered (gdb_stdlog, "{ frame_register_unwind (frame=%d,regnum=\"%s\",...) ", - frame->level, frame_map_regnum_to_name (regnum)); + frame->level, frame_map_regnum_to_name (frame, regnum)); } /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates @@ -773,42 +773,15 @@ frame_register_read (struct frame_info *frame, int regnum, void *myaddr) includes builtin registers. */ int -frame_map_name_to_regnum (const char *name, int len) +frame_map_name_to_regnum (struct frame_info *frame, const char *name, int len) { - int i; - - if (len < 0) - len = strlen (name); - - /* Search register name space. */ - for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++) - if (REGISTER_NAME (i) && len == strlen (REGISTER_NAME (i)) - && strncmp (name, REGISTER_NAME (i), len) == 0) - { - return i; - } - - /* Try builtin registers. */ - i = builtin_reg_map_name_to_regnum (name, len); - if (i >= 0) - { - /* A builtin register doesn't fall into the architecture's - register range. */ - gdb_assert (i >= NUM_REGS + NUM_PSEUDO_REGS); - return i; - } - - return -1; + return user_reg_map_name_to_regnum (get_frame_arch (frame), name, len); } const char * -frame_map_regnum_to_name (int regnum) +frame_map_regnum_to_name (struct frame_info *frame, int regnum) { - if (regnum < 0) - return NULL; - if (regnum < NUM_REGS + NUM_PSEUDO_REGS) - return REGISTER_NAME (regnum); - return builtin_reg_map_regnum_to_name (regnum); + return user_reg_map_regnum_to_name (get_frame_arch (frame), regnum); } /* Create a sentinel frame. */ diff --git a/gdb/frame.h b/gdb/frame.h index 87c20570c4..e821db6912 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -409,8 +409,10 @@ extern void put_frame_register (struct frame_info *frame, int regnum, includes builtin registers. If NAMELEN is negative, use the NAME's length when doing the comparison. */ -extern int frame_map_name_to_regnum (const char *name, int namelen); -extern const char *frame_map_regnum_to_name (int regnum); +extern int frame_map_name_to_regnum (struct frame_info *frame, + const char *name, int namelen); +extern const char *frame_map_regnum_to_name (struct frame_info *frame, + int regnum); /* Unwind the PC. Strictly speaking return the resume address of the calling frame. For GDB, `pc' is the resume address and not a diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 911e865cf4..df7d9508cc 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1651,7 +1651,8 @@ registers_info (char *addr_exp, int fpregs) /* A register name? */ { - int regnum = frame_map_name_to_regnum (start, end - start); + int regnum = frame_map_name_to_regnum (deprecated_selected_frame, + start, end - start); if (regnum >= 0) { gdbarch_print_registers_info (current_gdbarch, gdb_stdout, diff --git a/gdb/parse.c b/gdb/parse.c index 5db165ad4e..c16d313b29 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -455,7 +455,8 @@ write_dollar_variable (struct stoken str) /* Handle tokens that refer to machine registers: $ followed by a register name. */ - i = frame_map_name_to_regnum (str.ptr + 1, str.length - 1); + i = frame_map_name_to_regnum (deprecated_selected_frame, + str.ptr + 1, str.length - 1); if (i >= 0) goto handle_register; diff --git a/gdb/std-regs.c b/gdb/std-regs.c index 1241852383..1e8f3c8c8e 100644 --- a/gdb/std-regs.c +++ b/gdb/std-regs.c @@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "builtin-regs.h" +#include "user-regs.h" #include "frame.h" #include "gdbtypes.h" #include "value.h" @@ -147,14 +147,14 @@ _initialize_frame_reg (void) /* Frame based $fp, $pc, $sp and $ps. These only come into play when the target does not define its own version of these registers. */ - add_builtin_reg ("fp", value_of_builtin_frame_fp_reg); - add_builtin_reg ("pc", value_of_builtin_frame_pc_reg); - add_builtin_reg ("sp", value_of_builtin_frame_sp_reg); - add_builtin_reg ("ps", value_of_builtin_frame_ps_reg); + user_reg_add_builtin ("fp", value_of_builtin_frame_fp_reg); + user_reg_add_builtin ("pc", value_of_builtin_frame_pc_reg); + user_reg_add_builtin ("sp", value_of_builtin_frame_sp_reg); + user_reg_add_builtin ("ps", value_of_builtin_frame_ps_reg); /* NOTE: cagney/2002-04-05: For moment leave the $frame / $gdbframe / $gdb.frame disabled. It isn't yet clear which of the many options is the best. */ if (0) - add_builtin_reg ("frame", value_of_builtin_frame_reg); + user_reg_add_builtin ("frame", value_of_builtin_frame_reg); } diff --git a/gdb/user-regs.c b/gdb/user-regs.c new file mode 100644 index 0000000000..3d60b2f90f --- /dev/null +++ b/gdb/user-regs.c @@ -0,0 +1,186 @@ +/* User visible, per-frame registers, 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 "user-regs.h" +#include "gdbtypes.h" +#include "gdb_string.h" +#include "gdb_assert.h" +#include "frame.h" + +/* A table of user registers. + + User registers have regnum's that live above of the range [0 + .. NUM_REGS + NUM_PSEUDO_REGS) (which is controlled by the target). + The target should never see a user register's regnum value. + + Always append, never delete. By doing this, the relative regnum + (offset from NUM_REGS + NUM_PSEUDO_REGS) assigned to each user + register never changes. */ + +struct user_reg +{ + const char *name; + struct value *(*read) (struct frame_info * frame); +}; + +struct user_regs +{ + struct user_reg *user; + int nr; +}; + +static void +append_user_reg (struct user_regs *regs, + const char *name, user_reg_read_ftype *read) +{ + regs->nr++; + regs->user = xrealloc (regs->user, + regs->nr * sizeof (struct user_reg)); + regs->user[regs->nr - 1].name = name; + regs->user[regs->nr - 1].read = read; +} + +/* An array of the builtin user registers. */ + +static struct user_regs builtin_user_regs; + +void +user_reg_add_builtin (const char *name, user_reg_read_ftype *read) +{ + append_user_reg (&builtin_user_regs, name, read); +} + +/* Per-architecture user registers. Start with the builtin user + registers and then, again, append. */ + +static struct gdbarch_data *user_regs_data; + +static void * +user_regs_init (struct gdbarch *gdbarch) +{ + int i; + struct user_regs *regs = XMALLOC (struct user_regs); + memset (regs, 0, sizeof (struct user_regs)); + for (i = 0; i < builtin_user_regs.nr; i++) + append_user_reg (regs, builtin_user_regs.user[i].name, + builtin_user_regs.user[i].read); + return regs; +} + +static void +user_regs_free (struct gdbarch *gdbarch, void *data) +{ + struct user_regs *regs = data; + xfree (regs->user); + xfree (regs); +} + +void +user_reg_add (struct gdbarch *gdbarch, const char *name, + user_reg_read_ftype *read) +{ + struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + if (regs == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + regs = user_regs_init (gdbarch); + set_gdbarch_data (gdbarch, user_regs_data, regs); + } + append_user_reg (regs, name, read); +} + +int +user_reg_map_name_to_regnum (struct gdbarch *gdbarch, const char *name, + int len) +{ + /* Make life easy, set the len to something reasonable. */ + if (len < 0) + len = strlen (name); + + /* Search register name space first - always let an architecture + specific register override the user registers. */ + { + int i; + int maxregs = (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)); + for (i = 0; i < maxregs; i++) + { + const char *regname = gdbarch_register_name (gdbarch, i); + if (regname != NULL && len == strlen (regname) + && strncmp (regname, name, len) == 0) + { + return i; + } + } + } + + /* Search the user name space. */ + { + struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + int reg; + for (reg = 0; reg < regs->nr; reg++) + { + if ((len < 0 && strcmp (regs->user[reg].name, name)) + || (len == strlen (regs->user[reg].name) + && strncmp (regs->user[reg].name, name, len) == 0)) + return NUM_REGS + NUM_PSEUDO_REGS + reg; + } + } + + return -1; +} + +const char * +user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum) +{ + int maxregs = (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)); + struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + if (regnum < 0) + return NULL; + if (regnum < maxregs) + return gdbarch_register_name (gdbarch, regnum); + if (regnum < (maxregs + regs->nr)) + return regs->user[regnum - maxregs].name; + return NULL; +} + +struct value * +value_of_user_reg (int regnum, struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data); + int reg = regnum - (NUM_REGS + NUM_PSEUDO_REGS); + gdb_assert (reg >= 0 && reg < regs->nr); + return regs->user[reg].read (frame); +} + +extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */ + +void +_initialize_user_regs (void) +{ + user_regs_data = register_gdbarch_data (user_regs_init, user_regs_free); +} diff --git a/gdb/user-regs.h b/gdb/user-regs.h new file mode 100644 index 0000000000..efc5530cee --- /dev/null +++ b/gdb/user-regs.h @@ -0,0 +1,70 @@ +/* Per-frame user registers, for GDB, the GNU debugger. + + Copyright 2002, 2003 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 USER_REGS_H +#define USER_REGS_H + +/* Implement both builtin, and architecture specific, per-frame user + visible registers. + + Builtin registers apply to all architectures, where as architecture + specific registers are present when the architecture is selected. + + These registers are assigned register numbers outside the + architecture's register range [0 .. NUM_REGS + NUM_PSEUDO_REGS). + Their values should be constructed using per-frame information. */ + +/* TODO: cagney/2003-06-27: Need to think more about how these + registers are added, read, and modified. At present they are kind + of assumed to be read-only. Should it, for instance, return a + register descriptor that contains all the relvent access methods. */ + +struct frame_info; + +/* Given an architecture, map a user visible register name onto its + index. */ + +extern int user_reg_map_name_to_regnum (struct gdbarch *gdbarch, + const char *str, int len); + +extern const char *user_reg_map_regnum_to_name (struct gdbarch *gdbarch, + int regnum); + +/* Return the value of the frame register in the specified frame. + + Note; These methods return a "struct value" instead of the raw + bytes as, at the time the register is being added, the type needed + to describe the register has not bee initialized. */ + +typedef struct value *(user_reg_read_ftype) (struct frame_info *frame); +extern struct value *value_of_user_reg (int regnum, struct frame_info *frame); + +/* Add a builtin register (present in all architectures). */ +extern void user_reg_add_builtin (const char *name, + user_reg_read_ftype *read); + +/* Add a per-architecture frame register. */ +extern void user_reg_add (struct gdbarch *gdbarch, const char *name, + user_reg_read_ftype *read); + +#endif