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] Re-implement ``standard registers''


Hello,

This follows up a WIP patch I sent out a few months ago.  It 
re-implements the ``Standard Registers''.  For background, see:

http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=251
http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC60

In a follow-on patch I'll be removing the existing std-reg code 
(parse.c) and that nasty piece of work that sometimes maps $fp <-> 
frame->base.

With the two patches committed, GDB should match its documentation.

After that, the $frame.base register can be disabled (or what ever it is 
called).

enjoy,
Andrew
2002-04-06  Andrew Cagney  <ac131313@redhat.com>

	* findvar.c: Include "builtin-regs.h".
	(value_of_register): Call value_of_builtin_reg when applicable.
	* parse.c: Include "builtin-regs.h" and "gdb_assert.h".
	(target_map_name_to_register): Call
	builtin_reg_map_name_to_regnum.
	* Makefile.in (SFILES): Add builtin-regs.c and std-regs.c.
	(COMMON_OBS): Add builtin-regs.o and std-regs.o.
	(builtin_regs_h): Define.
	(builtin-regs.o): New target.
	(findvar.o): Add $(builtin_regs_h).
	* builtin-regs.c, builtin-regs.h: New files.
	* std-regs.c: New file.
	Partial fix for PR gdb/251.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.167
diff -u -r1.167 Makefile.in
--- Makefile.in	2002/03/29 01:22:41	1.167
+++ Makefile.in	2002/04/06 18:05:05
@@ -550,6 +550,7 @@
 	tui/tui-file.h tui/tui-file.c tui/tui-out.c tui/tui-hooks.c \
 	ui-file.h ui-file.c \
 	frame.c doublest.c \
+	builtin-regs.c std-regs.c \
 	gnu-v2-abi.c gnu-v3-abi.c hpacc-abi.c cp-abi.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
@@ -589,6 +590,7 @@
 arch_utils_h =	arch-utils.h
 ax_h = 		ax.h $(doublest_h)
 bcache_h =	bcache.h
+builtin_regs_h = builtin-regs.h
 breakpoint_h =	breakpoint.h $(frame_h) $(value_h)
 buildsym_h =	buildsym.h
 c_lang_h =	c-lang.h $(value_h)
@@ -708,6 +710,7 @@
 	event-loop.o event-top.o inf-loop.o completer.o \
 	gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
 	memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
+	builtin-regs.o std-regs.o \
 	signals.o \
 	kod.o kod-cisco.o \
 	gdb-events.o \
@@ -1273,6 +1276,9 @@
 buildsym.o: buildsym.c $(bfd_h) $(buildsym_h) $(complaints_h) $(defs_h) \
 	$(objfiles_h) $(symfile_h) $(symtab_h) $(gdb_string_h)
 
+builtin-regs.o: builtin-regs.c $(defs.h) $(builtin_regs_h) $(gdbtypes_h) \
+	$(gdb_string_h) $(value_h) $(frame_h)
+
 c-lang.o: c-lang.c $(c_lang_h) $(defs_h) $(expression_h) $(gdbtypes_h) \
 	$(language_h) $(parser_defs_h) $(symtab_h)
 
@@ -1407,7 +1413,7 @@
 	$(language_h) $(parser_defs_h) $(symtab_h) $(value_h)
 
 findvar.o: findvar.c $(defs_h) $(gdbcore_h) $(inferior_h) $(target_h) \
-	$(gdb_string_h) $(regcache_h)
+	$(gdb_string_h) $(regcache_h) $(builtin_regs_h)
 
 frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \
 	$(regcache_h)
@@ -1802,6 +1808,9 @@
 	$(gdb_stabs_h) $(objfiles_h) $(symfile_h) $(symtab_h) $(gdb_string_h)
 
 somsolib.o: somsolib.c $(defs_h) $(regcache_h)
+
+std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) \
+	$(gdbtypes_h) $(value_h)
 
 pa64solib.o: pa64solib.c $(defs_h) $(regcache_h)
 
Index: builtin-regs.c
===================================================================
RCS file: builtin-regs.c
diff -N builtin-regs.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ builtin-regs.c	Sat Apr  6 10:05:05 2002
@@ -0,0 +1,77 @@
+/* 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;
+}
+
+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
--- /dev/null	Tue May  5 13:32:27 1998
+++ builtin-regs.h	Sat Apr  6 10:05:05 2002
@@ -0,0 +1,35 @@
+/* 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
+
+extern int builtin_reg_map_name_to_regnum (const char *str, int len);
+
+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: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.30
diff -u -r1.30 findvar.c
--- findvar.c	2002/04/05 22:04:41	1.30
+++ findvar.c	2002/04/06 18:05:09
@@ -33,6 +33,7 @@
 #include "floatformat.h"
 #include "symfile.h"		/* for overlay functions */
 #include "regcache.h"
+#include "builtin-regs.h"
 
 /* Basic byte-swapping routines.  GDB has needed these for a long time...
    All extract a target-format integer at ADDR which is LEN bytes long.  */
