This is the mail archive of the gdb-patches@sourceware.org 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]

[rfc] Remove current_gdbarch register handling from symbol readers


Hello,

this patch removes most of the remaining instances of current_gdbarch 
from the symbol readers.  These are all related to handling register
numbers.   The problem is that during symbol reading, we may not
actually know the GDB register numbers for the target -- those may
change once we actually connect to a target which may provide its
own target description.

What the patch does is to delay register renaming by storing the
original number from the debug info into SYMBOL_VALUE, and perform
the conversion to a GDB register number only when debug info is
actually used -- at which time we must have a frame context in
order to evaluate "register" symbols, so we can use the correct
architecture.

This is implemented by extending the SYMBOL_OPS field, which is
currently only used for LOC_COMPUTED types, to also provide
callback routine for LOC_REGISTER (and LOC_REGPARM_ADDR) types.
All symbol readers using those types are adapted to provide
an appropriate implementation of the callback.

Tested on powerpc64-linux and amd64-linux (also with stabs).
Any comments are welcome; I'm planning to commit in about a week.


Bye,
Ulrich

ChangeLog:

	* symtab.h: Rename SYMBOL_OPS to SYMBOL_COMPUTED_OPS.
	* ax-gdb.c (gen_var_ref): Likewise.
	* findvar.c (read_var_value, symbol_read_needs_frame): Likewise.
	* printcmd.c (address_info): Likewise.
	* dwarf2loc.c (dwarf_expr_frame_base): Likewise.
	* dwarf2read.c (dwarf2_symbol_mark_computed): Likewise.
	* symtab.h: Rename struct symbol_ops to struct symbol_computed_ops.
	* dwarf2loc.h: Likewise.
	* dwarf2loc.c (dwarf2_locexpr_funcs, dwarf2_loclist_funcs): Likewise.

	* symtab.h: (struct symbol_register_ops): New struct definition.
	(struct symbol): Make "ops" member a union of symbol_computed_ops and
	symbol_register_ops callback pointers.
	(SYMBOL_REGISTER_OPS): New macro.
	* tracepoint.c: Include "objfiles.h".
	(scope_info, collect_symbol): Use SYMBOL_REGISTER_OPS register_number
	callback to retrieve register numbers.
	* ax-gdb.c (gen_var_ref): Likewise.
	* findvar.c (read_var_value): Likewise.
	* printcmd.c (address_info): Likewise.
	* tracepoint.c (scope_info, collect_symbol): Likewise.

	* coffread.c (coff_reg_to_regnum): New function.
	(coff_register_funcs): New static variable.
	(process_coff_symbol): Do not call gdbarch_sdb_reg_to_regnum.
	Install SYMBOL_REGISTER_OPS callbacks.
	* mdebugread.c (mdebug_reg_to_regnum): New function.
	(mdebug_register_funcs): New static variable.
	(parse_symbol): Do not call gdbarch_ecoff_reg_to_regnum.
	Install SYMBOL_REGISTER_OPS callbacks.
	* stabsread.c (stab_reg_to_regnum): New function.
	(stab_register_funcs): New static variable.
	(define_symbol): Do not call gdbarch_stab_reg_to_regnum.
	Install SYMBOL_REGISTER_OPS callbacks.


Index: gdb-head/gdb/ax-gdb.c
===================================================================
--- gdb-head.orig/gdb/ax-gdb.c
+++ gdb-head/gdb/ax-gdb.c
@@ -592,7 +592,7 @@ gen_var_ref (struct gdbarch *gdbarch, st
          this as an lvalue or rvalue, the caller will generate the
          right code.  */
       value->kind = axs_lvalue_register;
-      value->u.reg = SYMBOL_VALUE (var);
+      value->u.reg = SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch);
       break;
 
       /* A lot like LOC_REF_ARG, but the pointer lives directly in a
@@ -600,7 +600,7 @@ gen_var_ref (struct gdbarch *gdbarch, st
          because it's just like any other case where the thing
 	 has a real address.  */
     case LOC_REGPARM_ADDR:
-      ax_reg (ax, SYMBOL_VALUE (var));
+      ax_reg (ax, SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch));
       value->kind = axs_lvalue_memory;
       break;
 
