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] More rework of the internal variable logic


Hello,

this patch implements further changes to the internal variable infrastructure.
The previous patch allowed delaying creation of the internal variable's value
until the time the variable is references -- this patch in addition allows
delaying creation of the variable's *type*.

The value_of_internalvar routine gets a GDBARCH argument, which is used to
select appropriate types *at access time* for the architecture, for such
internal variables that are not inherently typed already.

This has a number of advantages:

- The create_internalvar_type_lazy ("make_value") logic can be cleanly
  integrated into the new approach.

- We no longer need a global internal_fn_type to represent internal functions.

- set_internalvar_integer no longer needs to refer to a global built-in
  integer type.

- We can provide a new set_internalvar_string routine that significantly
  simplifies setting an internal variable to a GDB-created string value
  (like tracepoint.c:set_traceframe_context does).

Tested on amd64-linux and powerpc64-linux.


ChangeLog:

	* gdbtypes.h (struct builtin_type): Add internal_fn member.
	* gdbtypes.c (gdbtypes_post_init): Initialize it.
	* value.c (internal_fn_type): Remove.
	(_initialize_values): Do not initialize it.

	* value.c (struct internalvar): Add enum internalvar_kind type and
	kind member.  Restructure union internalvar_data type.  Remove type,
	canonical, and make_value members.
	(init_if_undefined_command): Update for data structure changes.
	(create_internalvar): Likewise.
	(create_internalvar_type_lazy): Likewise.
	(get_internalvar_integer): Likewise.
	(get_internalvar_function): Likewise.
	(set_internalvar_component): Likewise.
	(set_internalvar): Likewise.
	(set_internalvar_integer): Likewise.
	(set_internalvar_function): Likewise.
	(clear_internalvar): Likewise.
	(add_internal_function): Likewise.
	(preserve_one_internalvar): New function.
	(preserve_values): Call it.

	* value.h (value_of_internalvar): Add GDBARCH parameter.
	(internalvar_make_value): Likewise.
	* value.c (value_of_internalvar): Add GDBARCH parameter.  Pass it to
	make_value callback.  Use it to generate per-architecture result value
	types for internal variables with no pre-defined type.  Update for data
	structure changes.
	(show_convenience): Pass architecture to value_of_internalvar.
	* eval.c (evaluate_subexp_standard): Likewise.
	* infrun.c (siginfo_make_value): Add GDBARCH parameter.  Use it
	instead of current frame architecture.  Return per-architecture type.

	* value.h (set_internalvar_string): Add prototype.
	* value.c (set_internalvar_string): New function.
	* tracepoint.c (set_traceframe_context): Use it.


Index: gdb-head/gdb/value.c
===================================================================
--- gdb-head.orig/gdb/value.c
+++ gdb-head/gdb/value.c
@@ -222,9 +222,6 @@ static struct value_history_chunk *value
 
 static int value_history_count;	/* Abs number of last entry stored */
 