@@ -298,6 +299,11 @@
   struct value *reg_val;
   char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
   enum lval_type lval;
+
+  /* Builtin 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, selected_frame);
 
   get_saved_register (raw_buffer, &optim, &addr,
 		      frame, regnum, &lval);
Index: parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.20
diff -u -r1.20 parse.c
--- parse.c	2002/04/05 22:04:41	1.20
+++ parse.c	2002/04/06 18:05:10
@@ -47,6 +47,8 @@
 #include "inferior.h"		/* for NUM_PSEUDO_REGS.  NOTE: replace 
 				   with "gdbarch.h" when appropriate.  */
 #include "doublest.h"
+#include "builtin-regs.h"
+#include "gdb_assert.h"
 
 
 /* Symbols which architectures can redefine.  */
@@ -132,6 +134,14 @@
       {
 	return std_regs[i].regnum;
       }
+
+  /* Try builtin registers.  */
+  i = builtin_reg_map_name_to_regnum (str, len);
+  if (i >= 0)
+    {
+      gdb_assert (i >= NUM_REGS + NUM_PSEUDO_REGS);
+      return i;
+    }
 
   return -1;
 }
Index: std-regs.c
===================================================================
RCS file: std-regs.c
diff -N std-regs.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ std-regs.c	Sat Apr  6 10:05:10 2002
@@ -0,0 +1,150 @@
+/* Builtin frame register, 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 "frame.h"
+#include "gdbtypes.h"
+#include "value.h"
+
+/* Types that describe the various builtin registers.  */
+
+static struct type *builtin_type_frame_reg;
+
+/* Constructors for those types.  */
+
+static void
+build_builtin_type_frame_reg (void)
+{
+  /* $frame.  */
+  if (builtin_type_frame_reg == NULL)
+    {
+#if 0
+      struct frame
+      {
+	void *base;
+      };
+#endif
+      builtin_type_frame_reg = init_composite_type ("frame", TYPE_CODE_STRUCT);
+      append_composite_type_field (builtin_type_frame_reg, "base",
+				   builtin_type_void_data_ptr);
+    }
+}
+
+static struct value *
+value_of_builtin_frame_reg (struct frame_info *frame)
+{
+  struct value *val;
+  char *buf;
+  build_builtin_type_frame_reg ();
+  val = allocate_value (builtin_type_frame_reg);
+  VALUE_LVAL (val) = not_lval;
+  buf = VALUE_CONTENTS_RAW (val);
+  memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+  /* frame.base.  */
+  if (frame != NULL)
+    ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, frame->frame);
+  buf += TYPE_LENGTH (builtin_type_void_data_ptr);
+  /* frame.XXX.  */
+  return val;
+}
+
+static struct value *
+value_of_builtin_frame_fp_reg (struct frame_info *frame)
+{
+#ifdef FP_REGNUM
+  if (FP_REGNUM >= 0)
+    return value_of_register (FP_REGNUM, frame);
+#endif
+  {
+    struct value *val = allocate_value (builtin_type_void_data_ptr);
+    char *buf = VALUE_CONTENTS_RAW (val);
+    if (frame == NULL)
+      memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+    else
+      ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, frame->frame);
+    return val;
+  }
+}
+
+static struct value *
+value_of_builtin_frame_pc_reg (struct frame_info *frame)
+{
+#ifdef PC_REGNUM
+  if (PC_REGNUM >= 0)
+    return value_of_register (PC_REGNUM, frame);
+#endif
+  {
+    struct value *val = allocate_value (builtin_type_void_data_ptr);
+    char *buf = VALUE_CONTENTS_RAW (val);
+    if (frame == NULL)
+      memset (buf, TYPE_LENGTH (VALUE_TYPE (val)), 0);
+    else
+      ADDRESS_TO_POINTER (builtin_type_void_data_ptr, buf, frame->pc);
+    return val;
+  }
+}
+
+static struct value *
+value_of_builtin_frame_sp_reg (struct frame_info *frame)
+{
+#ifdef SP_REGNUM
+  if (SP_REGNUM >= 0)
+    return value_of_register (SP_REGNUM, frame);
+#endif
+  error ("Standard register ``$sp'' is not available for this target");
+}
+
+static struct value *
+value_of_builtin_frame_ps_reg (struct frame_info *frame)
+{
+#ifdef PS_REGNUM
+  if (PS_REGNUM >= 0)
+    return value_of_register (PS_REGNUM, frame);
+#endif
+  error ("Standard register ``$ps'' is not available for this target");
+}
+
+void
+_initialize_frame_reg (void)
+{
+  /* FIXME: cagney/2002-02-08: At present the local builtin types
+     can't be initialized using _initialize*() or gdbarch.  Due mainly
+     to non-multi-arch targets, GDB initializes things piece meal and,
+     as a consequence can leave these types NULL.  */
+  REGISTER_GDBARCH_SWAP (builtin_type_frame_reg);
+
+  /* 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);
+
+  /* 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);
+}

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