Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Cc: Sergio Durigan Junior <sergiodj@redhat.com>,
	Tom Tromey <tromey@redhat.com>
Subject: Re: [PATCH 3/6] Modify internalvar mechanism
Date: Tue, 12 Apr 2011 11:24:00 -0000	[thread overview]
Message-ID: <201104121224.31901.pedro@codesourcery.com> (raw)
In-Reply-To: <m3lizqpvbh.fsf@redhat.com>

On Monday 04 April 2011 04:08:34, Sergio Durigan Junior wrote:
> Hi,
> 
> This patch modifies the mechanism of internalvar.  It basically adds
> more manipulation functions to them (`compile_to_ax' and `destroy'), and
> updates the definitions and pointers of existing internalvars.

Can you explain this?  Why would you want to compile an internal var
to AX, for example?

It would be imensely helpful if patches came with a high
level explanation of why they are necessary in the first
place.  :-/


> 
> Regtested on the compile farm.
> 
> Thanks,
> 
> Sergio.
> 
> ---
>  gdb/ChangeLog      |   32 ++++++++++++++++++++++++++++
>  gdb/ax-gdb.c       |    5 ++-
>  gdb/infrun.c       |   14 ++++++++++-
>  gdb/thread.c       |   14 ++++++++++-
>  gdb/tracepoint.c   |   14 ++++++++++-
>  gdb/value.c        |   58 ++++++++++++++++++++++++++++++++++++++++++++-------
>  gdb/value.h        |   48 ++++++++++++++++++++++++++++++++++++++++--
>  gdb/windows-tdep.c |   13 +++++++++-
>  8 files changed, 177 insertions(+), 21 deletions(-)
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index f20653b..1fa276d 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,5 +1,37 @@
>  2011-04-04  Tom Tromey  <tromey@redhat.com>
>  
> +	* ax-gdb.c (gen_expr): Clean up code to handle internal variables
> +	and to compile agent expressions.
> +	* infrun.c (siginfo_make_value): New argument `ignore'.
> +	(siginfo_funcs): New struct.
> +	(_initialize_infrun): New argument when calling
> +	`create_internalvar_type_lazy'.
> +	* thread.c (thread_id_make_value): New argument `ignore'.
> +	(thread_funcs): New struct.
> +	(_initialize_thread): New argument when calling
> +	`create_internalvar_type_lazy'.
> +	* tracepoint.c (sdata_make_value): New argument `ignore'.
> +	(sdata_funcs): New struct.
> +	(_initialize_tracepoint): New argument when calling
> +	`create_internalvar_type_lazy'.
> +	* value.c (make_value): New struct.
> +	(create_internalvar_type_lazy): New argument `data'.
> +	(compile_internalvar_to_ax): New function.
> +	(value_of_internalvar): Properly handling `make_value' case.
> +	(clear_internalvar): Likewise.
> +	(show_convenience): Adding `TRY_CATCH' block.
> +	* value.h (internalvar_make_value): Delete, replace by...
> +	(struct internalvar_funcs): ... this.
> +	(create_internalvar_type_lazy) <fun>: Delete argument.
> +	(create_internalvar_type_lazy) <funcs>, <data>: New arguments.
> +	(compile_internalvar_to_ax): New function.
> +	* windows-tdep.c (tlb_make_value): New argument `ignore'.
> +	(tlb_funcs): New struct.
> +	(_initialize_windows_tdep): New argument when calling
> +	`create_internalvar_type_lazy'.
> +
> +2011-04-04  Tom Tromey  <tromey@redhat.com>
> +
>  	* breakpoint.c (create_breakpoints_sal): Added code to handle
>  	pre-expanded sals.
>  	(create_breakpoint): Likewise.
> diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
> index d1736e1..3e54716 100644
> --- a/gdb/ax-gdb.c
> +++ b/gdb/ax-gdb.c
> @@ -2001,7 +2001,8 @@ gen_expr (struct expression *exp, union exp_element **pc,
>  
>      case OP_INTERNALVAR:
>        {
> -	const char *name = internalvar_name ((*pc)[1].internalvar);
> +	struct internalvar *var = (*pc)[1].internalvar;
> +	const char *name = internalvar_name (var);
>  	struct trace_state_variable *tsv;
>  
>  	(*pc) += 3;
> @@ -2015,7 +2016,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
>  	    value->kind = axs_rvalue;
>  	    value->type = builtin_type (exp->gdbarch)->builtin_long_long;
>  	  }
> -	else
> +	else if (! compile_internalvar_to_ax (var, ax, value))
>  	  error (_("$%s is not a trace state variable; GDB agent "
>  		   "expressions cannot use convenience variables."), name);
>        }
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index 7cee7c8..77d8da8 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -6253,7 +6253,8 @@ static struct lval_funcs siginfo_value_funcs =
>     if there's no object available.  */
>  
>  static struct value *
> -siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var)
> +siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
> +		    void *ignore)
>  {
>    if (target_has_stack
>        && !ptid_equal (inferior_ptid, null_ptid)
> @@ -6826,6 +6827,15 @@ show_schedule_multiple (struct ui_file *file, int from_tty,
>  			    "of all processes is %s.\n"), value);
>  }
>  
> +/* Implementation of `siginfo' variable.  */
> +
> +static const struct internalvar_funcs siginfo_funcs =
> +{
> +  siginfo_make_value,
> +  NULL,
> +  NULL
> +};
> +
>  void
>  _initialize_infrun (void)
>  {
> @@ -7098,7 +7108,7 @@ Tells gdb whether to detach the child of a fork."),
>       value with a void typed value, and when we get here, gdbarch
>       isn't initialized yet.  At this point, we're quite sure there
>       isn't another convenience variable of the same name.  */
> -  create_internalvar_type_lazy ("_siginfo", siginfo_make_value);
> +  create_internalvar_type_lazy ("_siginfo", &siginfo_funcs, NULL);
>  
>    add_setshow_boolean_cmd ("observer", no_class,
>  			   &observer_mode_1, _("\
> diff --git a/gdb/thread.c b/gdb/thread.c
> index 6ad1807..aef9dce 100644
> --- a/gdb/thread.c
> +++ b/gdb/thread.c
> @@ -1438,7 +1438,8 @@ update_thread_list (void)
>     no thread is selected, or no threads exist.  */
>  
>  static struct value *
> -thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var)
> +thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var,
> +		      void *ignore)
>  {
>    struct thread_info *tp = find_thread_ptid (inferior_ptid);
>  
> @@ -1449,6 +1450,15 @@ thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var)
>  /* Commands with a prefix of `thread'.  */
>  struct cmd_list_element *thread_cmd_list = NULL;
>  
> +/* Implementation of `thread' variable.  */
> +
> +static struct internalvar_funcs thread_funcs =
> +{
> +  thread_id_make_value,
> +  NULL,
> +  NULL
> +};
> +
>  void
>  _initialize_thread (void)
>  {
> @@ -1494,5 +1504,5 @@ Show printing of thread events (such as thread start and exit)."), NULL,
>           show_print_thread_events,
>           &setprintlist, &showprintlist);
>  
> -  create_internalvar_type_lazy ("_thread", thread_id_make_value);
> +  create_internalvar_type_lazy ("_thread", &thread_funcs, NULL);
>  }
> diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
> index 3ae35d0..12e1b80 100644
> --- a/gdb/tracepoint.c
> +++ b/gdb/tracepoint.c
> @@ -4497,7 +4497,8 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
>     available.  */
>  
>  static struct value *
> -sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var)
> +sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
> +		  void *ignore)
>  {
>    LONGEST size;
>    gdb_byte *buf;
> @@ -4676,6 +4677,15 @@ traceframe_available_memory (VEC(mem_range_s) **result,
>    return 0;
>  }
>  
> +/* Implementation of `sdata' variable.  */
> +
> +static const struct internalvar_funcs sdata_funcs =
> +{
> +  sdata_make_value,
> +  NULL,
> +  NULL
> +};
> +
>  /* module initialization */
>  void
>  _initialize_tracepoint (void)
> @@ -4686,7 +4696,7 @@ _initialize_tracepoint (void)
>       value with a void typed value, and when we get here, gdbarch
>       isn't initialized yet.  At this point, we're quite sure there
>       isn't another convenience variable of the same name.  */
> -  create_internalvar_type_lazy ("_sdata", sdata_make_value);
> +  create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL);
>  
>    traceframe_number = -1;
>    tracepoint_number = -1;
> diff --git a/gdb/value.c b/gdb/value.c
> index 2acb1df..f2eb01d 100644
> --- a/gdb/value.c
> +++ b/gdb/value.c
> @@ -1530,7 +1530,14 @@ struct internalvar
>        struct value *value;
>  
>        /* The call-back routine used with INTERNALVAR_MAKE_VALUE.  */
> -      internalvar_make_value make_value;
> +      struct
> +        {
> +	  /* The functions to call.  */
> +	  const struct internalvar_funcs *functions;
> +
> +	  /* The function's user-data.  */
> +	  void *data;
> +        } make_value;
>  
>        /* The internal function used with INTERNALVAR_FUNCTION.  */
>        struct
> @@ -1629,18 +1636,39 @@ create_internalvar (const char *name)
>  /* Create an internal variable with name NAME and register FUN as the
>     function that value_of_internalvar uses to create a value whenever
>     this variable is referenced.  NAME should not normally include a
> -   dollar sign.  */
> +   dollar sign.  DATA is passed uninterpreted to FUN when it is
> +   called.  CLEANUP, if not NULL, is called when the internal variable
> +   is destroyed.  It is passed DATA as its only argument.  */
>  
>  struct internalvar *
> -create_internalvar_type_lazy (char *name, internalvar_make_value fun)
> +create_internalvar_type_lazy (const char *name,
> +			      const struct internalvar_funcs *funcs,
> +			      void *data)
>  {
>    struct internalvar *var = create_internalvar (name);
>  
>    var->kind = INTERNALVAR_MAKE_VALUE;
> -  var->u.make_value = fun;
> +  var->u.make_value.functions = funcs;
> +  var->u.make_value.data = data;
>    return var;
>  }
>  
> +/* See documentation in value.h.  */
> +
> +int
> +compile_internalvar_to_ax (struct internalvar *var,
> +			   struct agent_expr *expr,
> +			   struct axs_value *value)
> +{
> +  if (var->kind != INTERNALVAR_MAKE_VALUE
> +      || var->u.make_value.functions->compile_to_ax == NULL)
> +    return 0;
> +
> +  var->u.make_value.functions->compile_to_ax (var, expr, value,
> +					      var->u.make_value.data);
> +  return 1;
> +}
> +
>  /* Look up an internal variable with name NAME.  NAME should not
>     normally include a dollar sign.
>  
> @@ -1713,7 +1741,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
>        break;
>  
>      case INTERNALVAR_MAKE_VALUE:
> -      val = (*var->u.make_value) (gdbarch, var);
> +      val = (*var->u.make_value.functions->make_value) (gdbarch, var,
> +							var->u.make_value.data);
>        break;
>  
>      default:
> @@ -1909,6 +1938,11 @@ clear_internalvar (struct internalvar *var)
>        xfree (var->u.string);
>        break;
>  
> +    case INTERNALVAR_MAKE_VALUE:
> +      if (var->u.make_value.functions->destroy != NULL)
> +	var->u.make_value.functions->destroy (var->u.make_value.data);
> +      break;
> +
>      default:
>        break;
>      }
> @@ -2080,14 +2114,22 @@ show_convenience (char *ignore, int from_tty)
>    get_user_print_options (&opts);
>    for (var = internalvars; var; var = var->next)
>      {
> +      volatile struct gdb_exception e;
> +
>        if (!varseen)
>  	{
>  	  varseen = 1;
>  	}
>        printf_filtered (("$%s = "), var->name);
> -      value_print (value_of_internalvar (gdbarch, var), gdb_stdout,
> -		   &opts);
> -      printf_filtered (("\n"));
> +
> +      TRY_CATCH (e, RETURN_MASK_ERROR)
> +	{
> +	  value_print (value_of_internalvar (gdbarch, var), gdb_stdout,
> +		       &opts);
> +	  printf_filtered (("\n"));
> +	}
> +      if (e.reason < 0)
> +	printf_filtered (_("<error: %s>\n"), e.message);
>      }
>    if (!varseen)
>      printf_unfiltered (_("No debugger convenience variables now defined.\n"
> diff --git a/gdb/value.h b/gdb/value.h
> index 0889cef..71c995c 100644
> --- a/gdb/value.h
> +++ b/gdb/value.h
> @@ -697,10 +697,52 @@ extern struct internalvar *lookup_only_internalvar (const char *name);
>  
>  extern struct internalvar *create_internalvar (const char *name);
>  
> -typedef struct value * (*internalvar_make_value) (struct gdbarch *,
> -						  struct internalvar *);
> +/* An internalvar can be dynamically computed by supplying a vector of
> +   function pointers to perform various operations.  */
> +
> +struct internalvar_funcs
> +{
> +  /* Compute the value of the variable.  The DATA argument passed to
> +     the function is the same argument that was passed to
> +     `create_internalvar_type_lazy'.  */
> +
> +  struct value *(*make_value) (struct gdbarch *arch,
> +			       struct internalvar *var,
> +			       void *data);
> +
> +  /* Update the agent expression EXPR with bytecode to compute the
> +     value.  VALUE is the agent value we are updating.  The DATA
> +     argument passed to this function is the same argument that was
> +     passed to `create_internalvar_type_lazy'.  If this pointer is
> +     NULL, then the internalvar cannot be compiled to an agent
> +     expression.  */
> +
> +  void (*compile_to_ax) (struct internalvar *var,
> +			 struct agent_expr *expr,
> +			 struct axs_value *value,
> +			 void *data);
> +
> +  /* If non-NULL, this is called to destroy DATA.  The DATA argument
> +     passed to this function is the same argument that was passed to
> +     `create_internalvar_type_lazy'.  */
> +
> +  void (*destroy) (void *data);
> +};
> +
>  extern struct internalvar *
> -  create_internalvar_type_lazy (char *name, internalvar_make_value fun);
> +create_internalvar_type_lazy (const char *name,
> +			      const struct internalvar_funcs *funcs,
> +			      void *data);
> +
> +/* Compile an internal variable to an agent expression.  VAR is the
> +   variable to compile; EXPR and VALUE are the agent expression we are
> +   updating.  This will return 0 if there is no known way to compile
> +   VAR, and 1 if VAR was successfully compiled.  It may also throw an
> +   exception on error.  */
> +
> +extern int compile_internalvar_to_ax (struct internalvar *var,
> +				      struct agent_expr *expr,
> +				      struct axs_value *value);
>  
>  extern struct internalvar *lookup_internalvar (const char *name);
>  
> diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
> index 31ddd14..b319250 100644
> --- a/gdb/windows-tdep.c
> +++ b/gdb/windows-tdep.c
> @@ -268,7 +268,7 @@ static struct lval_funcs tlb_value_funcs =
>     if there's no object available.  */
>  
>  static struct value *
> -tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var)
> +tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var, void *ignore)
>  {
>    if (target_has_stack && !ptid_equal (inferior_ptid, null_ptid))
>      {
> @@ -425,6 +425,15 @@ init_w32_command_list (void)
>      }
>  }
>  
> +/* Implementation of `tlb' variable.  */
> +
> +static const struct internalvar_funcs tlb_funcs =
> +{
> +  tlb_make_value,
> +  NULL,
> +  NULL
> +};
> +
>  void
>  _initialize_windows_tdep (void)
>  {
> @@ -451,5 +460,5 @@ even if their meaning is unknown."),
>       value with a void typed value, and when we get here, gdbarch
>       isn't initialized yet.  At this point, we're quite sure there
>       isn't another convenience variable of the same name.  */
> -  create_internalvar_type_lazy ("_tlb", tlb_make_value);
> +  create_internalvar_type_lazy ("_tlb", &tlb_funcs, NULL);
>  }
> 

-- 
Pedro Alves


  parent reply	other threads:[~2011-04-12 11:24 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-04  3:08 Sergio Durigan Junior
2011-04-11 21:08 ` Jan Kratochvil
2011-04-12 11:24 ` Pedro Alves [this message]
2011-04-12 20:40   ` Tom Tromey
2011-04-12 22:33   ` Sergio Durigan Junior
2011-04-19 17:53     ` Pedro Alves
2011-04-19 18:40       ` Tom Tromey
2011-04-19 20:01         ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201104121224.31901.pedro@codesourcery.com \
    --to=pedro@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sergiodj@redhat.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox