2012-04-27 Sergio Durigan Junior <sergiodj@redhat.com>

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'.
This commit is contained in:
Sergio Durigan Junior 2012-04-27 20:38:39 +00:00
parent c49ead2f38
commit 22d2b532b8
8 changed files with 167 additions and 18 deletions

View file

@ -1,3 +1,36 @@
2012-04-27 Sergio Durigan Junior <sergiodj@redhat.com>
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'.
2012-04-27 Mark Wielaard <mjw@redhat.com>
* dwarf2read.c (dwarf2_get_pc_bounds): Check DW_AT_high_pc form to

View file

@ -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);
}

View file

@ -6602,7 +6602,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)
@ -7024,6 +7025,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)
{
@ -7312,7 +7322,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, _("\

View file

@ -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);
}

View file

@ -4944,7 +4944,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;
@ -5123,6 +5124,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)
@ -5133,7 +5143,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;

View file

@ -1629,7 +1629,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
@ -1728,18 +1735,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.
@ -1812,7 +1840,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:
@ -2008,6 +2037,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;
}

View file

@ -764,10 +764,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);

View file

@ -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);
}