@@ -619,11 +619,11 @@ gen_var_ref (struct gdbarch *gdbarch, st
 
     case LOC_COMPUTED:
       /* FIXME: cagney/2004-01-26: It should be possible to
-	 unconditionally call the SYMBOL_OPS method when available.
+	 unconditionally call the SYMBOL_COMPUTED_OPS method when available.
 	 Unfortunately DWARF 2 stores the frame-base (instead of the
 	 function) location in a function's symbol.  Oops!  For the
 	 moment enable this when/where applicable.  */
-      SYMBOL_OPS (var)->tracepoint_var_ref (var, ax, value);
+      SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, ax, value);
       break;
 
     case LOC_OPTIMIZED_OUT:
Index: gdb-head/gdb/coffread.c
===================================================================
--- gdb-head.orig/gdb/coffread.c
+++ gdb-head/gdb/coffread.c
@@ -1469,6 +1469,16 @@ patch_opaque_types (struct symtab *s)
     }
 }
 
+static int
+coff_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+  return gdbarch_sdb_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops coff_register_funcs = {
+  coff_reg_to_regnum
+};
+
 static struct symbol *
 process_coff_symbol (struct coff_symbol *cs,
 		     union internal_auxent *aux,
@@ -1549,8 +1559,8 @@ process_coff_symbol (struct coff_symbol 
 #endif
 	case C_REG:
 	  SYMBOL_CLASS (sym) = LOC_REGISTER;
-	  SYMBOL_VALUE (sym) = gdbarch_sdb_reg_to_regnum
-				 (current_gdbarch, cs->c_value);
+	  SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+	  SYMBOL_VALUE (sym) = cs->c_value;
 	  add_symbol_to_list (sym, &local_symbols);
 	  break;
 
@@ -1566,9 +1576,9 @@ process_coff_symbol (struct coff_symbol 
 
 	case C_REGPARM:
 	  SYMBOL_CLASS (sym) = LOC_REGISTER;
+	  SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
 	  SYMBOL_IS_ARGUMENT (sym) = 1;
-	  SYMBOL_VALUE (sym) = gdbarch_sdb_reg_to_regnum
-				 (current_gdbarch, cs->c_value);
+	  SYMBOL_VALUE (sym) = cs->c_value;
 	  add_symbol_to_list (sym, &local_symbols);
 	  break;
 
Index: gdb-head/gdb/dwarf2loc.c
===================================================================
--- gdb-head.orig/gdb/dwarf2loc.c
+++ gdb-head/gdb/dwarf2loc.c
@@ -154,7 +154,7 @@ dwarf_expr_frame_base (void *baton, gdb_
      something has gone wrong.  */
   gdb_assert (framefunc != NULL);
 
-  if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs)
+  if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
     {
       struct dwarf2_loclist_baton *symbaton;
       struct frame_info *frame = debaton->frame;
@@ -532,7 +532,7 @@ locexpr_tracepoint_var_ref (struct symbo
 
 /* The set of location functions used with the DWARF-2 expression
    evaluator.  */
-const struct symbol_ops dwarf2_locexpr_funcs = {
+const struct symbol_computed_ops dwarf2_locexpr_funcs = {
   locexpr_read_variable,
   locexpr_read_needs_frame,
   locexpr_describe_location,
@@ -610,7 +610,7 @@ loclist_tracepoint_var_ref (struct symbo
 
 /* The set of location functions used with the DWARF-2 expression
    evaluator and location lists.  */
-const struct symbol_ops dwarf2_loclist_funcs = {
+const struct symbol_computed_ops dwarf2_loclist_funcs = {
   loclist_read_variable,
   loclist_read_needs_frame,
   loclist_describe_location,
Index: gdb-head/gdb/dwarf2loc.h
===================================================================
--- gdb-head.orig/gdb/dwarf2loc.h
+++ gdb-head/gdb/dwarf2loc.h
@@ -20,7 +20,7 @@
 #if !defined (DWARF2LOC_H)
 #define DWARF2LOC_H
 
-struct symbol_ops;
+struct symbol_computed_ops;
 struct objfile;
 struct dwarf2_per_cu_data;
 
@@ -69,7 +69,7 @@ struct dwarf2_loclist_baton
   struct dwarf2_per_cu_data *per_cu;
 };
 
-extern const struct symbol_ops dwarf2_locexpr_funcs;
-extern const struct symbol_ops dwarf2_loclist_funcs;
+extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
+extern const struct symbol_computed_ops dwarf2_loclist_funcs;
 
 #endif /* dwarf2loc.h */
Index: gdb-head/gdb/dwarf2read.c
===================================================================
--- gdb-head.orig/gdb/dwarf2read.c
+++ gdb-head/gdb/dwarf2read.c
@@ -10471,7 +10471,7 @@ dwarf2_symbol_mark_computed (struct attr
 	complaint (&symfile_complaints,
 		   _("Location list used without specifying the CU base address."));
 
-      SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
+      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
@@ -10501,7 +10501,7 @@ dwarf2_symbol_mark_computed (struct attr
 	  baton->data = NULL;
 	}
       
-      SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
Index: gdb-head/gdb/findvar.c
===================================================================
--- gdb-head.orig/gdb/findvar.c
+++ gdb-head/gdb/findvar.c
@@ -347,11 +347,11 @@ symbol_read_needs_frame (struct symbol *
          we failed to consider one.  */
     case LOC_COMPUTED:
       /* FIXME: cagney/2004-01-26: It should be possible to
-	 unconditionally call the SYMBOL_OPS method when available.
+	 unconditionally call the SYMBOL_COMPUTED_OPS method when available.
 	 Unfortunately DWARF 2 stores the frame-base (instead of the
 	 function) location in a function's symbol.  Oops!  For the
 	 moment enable this when/where applicable.  */
-      return SYMBOL_OPS (sym)->read_needs_frame (sym);
+      return SYMBOL_COMPUTED_OPS (sym)->read_needs_frame (sym);
 
     case LOC_REGISTER:
     case LOC_ARG:
@@ -486,7 +486,8 @@ read_var_value (struct symbol *var, stru
     case LOC_REGISTER:
     case LOC_REGPARM_ADDR:
       {
-	int regno = SYMBOL_VALUE (var);
+	int regno = SYMBOL_REGISTER_OPS (var)
+		      ->register_number (var, get_frame_arch (frame));
 	struct value *regval;
 
 	if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
@@ -514,11 +515,11 @@ read_var_value (struct symbol *var, stru
 
     case LOC_COMPUTED:
       /* FIXME: cagney/2004-01-26: It should be possible to
-	 unconditionally call the SYMBOL_OPS method when available.
+	 unconditionally call the SYMBOL_COMPUTED_OPS method when available.
 	 Unfortunately DWARF 2 stores the frame-base (instead of the
 	 function) location in a function's symbol.  Oops!  For the
 	 moment enable this when/where applicable.  */
-      return SYMBOL_OPS (var)->read_variable (var, frame);
+      return SYMBOL_COMPUTED_OPS (var)->read_variable (var, frame);
 
     case LOC_UNRESOLVED:
       {
Index: gdb-head/gdb/mdebugread.c
===================================================================
--- gdb-head.orig/gdb/mdebugread.c
+++ gdb-head/gdb/mdebugread.c
@@ -528,6 +528,16 @@ add_pending (FDR *fh, char *sh, struct t
    SYMR's handled (normally one).  */
 
 static int
+mdebug_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+  return gdbarch_ecoff_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+}
+
+static const struct symbol_register_ops mdebug_register_funcs = {
+  mdebug_reg_to_regnum
+};
+
+static int
 parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 	      struct section_offsets *section_offsets, struct objfile *objfile)
 {
@@ -607,16 +617,16 @@ parse_symbol (SYMR *sh, union aux_ext *a
       goto data;
 
     case stLocal:		/* local variable, goes into current block */
+      b = top_stack->cur_block;
+      s = new_symbol (name);
+      SYMBOL_VALUE (s) = svalue;
       if (sh->sc == scRegister)
 	{
 	  class = LOC_REGISTER;
-	  svalue = gdbarch_ecoff_reg_to_regnum (current_gdbarch, svalue);
+	  SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
 	}
       else
 	class = LOC_LOCAL;
-      b = top_stack->cur_block;
-      s = new_symbol (name);
-      SYMBOL_VALUE (s) = svalue;
 
     data:			/* Common code for symbols describing data */
       SYMBOL_DOMAIN (s) = VAR_DOMAIN;
@@ -649,7 +659,7 @@ parse_symbol (SYMR *sh, union aux_ext *a
 	case scRegister:
 	  /* Pass by value in register.  */
 	  SYMBOL_CLASS (s) = LOC_REGISTER;
-	  svalue = gdbarch_ecoff_reg_to_regnum (current_gdbarch, svalue);
+	  SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
 	  break;
 	case scVar:
 	  /* Pass by reference on stack.  */
@@ -658,7 +668,7 @@ parse_symbol (SYMR *sh, union aux_ext *a
 	case scVarRegister:
 	  /* Pass by reference in register.  */
 	  SYMBOL_CLASS (s) = LOC_REGPARM_ADDR;
-	  svalue = gdbarch_ecoff_reg_to_regnum (current_gdbarch, svalue);
+	  SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
 	  break;
 	default:
 	  /* Pass by value on stack.  */
Index: gdb-head/gdb/printcmd.c
===================================================================
--- gdb-head.orig/gdb/printcmd.c
+++ gdb-head/gdb/printcmd.c
@@ -1091,6 +1091,8 @@ sym_info (char *arg, int from_tty)
 static void
 address_info (char *exp, int from_tty)
 {
+  struct gdbarch *gdbarch;
+  int regno;
   struct symbol *sym;
   struct minimal_symbol *msymbol;
   long val;
@@ -1153,6 +1155,7 @@ address_info (char *exp, int from_tty)
   printf_filtered ("\" is ");
   val = SYMBOL_VALUE (sym);
   section = SYMBOL_OBJ_SECTION (sym);
+  gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
 
   switch (SYMBOL_CLASS (sym))
     {
@@ -1177,20 +1180,28 @@ address_info (char *exp, int from_tty)
 
     case LOC_COMPUTED:
       /* FIXME: cagney/2004-01-26: It should be possible to
-	 unconditionally call the SYMBOL_OPS method when available.
+	 unconditionally call the SYMBOL_COMPUTED_OPS method when available.
 	 Unfortunately DWARF 2 stores the frame-base (instead of the
 	 function) location in a function's symbol.  Oops!  For the
 	 moment enable this when/where applicable.  */
-      SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
+      SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
       break;
 
     case LOC_REGISTER:
+      /* GDBARCH is the architecture associated with the objfile the symbol
+	 is defined in; the target architecture may be different, and may
+	 provide additional registers.  However, we do not know the target
+	 architecture at this point.  We assume the objfile architecture
+	 will contain all the standard registers that occur in debug info
+	 in that objfile.  */
+      regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
+
       if (SYMBOL_IS_ARGUMENT (sym))
 	printf_filtered (_("an argument in register %s"),
-			 gdbarch_register_name (current_gdbarch, val));
+			 gdbarch_register_name (gdbarch, regno));
       else
 	printf_filtered (_("a variable in register %s"),
-			 gdbarch_register_name (current_gdbarch, val));
+			 gdbarch_register_name (gdbarch, regno));
       break;
 
     case LOC_STATIC:
@@ -1208,8 +1219,10 @@ address_info (char *exp, int from_tty)
       break;
 
     case LOC_REGPARM_ADDR:
+      /* Note comment at LOC_REGISTER.  */
+      regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
       printf_filtered (_("address of an argument in register %s"),
-		       gdbarch_register_name (current_gdbarch, val));
+		       gdbarch_register_name (gdbarch, regno));
       break;
 
     case LOC_ARG:
Index: gdb-head/gdb/stabsread.c
===================================================================
--- gdb-head.orig/gdb/stabsread.c
+++ gdb-head/gdb/stabsread.c
@@ -579,6 +579,29 @@ symbol_reference_defined (char **string)
     }
 }
 
+static int
+stab_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
+{
+  int regno = gdbarch_stab_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
+
+  if (regno >= gdbarch_num_regs (gdbarch)
+		+ gdbarch_num_pseudo_regs (gdbarch))
+    {
+      reg_value_complaint (regno,
+			   gdbarch_num_regs (gdbarch)
+			     + gdbarch_num_pseudo_regs (gdbarch),
+			   SYMBOL_PRINT_NAME (sym));
+
+      regno = gdbarch_sp_regnum (gdbarch); /* Known safe, though useless */
+    }
+
+  return regno;
+}
+
+static const struct symbol_register_ops stab_register_funcs = {
+  stab_reg_to_regnum
+};
+
 struct symbol *
 define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	       struct objfile *objfile)
@@ -993,18 +1016,9 @@ define_symbol (CORE_ADDR valu, char *str
       /* Parameter which is in a register.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_REGISTER;
+      SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
       SYMBOL_IS_ARGUMENT (sym) = 1;
-      SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
-      if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
-				  + gdbarch_num_pseudo_regs (current_gdbarch))
-	{
-	  reg_value_complaint (SYMBOL_VALUE (sym),
-			       gdbarch_num_regs (current_gdbarch)
-				 + gdbarch_num_pseudo_regs (current_gdbarch),
-			       SYMBOL_PRINT_NAME (sym));
-	  SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
-	  /* Known safe, though useless */
-	}
+      SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
       break;
@@ -1013,17 +1027,8 @@ define_symbol (CORE_ADDR valu, char *str
       /* Register variable (either global or local).  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_REGISTER;
-      SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
-      if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
-				+ gdbarch_num_pseudo_regs (current_gdbarch))
-	{
-	  reg_value_complaint (SYMBOL_VALUE (sym),
-			       gdbarch_num_regs (current_gdbarch)
-				 + gdbarch_num_pseudo_regs (current_gdbarch),
-			       SYMBOL_PRINT_NAME (sym));
-	  SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
-	  /* Known safe, though useless */
-	}
+      SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
+      SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       if (within_function)
 	{
@@ -1059,6 +1064,7 @@ define_symbol (CORE_ADDR valu, char *str
 			     SYMBOL_LINKAGE_NAME (sym)) == 0)
 		{
 		  SYMBOL_CLASS (prev_sym) = LOC_REGISTER;
+		  SYMBOL_REGISTER_OPS (prev_sym) = &stab_register_funcs;
 		  /* Use the type from the LOC_REGISTER; that is the type
 		     that is actually in that register.  */
 		  SYMBOL_TYPE (prev_sym) = SYMBOL_TYPE (sym);
@@ -1296,18 +1302,9 @@ define_symbol (CORE_ADDR valu, char *str
       /* Reference parameter which is in a register.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+      SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
       SYMBOL_IS_ARGUMENT (sym) = 1;
-      SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
-      if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
-				+ gdbarch_num_pseudo_regs (current_gdbarch))
-	{
-	  reg_value_complaint (SYMBOL_VALUE (sym),
-			       gdbarch_num_regs (current_gdbarch)
-				 + gdbarch_num_pseudo_regs (current_gdbarch),
-			       SYMBOL_PRINT_NAME (sym));
-	  SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
-	  /* Known safe, though useless */
-	}
+      SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
       break;
Index: gdb-head/gdb/symtab.h
===================================================================
--- gdb-head.orig/gdb/symtab.h
+++ gdb-head/gdb/symtab.h
@@ -414,7 +414,11 @@ enum address_class
 
   LOC_STATIC,
 
-  /* Value is in register.  SYMBOL_VALUE is the register number.
+  /* Value is in register.  SYMBOL_VALUE is the register number
+     in the original debug format.  SYMBOL_REGISTER_OPS holds a
+     function that can be called to transform this into the
+     actual register number this represents in a specific target
+     architecture (gdbarch).
 
      For some symbol formats (stabs, for some compilers at least),
      the compiler generates two symbols, an argument and a register.
@@ -488,16 +492,16 @@ enum address_class
   LOC_OPTIMIZED_OUT,
 
   /* The variable's address is computed by a set of location
-     functions (see "struct symbol_ops" below).  */
+     functions (see "struct symbol_computed_ops" below).  */
   LOC_COMPUTED,
 };
 
-/* The methods needed to implement a symbol class.  These methods can
+/* The methods needed to implement LOC_COMPUTED.  These methods can
    use the symbol's .aux_value for additional per-symbol information.
 
    At present this is only used to implement location expressions.  */
 
-struct symbol_ops
+struct symbol_computed_ops
 {
 
   /* Return the value of the variable SYMBOL, relative to the stack
@@ -527,6 +531,13 @@ struct symbol_ops
 			      struct axs_value * value);
 };
 
+/* Functions used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
+
+struct symbol_register_ops
+{
+  int (*register_number) (struct symbol *symbol, struct gdbarch *gdbarch);
+};
+
 /* This structure is space critical.  See space comments at the top. */
 
 struct symbol
@@ -571,7 +582,14 @@ struct symbol
   /* Method's for symbol's of this class.  */
   /* NOTE: cagney/2003-11-02: See comment above attached to "aclass".  */
 
-  const struct symbol_ops *ops;
+  union
+    {
+      /* Used with LOC_COMPUTED.  */
+      const struct symbol_computed_ops *ops_computed;
+
+      /* Used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
+      const struct symbol_register_ops *ops_register;
+    } ops;
 
   /* An arbitrary data pointer, allowing symbol readers to record
      additional information on a per-symbol basis.  Note that this data
@@ -598,7 +616,8 @@ struct symbol
 #define SYMBOL_TYPE(symbol)		(symbol)->type
 #define SYMBOL_LINE(symbol)		(symbol)->line
 #define SYMBOL_SYMTAB(symbol)		(symbol)->symtab
-#define SYMBOL_OPS(symbol)              (symbol)->ops
+#define SYMBOL_COMPUTED_OPS(symbol)     (symbol)->ops.ops_computed
+#define SYMBOL_REGISTER_OPS(symbol)     (symbol)->ops.ops_register
 #define SYMBOL_LOCATION_BATON(symbol)   (symbol)->aux_value
 
 /* A partial_symbol records the name, domain, and address class of
Index: gdb-head/gdb/tracepoint.c
===================================================================
--- gdb-head.orig/gdb/tracepoint.c
+++ gdb-head/gdb/tracepoint.c
@@ -40,6 +40,7 @@
 #include "observer.h"
 #include "user-regs.h"
 #include "valprint.h"
+#include "objfiles.h"
 
 #include "ax.h"
 #include "ax-gdb.h"
@@ -791,7 +792,7 @@ collect_symbol (struct collection_list *
       add_memrange (collect, memrange_absolute, offset, len);
       break;
     case LOC_REGISTER:
-      reg = SYMBOL_VALUE (sym);
+      reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, current_gdbarch);
       if (info_verbose)
 	printf_filtered ("LOC_REG[parm] %s: ", 
 			 SYMBOL_PRINT_NAME (sym));
@@ -1854,6 +1855,8 @@ scope_info (char *args, int from_tty)
   char **canonical, *symname, *save_args = args;
   struct dict_iterator iter;
   int j, count = 0;
+  struct gdbarch *gdbarch;
+  int regno;
 
   if (args == 0 || *args == 0)
     error (_("requires an argument (function, line or *addr) to define a scope"));
@@ -1880,6 +1883,8 @@ scope_info (char *args, int from_tty)
 	  if (symname == NULL || *symname == '\0')
 	    continue;		/* probably botched, certainly useless */
 
+	  gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
+
 	  printf_filtered ("Symbol %s is ", symname);
 	  switch (SYMBOL_CLASS (sym))
 	    {
@@ -1905,14 +1910,21 @@ scope_info (char *args, int from_tty)
 	      printf_filtered ("%s", paddress (SYMBOL_VALUE_ADDRESS (sym)));
 	      break;
 	    case LOC_REGISTER:
+	      /* GDBARCH is the architecture associated with the objfile
+		 the symbol is defined in; the target architecture may be
+		 different, and may provide additional registers.  However,
+		 we do not know the target architecture at this point.
+		 We assume the objfile architecture will contain all the
+		 standard registers that occur in debug info in that
+		 objfile.  */
+	      regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
+
 	      if (SYMBOL_IS_ARGUMENT (sym))
 		printf_filtered ("an argument in register $%s",
-				 gdbarch_register_name
-				 (current_gdbarch, SYMBOL_VALUE (sym)));
+				 gdbarch_register_name (gdbarch, regno));
 	      else
 		printf_filtered ("a local variable in register $%s",
-				 gdbarch_register_name
-				 (current_gdbarch, SYMBOL_VALUE (sym)));
+				 gdbarch_register_name (gdbarch, regno));
 	      break;
 	    case LOC_ARG:
 	      printf_filtered ("an argument at stack/frame offset %ld",
@@ -1927,9 +1939,10 @@ scope_info (char *args, int from_tty)
 			       SYMBOL_VALUE (sym));
 	      break;
 	    case LOC_REGPARM_ADDR:
+	      /* Note comment at LOC_REGISTER.  */
+	      regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
 	      printf_filtered ("the address of an argument, in register $%s",
-			       gdbarch_register_name
-				 (current_gdbarch, SYMBOL_VALUE (sym)));
+			       gdbarch_register_name (gdbarch, regno));
 	      break;
 	    case LOC_TYPEDEF:
 	      printf_filtered ("a typedef.\n");
@@ -1957,7 +1970,7 @@ scope_info (char *args, int from_tty)
 	      printf_filtered ("optimized out.\n");
 	      continue;
 	    case LOC_COMPUTED:
-	      SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
+	      SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
 	      break;
 	    }
 	  if (SYMBOL_TYPE (sym))
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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