-/* The type of internal functions.  */
-
-static struct type *internal_fn_type;
 
 /* List of all value objects currently allocated
    (except for those released by calls to release_value)
@@ -882,25 +879,67 @@ struct internalvar
 {
   struct internalvar *next;
   char *name;
-  struct type *type;
 
-  /* True if this internalvar is the canonical name for a convenience
-     function.  */
-  int canonical;
-
-  /* If this function is non-NULL, it is used to compute a fresh value
-     on every access to the internalvar.  */
-  internalvar_make_value make_value;
-
-  /* To reduce dependencies on target properties (like byte order) that
-     may change during the lifetime of an internal variable, we store
-     simple scalar values as host objects.  */
+  /* We support various different kinds of content of an internal variable.
+     enum internalvar_kind specifies the kind, and union internalvar_data
+     provides the data associated with this particular kind.  */
+
+  enum internalvar_kind
+    {
+      /* The internal variable is empty.  */
+      INTERNALVAR_VOID,
+
+      /* The value of the internal variable is provided directly as
+	 a GDB value object.  */
+      INTERNALVAR_VALUE,
+
+      /* A fresh value is computed via a call-back routine on every
+	 access to the internal variable.  */
+      INTERNALVAR_MAKE_VALUE,
+
+      /* The internal variable holds a GDB internal convenience function.  */
+      INTERNALVAR_FUNCTION,
+
+      /* The variable holds a simple scalar value.  */
+      INTERNALVAR_SCALAR,
+
+      /* The variable holds a GDB-provided string.  */
+      INTERNALVAR_STRING,
+
+    } kind;
+
   union internalvar_data
     {
-      struct value *v;
-      struct internal_function *f;
-      LONGEST l;
-      CORE_ADDR a;
+      /* A value object used with INTERNALVAR_VALUE.  */
+      struct value *value;
+
+      /* The call-back routine used with INTERNALVAR_MAKE_VALUE.  */
+      internalvar_make_value make_value;
+
+      /* The internal function used with INTERNALVAR_FUNCTION.  */
+      struct
+	{
+	  struct internal_function *function;
+	  /* True if this is the canonical name for the function.  */
+	  int canonical;
+	} fn;
+
+      /* A scalar value used with INTERNALVAR_SCALAR.  */
+      struct
+        {
+	  /* If type is non-NULL, it will be used as the type to generate
+	     a value for this internal variable.  If type is NULL, a default
+	     integer type for the architecture is used.  */
+	  struct type *type;
+	  union
+	    {
+	      LONGEST l;    /* Used with TYPE_CODE_INT and NULL types.  */
+	      CORE_ADDR a;  /* Used with TYPE_CODE_PTR types.  */
+	    } val;
+        } scalar;
+
+      /* A string value used with INTERNALVAR_STRING.  */
+      char *string;
     } u;
 };
 
@@ -932,7 +971,7 @@ init_if_undefined_command (char* args, i
 
   /* Only evaluate the expression if the lvalue is void.
      This may still fail if the expresssion is invalid.  */
-  if (TYPE_CODE (intvar->type) == TYPE_CODE_VOID)
+  if (intvar->kind == INTERNALVAR_VOID)
     evaluate_expression (expr);
 
   do_cleanups (old_chain);
@@ -967,9 +1006,7 @@ create_internalvar (const char *name)
   struct internalvar *var;
   var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
   var->name = concat (name, (char *)NULL);
-  var->type = builtin_type_void;
-  var->make_value = NULL;
-  var->canonical = 0;
+  var->kind = INTERNALVAR_VOID;
   var->next = internalvars;
   internalvars = var;
   return var;
@@ -984,7 +1021,8 @@ struct internalvar *
 create_internalvar_type_lazy (char *name, internalvar_make_value fun)
 {
   struct internalvar *var = create_internalvar (name);
-  var->make_value = fun;
+  var->kind = INTERNALVAR_MAKE_VALUE;
+  var->u.make_value = fun;
   return var;
 }
 
@@ -1006,53 +1044,77 @@ lookup_internalvar (const char *name)
   return create_internalvar (name);
 }
 
+/* Return current value of internal variable VAR.  For variables that
+   are not inherently typed, use a value type appropriate for GDBARCH.  */
+
 struct value *
-value_of_internalvar (struct internalvar *var)
+value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
 {
   struct value *val;
 
-  if (var->make_value != NULL)
-    val = (*var->make_value) (var);
-  else
+  switch (var->kind)
     {
-      switch (TYPE_CODE (var->type))
-	{
-	case TYPE_CODE_VOID:
-	case TYPE_CODE_INTERNAL_FUNCTION:
-	  val = allocate_value (var->type);
-	  break;
+    case INTERNALVAR_VOID:
+      val = allocate_value (builtin_type (gdbarch)->builtin_void);
+      break;
 
-	case TYPE_CODE_INT:
-	  val = value_from_longest (var->type, var->u.l);
-	  break;
+    case INTERNALVAR_FUNCTION:
+      val = allocate_value (builtin_type (gdbarch)->internal_fn);
+      break;
 
-	case TYPE_CODE_PTR:
-	  val = value_from_pointer (var->type, var->u.a);
-	  break;
+    case INTERNALVAR_SCALAR:
+      if (!var->u.scalar.type)
+	val = value_from_longest (builtin_type (gdbarch)->builtin_int,
+				  var->u.scalar.val.l);
+      else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT)
+	val = value_from_longest (var->u.scalar.type, var->u.scalar.val.l);
+      else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_PTR)
+	val = value_from_pointer (var->u.scalar.type, var->u.scalar.val.a);
+      else
+        internal_error (__FILE__, __LINE__, "bad type");
+      break;
 
-	default:
-	  val = value_copy (var->u.v);
-	  break;
-	}
+    case INTERNALVAR_STRING:
+      val = value_cstring (var->u.string, strlen (var->u.string),
+			   builtin_type (gdbarch)->builtin_char);
+      break;
 
