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:
parent
c49ead2f38
commit
22d2b532b8
8 changed files with 167 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
14
gdb/infrun.c
14
gdb/infrun.c
|
@ -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, _("\
|
||||
|
|
14
gdb/thread.c
14
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
44
gdb/value.c
44
gdb/value.c
|
@ -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;
|
||||
}
|
||||
|
|
48
gdb/value.h
48
gdb/value.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue