This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch,rfc] builtin regs -> user regs


Hello,

Ref: Three register layers
http://sources.redhat.com/ml/gdb/2003-06/msg00437.html

This patch replaces the builtin registers with user [visible] per-frame registers.

The builtin registers were global - always present regardless of the architecture. These new user [visible] registers support both global, and per-architecture registers.

As with the above post, these registers live on top of the frame vis:

	user
	 |
	cooked/frame
	 |
	raw

and this makes it possible to construct user visible registers using per-frame register values. In the case of the MIPS, the 64 bit $fpr0 would be the concatenation of the two 32 bit registers: $fgr0 and $fgr1.

Please note though that the way registers are read/written needs further refinement (I left it as is for the moment). I suspect, for instance, that currently register writes don't work at all.

I'm also not comfortable with using `builtin' for the registers that apply to all architectures. Perhaphs:
user_reg_add_all
user_reg_add_global
are better. Thougts?


comments?
Andrew

(no this isn't for the 6.0 branch)
2003-06-29  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.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.411
diff -u -r1.411 Makefile.in
--- Makefile.in	28 Jun 2003 16:19:05 -0000	1.411
+++ Makefile.in	29 Jun 2003 15:01:31 -0000
@@ -510,7 +510,7 @@
 
 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 @@
 	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 @@
 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 @@
 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 @@
 	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 @@
 	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 @@
 	$(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 @@
 	$(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 @@
 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 @@
 	$(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 @@
 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) \
Index: builtin-regs.c
===================================================================
RCS file: builtin-regs.c
diff -N builtin-regs.c
--- builtin-regs.c	25 Sep 2002 20:30:37 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -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);
-}
Index: builtin-regs.h
===================================================================
RCS file: builtin-regs.h
diff -N builtin-regs.h
--- builtin-regs.h	12 Apr 2003 17:41:25 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -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
Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.125
diff -u -r1.125 d10v-tdep.c
--- d10v-tdep.c	13 Jun 2003 20:37:27 -0000	1.125
+++ d10v-tdep.c	29 Jun 2003 15:01:31 -0000
@@ -797,9 +797,9 @@
     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);
Index: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.30
diff -u -r1.30 eval.c
--- eval.c	30 Apr 2003 01:27:53 -0000	1.30
+++ eval.c	29 Jun 2003 15:01:32 -0000
@@ -454,7 +454,7 @@
 	(*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;
       }
Index: expprint.c
===================================================================
RCS file: /cvs/src/src/gdb/expprint.c,v
retrieving revision 1.16
diff -u -r1.16 expprint.c
--- expprint.c	25 Feb 2003 21:36:17 -0000	1.16
+++ expprint.c	29 Jun 2003 15:01:32 -0000
@@ -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 @@
     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;
       }
 
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.60
diff -u -r1.60 findvar.c
--- findvar.c	14 Jun 2003 22:35:23 -0000	1.60
+++ findvar.c	29 Jun 2003 15:01:33 -0000
@@ -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 @@
   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);
 
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.128
diff -u -r1.128 frame.c
--- frame.c	29 Jun 2003 13:27:26 -0000	1.128
+++ frame.c	29 Jun 2003 15:01:34 -0000
@@ -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 @@
     {
       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 @@
    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.  */
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.103
diff -u -r1.103 frame.h
--- frame.h	21 Jun 2003 16:51:47 -0000	1.103
+++ frame.h	29 Jun 2003 15:01:34 -0000
@@ -409,8 +409,10 @@
    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
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.82
diff -u -r1.82 infcmd.c
--- infcmd.c	17 Jun 2003 20:28:13 -0000	1.82
+++ infcmd.c	29 Jun 2003 15:01:35 -0000
@@ -1651,7 +1651,8 @@
 
       /* 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,
Index: parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.34
diff -u -r1.34 parse.c
--- parse.c	14 May 2003 17:43:18 -0000	1.34
+++ parse.c	29 Jun 2003 15:01:35 -0000
@@ -455,7 +455,8 @@
 
   /* 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;
 
Index: std-regs.c
===================================================================
RCS file: /cvs/src/src/gdb/std-regs.c,v
retrieving revision 1.7
diff -u -r1.7 std-regs.c
--- std-regs.c	8 Jun 2003 18:27:14 -0000	1.7
+++ std-regs.c	29 Jun 2003 15:01:36 -0000
@@ -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 @@
   /* 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);
 }
Index: user-regs.c
===================================================================
RCS file: user-regs.c
diff -N user-regs.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ user-regs.c	29 Jun 2003 15:01:36 -0000
@@ -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);
+}
Index: user-regs.h
===================================================================
RCS file: user-regs.h
diff -N user-regs.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ user-regs.h	29 Jun 2003 15:01:36 -0000
@@ -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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]