+    case INTERNALVAR_VALUE:
+      val = value_copy (var->u.value);
       if (value_lazy (val))
 	value_fetch_lazy (val);
+      break;
 
-      /* If the variable's value is a computed lvalue, we want
-	 references to it to produce another computed lvalue, where
-	 referencces and assignments actually operate through the
-	 computed value's functions.
-
-	 This means that internal variables with computed values
-	 behave a little differently from other internal variables:
-	 assignments to them don't just replace the previous value
-	 altogether.  At the moment, this seems like the behavior we
-	 want.  */
-      if (val->lval != lval_computed)
-	{
-	  VALUE_LVAL (val) = lval_internalvar;
-	  VALUE_INTERNALVAR (val) = var;
-	}
+    case INTERNALVAR_MAKE_VALUE:
+      val = (*var->u.make_value) (gdbarch, var);
+      break;
+
+    default:
+      internal_error (__FILE__, __LINE__, "bad kind");
+    }
+
+  /* Change the VALUE_LVAL to lval_internalvar so that future operations
+     on this value go back to affect the original internal variable.
+
+     Do not do this for INTERNALVAR_MAKE_VALUE variables, as those have
+     no underlying modifyable state in the internal variable.
+
+     Likewise, if the variable's value is a computed lvalue, we want
+     references to it to produce another computed lvalue, where
+     references and assignments actually operate through the
+     computed value's functions.
+
+     This means that internal variables with computed values
+     behave a little differently from other internal variables:
+     assignments to them don't just replace the previous value
+     altogether.  At the moment, this seems like the behavior we
+     want.  */
+
+  if (var->kind != INTERNALVAR_MAKE_VALUE
+      && val->lval != lval_computed)
+    {
+      VALUE_LVAL (val) = lval_internalvar;
+      VALUE_INTERNALVAR (val) = var;
     }
 
   return val;
@@ -1061,11 +1123,16 @@ value_of_internalvar (struct internalvar
 int
 get_internalvar_integer (struct internalvar *var, LONGEST *result)
 {
-  switch (TYPE_CODE (var->type))
+  switch (var->kind)
     {
-    case TYPE_CODE_INT:
-      *result = var->u.l;
-      return 1;
+    case INTERNALVAR_SCALAR:
+      if (var->u.scalar.type == NULL
+	  || TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT)
+	{
+	  *result = var->u.scalar.val.l;
+	  return 1;
+	}
+      /* Fall through.  */
 
     default:
       return 0;
@@ -1076,10 +1143,10 @@ static int
 get_internalvar_function (struct internalvar *var,
 			  struct internal_function **result)
 {
-  switch (TYPE_CODE (var->type))
+  switch (var->kind)
     {
-    case TYPE_CODE_INTERNAL_FUNCTION:
-      *result = var->u.f;
+    case INTERNALVAR_FUNCTION:
+      *result = var->u.fn.function;
       return 1;
 
     default:
@@ -1093,17 +1160,10 @@ set_internalvar_component (struct intern
 {
   gdb_byte *addr;
 
-  switch (TYPE_CODE (var->type))
+  switch (var->kind)
     {
-    case TYPE_CODE_VOID:
-    case TYPE_CODE_INTERNAL_FUNCTION:
-    case TYPE_CODE_INT:
-    case TYPE_CODE_PTR:
-      /* We can never get a component of a basic type.  */
-      internal_error (__FILE__, __LINE__, "set_internalvar_component");
-
-    default:
-      addr = value_contents_writeable (var->u.v);
+    case INTERNALVAR_VALUE:
+      addr = value_contents_writeable (var->u.value);
 
       if (bitsize)
 	modify_field (addr + offset,
@@ -1112,52 +1172,65 @@ set_internalvar_component (struct intern
 	memcpy (addr + offset, value_contents (newval),
 		TYPE_LENGTH (value_type (newval)));
       break;
+
+    default:
+      /* We can never get a component of any other kind.  */
+      internal_error (__FILE__, __LINE__, "set_internalvar_component");
     }
 }
 
 void
 set_internalvar (struct internalvar *var, struct value *val)
 {
-  struct type *new_type = check_typedef (value_type (val));
+  enum internalvar_kind new_kind;
   union internalvar_data new_data = { 0 };
 
-  if (var->canonical)
+  if (var->kind == INTERNALVAR_FUNCTION && var->u.fn.canonical)
     error (_("Cannot overwrite convenience function %s"), var->name);
 
   /* Prepare new contents.  */
-  switch (TYPE_CODE (new_type))
+  switch (TYPE_CODE (check_typedef (value_type (val))))
     {
     case TYPE_CODE_VOID:
+      new_kind = INTERNALVAR_VOID;
       break;
 
     case TYPE_CODE_INTERNAL_FUNCTION:
       gdb_assert (VALUE_LVAL (val) == lval_internalvar);
-      get_internalvar_function (VALUE_INTERNALVAR (val), &new_data.f);
+      new_kind = INTERNALVAR_FUNCTION;
+      get_internalvar_function (VALUE_INTERNALVAR (val),
+				&new_data.fn.function);
+      /* Copies created here are never canonical.  */
       break;
 
     case TYPE_CODE_INT:
-      new_data.l = value_as_long (val);
+      new_kind = INTERNALVAR_SCALAR;
+      new_data.scalar.type = value_type (val);
+      new_data.scalar.val.l = value_as_long (val);
       break;
 
     case TYPE_CODE_PTR:
-      new_data.a = value_as_address (val);
+      new_kind = INTERNALVAR_SCALAR;
+      new_data.scalar.type = value_type (val);
+      new_data.scalar.val.a = value_as_address (val);
       break;
 
     default:
-      new_data.v = value_copy (val);
-      new_data.v->modifiable = 1;
+      new_kind = INTERNALVAR_VALUE;
+      new_data.value = value_copy (val);
+      new_data.value->modifiable = 1;
 
       /* Force the value to be fetched from the target now, to avoid problems
 	 later when this internalvar is referenced and the target is gone or
 	 has changed.  */
-      if (value_lazy (new_data.v))
-       value_fetch_lazy (new_data.v);
+      if (value_lazy (new_data.value))
+       value_fetch_lazy (new_data.value);
 
       /* Release the value from the value chain to prevent it from being
 	 deleted by free_all_values.  From here on this function should not
 	 call error () until new_data is installed into the var->u to avoid
 	 leaking memory.  */
-      release_value (new_data.v);
+      release_value (new_data.value);
       break;
     }
 
@@ -1165,7 +1238,7 @@ set_internalvar (struct internalvar *var
   clear_internalvar (var);
 
   /* Switch over.  */
-  var->type = new_type;
+  var->kind = new_kind;
   var->u = new_data;
   /* End code which must not call error().  */
 }
@@ -1176,9 +1249,19 @@ set_internalvar_integer (struct internal
   /* Clean up old contents.  */
   clear_internalvar (var);
 
-  /* Use a platform-independent 32-bit integer type.  */
-  var->type = builtin_type_int32;
-  var->u.l = l;
+  var->kind = INTERNALVAR_SCALAR;
+  var->u.scalar.type = NULL;
+  var->u.scalar.val.l = l;
+}
+
+void
+set_internalvar_string (struct internalvar *var, const char *string)
+{
+  /* Clean up old contents.  */
+  clear_internalvar (var);
+
+  var->kind = INTERNALVAR_STRING;
+  var->u.string = xstrdup (string);
 }
 
 static void
@@ -1187,29 +1270,32 @@ set_internalvar_function (struct interna
   /* Clean up old contents.  */
   clear_internalvar (var);
 
-  var->type = internal_fn_type;
-  var->u.f = f;
+  var->kind = INTERNALVAR_FUNCTION;
+  var->u.fn.function = f;
+  var->u.fn.canonical = 1;
+  /* Variables installed here are always the canonical version.  */
 }
 
 void
 clear_internalvar (struct internalvar *var)
 {
   /* Clean up old contents.  */
-  switch (TYPE_CODE (var->type))
+  switch (var->kind)
     {
-    case TYPE_CODE_VOID:
-    case TYPE_CODE_INTERNAL_FUNCTION:
-    case TYPE_CODE_INT:
-    case TYPE_CODE_PTR:
+    case INTERNALVAR_VALUE:
+      value_free (var->u.value);
+      break;
+
+    case INTERNALVAR_STRING:
+      xfree (var->u.string);
       break;
 
     default:
-      value_free (var->u.v);
       break;
     }
 
-  /* Set to void type.  */
-  var->type = builtin_type_void;
+  /* Reset to void kind.  */
+  var->kind = INTERNALVAR_VOID;
 }
 
 char *
@@ -1288,7 +1374,6 @@ add_internal_function (const char *name,
 
   ifn = create_internal_function (name, handler, cookie);
   set_internalvar_function (var, ifn);
-  var->canonical = 1;
 
   cmd = add_cmd (xstrdup (name), no_class, function_command, (char *) doc,
 		 &functionlist);
@@ -1311,6 +1396,26 @@ preserve_one_value (struct value *value,
 						 copied_types);
 }
 
+/* Likewise for internal variable VAR.  */
+
+static void
+preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
+			  htab_t copied_types)
+{
+  switch (var->kind)
+    {
+    case INTERNALVAR_SCALAR:
+      if (var->u.scalar.type && TYPE_OBJFILE (var->u.scalar.type) == objfile)
+	var->u.scalar.type
+	  = copy_type_recursive (objfile, var->u.scalar.type, copied_types);
+      break;
+
+    case INTERNALVAR_VALUE:
+      preserve_one_value (var->u.value, objfile, copied_types);
+      break;
+    }
+}
+
 /* Update the internal variables and value history when OBJFILE is
    discarded; we must copy the types out of the objfile.  New global types
    will be created for every convenience variable which currently points to
@@ -1336,23 +1441,7 @@ preserve_values (struct objfile *objfile
 	preserve_one_value (cur->values[i], objfile, copied_types);
 
   for (var = internalvars; var; var = var->next)
-    {
-      if (TYPE_OBJFILE (var->type) == objfile)
-	var->type = copy_type_recursive (objfile, var->type, copied_types);
-
-      switch (TYPE_CODE (var->type))
-	{
-	case TYPE_CODE_VOID:
-	case TYPE_CODE_INTERNAL_FUNCTION:
-	case TYPE_CODE_INT:
-	case TYPE_CODE_PTR:
-	  break;
-
-	default:
-	  preserve_one_value (var->u.v, objfile, copied_types);
-	  break;
-	}
-    }
+    preserve_one_internalvar (var, objfile, copied_types);
 
   for (val = values_in_python; val; val = val->next)
     preserve_one_value (val, objfile, copied_types);
@@ -1363,6 +1452,7 @@ preserve_values (struct objfile *objfile
 static void
 show_convenience (char *ignore, int from_tty)
 {
+  struct gdbarch *gdbarch = current_gdbarch;
   struct internalvar *var;
   int varseen = 0;
   struct value_print_options opts;
@@ -1375,7 +1465,7 @@ show_convenience (char *ignore, int from
 	  varseen = 1;
 	}
       printf_filtered (("$%s = "), var->name);
-      value_print (value_of_internalvar (var), gdb_stdout,
+      value_print (value_of_internalvar (gdbarch, var), gdb_stdout,
 		   &opts);
       printf_filtered (("\n"));
     }
@@ -2172,8 +2262,4 @@ VARIABLE is already initialized."));
   add_prefix_cmd ("function", no_class, function_command, _("\
 Placeholder command for showing help on convenience functions."),
 		  &functionlist, "function ", 0, &cmdlist);
-
-  internal_fn_type = alloc_type (NULL);
-  TYPE_CODE (internal_fn_type) = TYPE_CODE_INTERNAL_FUNCTION;
-  TYPE_NAME (internal_fn_type) = "<internal function>";
 }
Index: gdb-head/gdb/eval.c
===================================================================
--- gdb-head.orig/gdb/eval.c
+++ gdb-head/gdb/eval.c
@@ -779,7 +779,8 @@ evaluate_subexp_standard (struct type *e
 
     case OP_INTERNALVAR:
       (*pos) += 2;
-      return value_of_internalvar (exp->elts[pc + 1].internalvar);
+      return value_of_internalvar (exp->gdbarch,
+				   exp->elts[pc + 1].internalvar);
 
     case OP_STRING:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
Index: gdb-head/gdb/gdbtypes.c
===================================================================
--- gdb-head.orig/gdb/gdbtypes.c
+++ gdb-head/gdb/gdbtypes.c
@@ -3181,6 +3181,11 @@ gdbtypes_post_init (struct gdbarch *gdba
   builtin_type->builtin_func_ptr =
     lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
 
+  /* This type represents a GDB internal function.  */
+  builtin_type->internal_fn =
+    init_type (TYPE_CODE_INTERNAL_FUNCTION, 0, 0,
+	       "<internal function>", NULL);
+
   return builtin_type;
 }
 
Index: gdb-head/gdb/gdbtypes.h
===================================================================
--- gdb-head.orig/gdb/gdbtypes.h
+++ gdb-head/gdb/gdbtypes.h
@@ -999,6 +999,12 @@ struct builtin_type
      However, all function pointer types are interconvertible, so void
      (*) () can server as a generic function pointer.  */
   struct type *builtin_func_ptr;
+
+
+  /* Special-purpose types.  */
+
+  /* This type is used to represent a GDB internal function.  */
+  struct type *internal_fn;
 };
 
 /* Return the type table for the specified architecture.  */
Index: gdb-head/gdb/infrun.c
===================================================================
--- gdb-head.orig/gdb/infrun.c
+++ gdb-head/gdb/infrun.c
@@ -5148,29 +5148,21 @@ static struct lval_funcs siginfo_value_f
   };
 
 /* Return a new value with the correct type for the siginfo object of
-   the current thread.  Return a void value if there's no object
-   available.  */
+   the current thread using architecture GDBARCH.  Return a void value
+   if there's no object available.  */
 
 static struct value *
-siginfo_make_value (struct internalvar *var)
+siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var)
 {
-  struct type *type;
-  struct gdbarch *gdbarch;
-
   if (target_has_stack
-      && !ptid_equal (inferior_ptid, null_ptid))
+      && !ptid_equal (inferior_ptid, null_ptid)
+      && gdbarch_get_siginfo_type_p (gdbarch))
     {
-      gdbarch = get_frame_arch (get_current_frame ());
-
-      if (gdbarch_get_siginfo_type_p (gdbarch))
-	{
-	  type = gdbarch_get_siginfo_type (gdbarch);
-
-	  return allocate_computed_value (type, &siginfo_value_funcs, NULL);
-	}
+      struct type *type = gdbarch_get_siginfo_type (gdbarch);
+      return allocate_computed_value (type, &siginfo_value_funcs, NULL);
     }
 
-  return allocate_value (builtin_type_void);
+  return allocate_value (builtin_type (gdbarch)->builtin_void);
 }
 
 
Index: gdb-head/gdb/value.h
===================================================================
--- gdb-head.orig/gdb/value.h
+++ gdb-head/gdb/value.h
@@ -524,7 +524,8 @@ extern void binop_promote (const struct 
 
 extern struct value *access_value_history (int num);
 
-extern struct value *value_of_internalvar (struct internalvar *var);
+extern struct value *value_of_internalvar (struct gdbarch *gdbarch,
+					   struct internalvar *var);
 
 extern int get_internalvar_integer (struct internalvar *var, LONGEST *l);
 
@@ -532,6 +533,9 @@ extern void set_internalvar (struct inte
 
 extern void set_internalvar_integer (struct internalvar *var, LONGEST l);
 
+extern void set_internalvar_string (struct internalvar *var,
+				    const char *string);
+
 extern void clear_internalvar (struct internalvar *var);
 
 extern void set_internalvar_component (struct internalvar *var,
@@ -543,8 +547,8 @@ extern struct internalvar *lookup_only_i
 
 extern struct internalvar *create_internalvar (const char *name);
 
-typedef struct value * (*internalvar_make_value) (struct internalvar *);
-
+typedef struct value * (*internalvar_make_value) (struct gdbarch *,
+						  struct internalvar *);
 extern struct internalvar *
   create_internalvar_type_lazy (char *name, internalvar_make_value fun);
 
Index: gdb-head/gdb/tracepoint.c
===================================================================
--- gdb-head.orig/gdb/tracepoint.c
+++ gdb-head/gdb/tracepoint.c
@@ -228,12 +228,6 @@ set_traceframe_context (struct frame_inf
 {
   CORE_ADDR trace_pc;
 
-  static struct type *func_string, *file_string;
-  static struct type *func_range, *file_range;
-  struct value *func_val;
-  struct value *file_val;
-  int len;
-
   if (trace_frame == NULL)		/* Cease debugging any trace buffers.  */
     {
       traceframe_fun = 0;
@@ -261,20 +255,8 @@ set_traceframe_context (struct frame_inf
       || SYMBOL_LINKAGE_NAME (traceframe_fun) == NULL)
     clear_internalvar (lookup_internalvar ("trace_func"));
   else
-    {
-      len = strlen (SYMBOL_LINKAGE_NAME (traceframe_fun));
-      func_range = create_range_type (func_range,
-				      builtin_type_int32, 0, len - 1);
-      func_string = create_array_type (func_string,
-				       builtin_type_true_char, func_range);
-      func_val = allocate_value (func_string);
-      deprecated_set_value_type (func_val, func_string);
-      memcpy (value_contents_raw (func_val),
-	      SYMBOL_LINKAGE_NAME (traceframe_fun),
-	      len);
-      deprecated_set_value_modifiable (func_val, 0);
-      set_internalvar (lookup_internalvar ("trace_func"), func_val);
-    }
+    set_internalvar_string (lookup_internalvar ("trace_func"),
+			    SYMBOL_LINKAGE_NAME (traceframe_fun));
 
   /* Save file name as "$trace_file", a debugger variable visible to
      users.  */
@@ -282,20 +264,8 @@ set_traceframe_context (struct frame_inf
       || traceframe_sal.symtab->filename == NULL)
     clear_internalvar (lookup_internalvar ("trace_file"));
   else
-    {
-      len = strlen (traceframe_sal.symtab->filename);
-      file_range = create_range_type (file_range,
-				      builtin_type_int32, 0, len - 1);
-      file_string = create_array_type (file_string,
-				       builtin_type_true_char, file_range);
-      file_val = allocate_value (file_string);
-      deprecated_set_value_type (file_val, file_string);
-      memcpy (value_contents_raw (file_val),
-	      traceframe_sal.symtab->filename,
-	      len);
-      deprecated_set_value_modifiable (file_val, 0);
-      set_internalvar (lookup_internalvar ("trace_file"), file_val);
-    }
+    set_internalvar_string (lookup_internalvar ("trace_file"),
+			    traceframe_sal.symtab->filename);
 }
 
 /* ACTIONS functions: */
-- 
  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]