summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog30
-rw-r--r--gdb/Makefile.in22
-rw-r--r--gdb/builtin-regs.c86
-rw-r--r--gdb/builtin-regs.h39
-rw-r--r--gdb/d10v-tdep.c6
-rw-r--r--gdb/eval.c2
-rw-r--r--gdb/expprint.c6
-rw-r--r--gdb/findvar.c6
-rw-r--r--gdb/frame.c39
-rw-r--r--gdb/frame.h6
-rw-r--r--gdb/infcmd.c3
-rw-r--r--gdb/parse.c3
-rw-r--r--gdb/std-regs.c12
-rw-r--r--gdb/user-regs.c186
-rw-r--r--gdb/user-regs.h70
15 files changed, 329 insertions, 187 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index daf3c131980..e3f6e382889 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,33 @@
+2003-07-07 Andrew Cagney <cagney@redhat.com>
+
+ * 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 <cgf@redhat.com>
* win32-nat.c (solib_symbols_add): Use one variable for all section
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index e0f80b8e133..28f8583b270 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 07e5fcca58a..00000000000
--- 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 631903ab9fb..00000000000
--- 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 8a6df8e9199..135a0dd401a 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 c266cd1e33e..914a5520704 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 d0e940b3821..bbc63e73954 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 933146a78bc..2e6a858ab69 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 b241cc40ffb..3793a068ca8 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 87c20570c48..e821db6912b 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 911e865cf4e..df7d9508cca 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 5db165ad4e0..c16d313b29c 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 1241852383a..1e8f3c8c8e6 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 00000000000..3d60b2f90f6
--- /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 00000000000..efc5530ceee
--- /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