From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12328 invoked by alias); 6 Apr 2012 03:32:48 -0000 Received: (qmail 12318 invoked by uid 22791); 6 Apr 2012 03:32:47 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,T_FILL_THIS_FORM_SHORT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 06 Apr 2012 03:32:22 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q363WMsA024485 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 5 Apr 2012 23:32:22 -0400 Received: from psique ([10.3.112.12]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q363WIAC025686 for ; Thu, 5 Apr 2012 23:32:20 -0400 From: Sergio Durigan Junior To: gdb-patches@sourceware.org Subject: [PATCH 1/4 v2] Refactor internal variable mechanism References: X-URL: http://www.redhat.com Date: Fri, 06 Apr 2012 03:32:00 -0000 In-Reply-To: (Sergio Durigan Junior's message of "Fri, 06 Apr 2012 00:27:51 -0300") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-04/txt/msg00099.txt.bz2 Hi, This is the first patch of the series. This piece of code didn't change from the last time. You can see the last version of it in: http://sourceware.org/ml/gdb-patches/2012-03/msg00354.html Is this OK to check-in? gdb/ChangeLog 2012-07-04 Sergio Durigan Junior Tom Tromey * 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) : Delete argument. (create_internalvar_type_lazy) , : 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'. --- gdb/ax-gdb.c | 5 +++-- gdb/infrun.c | 14 ++++++++++++-- gdb/thread.c | 14 ++++++++++++-- gdb/tracepoint.c | 14 ++++++++++++-- gdb/value.c | 44 +++++++++++++++++++++++++++++++++++++++----- gdb/value.h | 48 +++++++++++++++++++++++++++++++++++++++++++++--- gdb/windows-tdep.c | 13 +++++++++++-- 7 files changed, 134 insertions(+), 18 deletions(-) diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index aaefed6..eebe61a 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -2038,7 +2038,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; @@ -2052,7 +2053,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 103ef30..54e39ef 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -6589,7 +6589,8 @@ static const 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) @@ -7011,6 +7012,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) { @@ -7299,7 +7309,7 @@ enabled by default on some platforms."), 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 97f283c..d361dd8 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -1439,7 +1439,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); @@ -1450,6 +1451,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 const struct internalvar_funcs thread_funcs = +{ + thread_id_make_value, + NULL, + NULL +}; + void _initialize_thread (void) { @@ -1495,5 +1505,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 057b441..fac6b44 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -4943,7 +4943,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; @@ -5122,6 +5123,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) @@ -5132,7 +5142,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 c23803a..7f2da6f 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -1588,7 +1588,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 @@ -1687,18 +1694,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. @@ -1771,7 +1799,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: @@ -1967,6 +1996,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; } diff --git a/gdb/value.h b/gdb/value.h index 4d04a20..f1f72cd 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -748,10 +748,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 6b84eff..a704599 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -268,7 +268,7 @@ static const 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)) { @@ -428,6 +428,15 @@ init_w32_command_list (void) /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_windows_tdep; +/* Implementation of `tlb' variable. */ + +static const struct internalvar_funcs tlb_funcs = +{ + tlb_make_value, + NULL, + NULL +}; + void _initialize_windows_tdep (void) { @@ -454,5 +463,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); } -- 1.7.7.6 -- Sergio