mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-27 14:00:30 +00:00
2010-03-17 Stan Shebs <stan@codesourcery.com>
* ax-gdb.h (struct axs_value): New field optimized_out. (gen_trace_for_var): Add gdbarch argument. * ax-gdb.c (gen_trace_static_fields): New function. (gen_traced_pop): Call it, add gdbarch argument. (gen_trace_for_expr): Update call to it. (gen_trace_for_var): Ditto, and report optimized-out variables. (gen_struct_ref_recursive): Check for optimized-out value. (gen_struct_elt_for_reference): Ditto. (gen_static_field): Pass gdbarch instead of expression, assume optimization if field not found. (gen_var_ref): Set the optimized_out flag. (gen_expr): Error on optimized-out variable. * tracepoint.c (collect_symbol): Handle struct-valued vars as expressions, skip optimized-out variables with computed locations. * dwarf2loc.c (dwarf2_tracepoint_var_ref): Flag instead of erroring out if location expression missing. (loclist_tracepoint_var_ref): Don't error out here.
This commit is contained in:
parent
a3b2a86bb7
commit
400c6af037
@ -1,3 +1,23 @@
|
|||||||
|
2010-03-17 Stan Shebs <stan@codesourcery.com>
|
||||||
|
|
||||||
|
* ax-gdb.h (struct axs_value): New field optimized_out.
|
||||||
|
(gen_trace_for_var): Add gdbarch argument.
|
||||||
|
* ax-gdb.c (gen_trace_static_fields): New function.
|
||||||
|
(gen_traced_pop): Call it, add gdbarch argument.
|
||||||
|
(gen_trace_for_expr): Update call to it.
|
||||||
|
(gen_trace_for_var): Ditto, and report optimized-out variables.
|
||||||
|
(gen_struct_ref_recursive): Check for optimized-out value.
|
||||||
|
(gen_struct_elt_for_reference): Ditto.
|
||||||
|
(gen_static_field): Pass gdbarch instead of expression, assume
|
||||||
|
optimization if field not found.
|
||||||
|
(gen_var_ref): Set the optimized_out flag.
|
||||||
|
(gen_expr): Error on optimized-out variable.
|
||||||
|
* tracepoint.c (collect_symbol): Handle struct-valued vars as
|
||||||
|
expressions, skip optimized-out variables with computed locations.
|
||||||
|
* dwarf2loc.c (dwarf2_tracepoint_var_ref): Flag instead of
|
||||||
|
erroring out if location expression missing.
|
||||||
|
(loclist_tracepoint_var_ref): Don't error out here.
|
||||||
|
|
||||||
2010-03-17 Tom Tromey <tromey@redhat.com>
|
2010-03-17 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* dwarf2read.c (dwarf2_get_section_info): Handle case where no
|
* dwarf2read.c (dwarf2_get_section_info): Handle case where no
|
||||||
|
134
gdb/ax-gdb.c
134
gdb/ax-gdb.c
@ -70,7 +70,7 @@ static struct value *const_var_ref (struct symbol *var);
|
|||||||
static struct value *const_expr (union exp_element **pc);
|
static struct value *const_expr (union exp_element **pc);
|
||||||
static struct value *maybe_const_expr (union exp_element **pc);
|
static struct value *maybe_const_expr (union exp_element **pc);
|
||||||
|
|
||||||
static void gen_traced_pop (struct agent_expr *, struct axs_value *);
|
static void gen_traced_pop (struct gdbarch *, struct agent_expr *, struct axs_value *);
|
||||||
|
|
||||||
static void gen_sign_extend (struct agent_expr *, struct type *);
|
static void gen_sign_extend (struct agent_expr *, struct type *);
|
||||||
static void gen_extend (struct agent_expr *, struct type *);
|
static void gen_extend (struct agent_expr *, struct type *);
|
||||||
@ -144,7 +144,7 @@ static void gen_struct_ref (struct expression *exp, struct agent_expr *ax,
|
|||||||
struct axs_value *value,
|
struct axs_value *value,
|
||||||
char *field,
|
char *field,
|
||||||
char *operator_name, char *operand_name);
|
char *operator_name, char *operand_name);
|
||||||
static void gen_static_field (struct expression *exp,
|
static void gen_static_field (struct gdbarch *gdbarch,
|
||||||
struct agent_expr *ax, struct axs_value *value,
|
struct agent_expr *ax, struct axs_value *value,
|
||||||
struct type *type, int fieldno);
|
struct type *type, int fieldno);
|
||||||
static void gen_repeat (struct expression *exp, union exp_element **pc,
|
static void gen_repeat (struct expression *exp, union exp_element **pc,
|
||||||
@ -331,11 +331,64 @@ maybe_const_expr (union exp_element **pc)
|
|||||||
emits the trace bytecodes at the appropriate points. */
|
emits the trace bytecodes at the appropriate points. */
|
||||||
static int trace_kludge;
|
static int trace_kludge;
|
||||||
|
|
||||||
|
/* Scan for all static fields in the given class, including any base
|
||||||
|
classes, and generate tracing bytecodes for each. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
gen_trace_static_fields (struct gdbarch *gdbarch,
|
||||||
|
struct agent_expr *ax,
|
||||||
|
struct type *type)
|
||||||
|
{
|
||||||
|
int i, nbases = TYPE_N_BASECLASSES (type);
|
||||||
|
struct axs_value value;
|
||||||
|
|
||||||
|
CHECK_TYPEDEF (type);
|
||||||
|
|
||||||
|
for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
|
||||||
|
{
|
||||||
|
if (field_is_static (&TYPE_FIELD (type, i)))
|
||||||
|
{
|
||||||
|
gen_static_field (gdbarch, ax, &value, type, i);
|
||||||
|
if (value.optimized_out)
|
||||||
|
continue;
|
||||||
|
switch (value.kind)
|
||||||
|
{
|
||||||
|
case axs_lvalue_memory:
|
||||||
|
{
|
||||||
|
int length = TYPE_LENGTH (check_typedef (value.type));
|
||||||
|
|
||||||
|
ax_const_l (ax, length);
|
||||||
|
ax_simple (ax, aop_trace);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case axs_lvalue_register:
|
||||||
|
/* We need to mention the register somewhere in the bytecode,
|
||||||
|
so ax_reqs will pick it up and add it to the mask of
|
||||||
|
registers used. */
|
||||||
|
ax_reg (ax, value.u.reg);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now scan through base classes recursively. */
|
||||||
|
for (i = 0; i < nbases; i++)
|
||||||
|
{
|
||||||
|
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
|
||||||
|
|
||||||
|
gen_trace_static_fields (gdbarch, ax, basetype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Trace the lvalue on the stack, if it needs it. In either case, pop
|
/* Trace the lvalue on the stack, if it needs it. In either case, pop
|
||||||
the value. Useful on the left side of a comma, and at the end of
|
the value. Useful on the left side of a comma, and at the end of
|
||||||
an expression being used for tracing. */
|
an expression being used for tracing. */
|
||||||
static void
|
static void
|
||||||
gen_traced_pop (struct agent_expr *ax, struct axs_value *value)
|
gen_traced_pop (struct gdbarch *gdbarch,
|
||||||
|
struct agent_expr *ax, struct axs_value *value)
|
||||||
{
|
{
|
||||||
if (trace_kludge)
|
if (trace_kludge)
|
||||||
switch (value->kind)
|
switch (value->kind)
|
||||||
@ -371,6 +424,12 @@ gen_traced_pop (struct agent_expr *ax, struct axs_value *value)
|
|||||||
else
|
else
|
||||||
/* If we're not tracing, just pop the value. */
|
/* If we're not tracing, just pop the value. */
|
||||||
ax_simple (ax, aop_pop);
|
ax_simple (ax, aop_pop);
|
||||||
|
|
||||||
|
/* To trace C++ classes with static fields stored elsewhere. */
|
||||||
|
if (trace_kludge
|
||||||
|
&& (TYPE_CODE (value->type) == TYPE_CODE_STRUCT
|
||||||
|
|| TYPE_CODE (value->type) == TYPE_CODE_UNION))
|
||||||
|
gen_trace_static_fields (gdbarch, ax, value->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -554,6 +613,7 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax,
|
|||||||
{
|
{
|
||||||
/* Dereference any typedefs. */
|
/* Dereference any typedefs. */
|
||||||
value->type = check_typedef (SYMBOL_TYPE (var));
|
value->type = check_typedef (SYMBOL_TYPE (var));
|
||||||
|
value->optimized_out = 0;
|
||||||
|
|
||||||
/* I'm imitating the code in read_var_value. */
|
/* I'm imitating the code in read_var_value. */
|
||||||
switch (SYMBOL_CLASS (var))
|
switch (SYMBOL_CLASS (var))
|
||||||
@ -650,8 +710,9 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LOC_OPTIMIZED_OUT:
|
case LOC_OPTIMIZED_OUT:
|
||||||
error (_("The variable `%s' has been optimized out."),
|
/* Flag this, but don't say anything; leave it up to callers to
|
||||||
SYMBOL_PRINT_NAME (var));
|
warn the user. */
|
||||||
|
value->optimized_out = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1342,7 +1403,10 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax,
|
|||||||
being handled as a global. */
|
being handled as a global. */
|
||||||
if (field_is_static (&TYPE_FIELD (type, i)))
|
if (field_is_static (&TYPE_FIELD (type, i)))
|
||||||
{
|
{
|
||||||
gen_static_field (exp, ax, value, type, i);
|
gen_static_field (exp->gdbarch, ax, value, type, i);
|
||||||
|
if (value->optimized_out)
|
||||||
|
error (_("static field `%s' has been optimized out, cannot use"),
|
||||||
|
field);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1425,7 +1489,7 @@ gen_maybe_namespace_elt (struct expression *exp,
|
|||||||
const struct type *curtype, char *name);
|
const struct type *curtype, char *name);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gen_static_field (struct expression *exp,
|
gen_static_field (struct gdbarch *gdbarch,
|
||||||
struct agent_expr *ax, struct axs_value *value,
|
struct agent_expr *ax, struct axs_value *value,
|
||||||
struct type *type, int fieldno)
|
struct type *type, int fieldno)
|
||||||
{
|
{
|
||||||
@ -1434,15 +1498,27 @@ gen_static_field (struct expression *exp,
|
|||||||
ax_const_l (ax, TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
|
ax_const_l (ax, TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
|
||||||
value->kind = axs_lvalue_memory;
|
value->kind = axs_lvalue_memory;
|
||||||
value->type = TYPE_FIELD_TYPE (type, fieldno);
|
value->type = TYPE_FIELD_TYPE (type, fieldno);
|
||||||
|
value->optimized_out = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
|
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
|
||||||
struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
|
struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
|
||||||
if (sym == NULL)
|
|
||||||
error (_("symbol not found"));
|
|
||||||
|
|
||||||
gen_var_ref (exp->gdbarch, ax, value, sym);
|
if (sym)
|
||||||
|
{
|
||||||
|
gen_var_ref (gdbarch, ax, value, sym);
|
||||||
|
|
||||||
|
/* Don't error if the value was optimized out, we may be
|
||||||
|
scanning all static fields and just want to pass over this
|
||||||
|
and continue with the rest. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Silently assume this was optimized out; class printing
|
||||||
|
will let the user know why the data is missing. */
|
||||||
|
value->optimized_out = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1468,7 +1544,10 @@ gen_struct_elt_for_reference (struct expression *exp,
|
|||||||
{
|
{
|
||||||
if (field_is_static (&TYPE_FIELD (t, i)))
|
if (field_is_static (&TYPE_FIELD (t, i)))
|
||||||
{
|
{
|
||||||
gen_static_field (exp, ax, value, t, i);
|
gen_static_field (exp->gdbarch, ax, value, t, i);
|
||||||
|
if (value->optimized_out)
|
||||||
|
error (_("static field `%s' has been optimized out, cannot use"),
|
||||||
|
fieldname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (TYPE_FIELD_PACKED (t, i))
|
if (TYPE_FIELD_PACKED (t, i))
|
||||||
@ -1526,6 +1605,10 @@ gen_maybe_namespace_elt (struct expression *exp,
|
|||||||
|
|
||||||
gen_var_ref (exp->gdbarch, ax, value, sym);
|
gen_var_ref (exp->gdbarch, ax, value, sym);
|
||||||
|
|
||||||
|
if (value->optimized_out)
|
||||||
|
error (_("`%s' has been optimized out, cannot use"),
|
||||||
|
SYMBOL_PRINT_NAME (sym));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1815,7 +1898,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
|||||||
/* Don't just dispose of the left operand. We might be tracing,
|
/* Don't just dispose of the left operand. We might be tracing,
|
||||||
in which case we want to emit code to trace it if it's an
|
in which case we want to emit code to trace it if it's an
|
||||||
lvalue. */
|
lvalue. */
|
||||||
gen_traced_pop (ax, &value1);
|
gen_traced_pop (exp->gdbarch, ax, &value1);
|
||||||
gen_expr (exp, pc, ax, value);
|
gen_expr (exp, pc, ax, value);
|
||||||
/* It's the consumer's responsibility to trace the right operand. */
|
/* It's the consumer's responsibility to trace the right operand. */
|
||||||
break;
|
break;
|
||||||
@ -1831,6 +1914,11 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
|||||||
|
|
||||||
case OP_VAR_VALUE:
|
case OP_VAR_VALUE:
|
||||||
gen_var_ref (exp->gdbarch, ax, value, (*pc)[2].symbol);
|
gen_var_ref (exp->gdbarch, ax, value, (*pc)[2].symbol);
|
||||||
|
|
||||||
|
if (value->optimized_out)
|
||||||
|
error (_("`%s' has been optimized out, cannot use"),
|
||||||
|
SYMBOL_PRINT_NAME ((*pc)[2].symbol));
|
||||||
|
|
||||||
(*pc) += 4;
|
(*pc) += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2004,6 +2092,11 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
|||||||
error (_("no `%s' found"), this_name);
|
error (_("no `%s' found"), this_name);
|
||||||
|
|
||||||
gen_var_ref (exp->gdbarch, ax, value, sym);
|
gen_var_ref (exp->gdbarch, ax, value, sym);
|
||||||
|
|
||||||
|
if (value->optimized_out)
|
||||||
|
error (_("`%s' has been optimized out, cannot use"),
|
||||||
|
SYMBOL_PRINT_NAME (sym));
|
||||||
|
|
||||||
(*pc) += 2;
|
(*pc) += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2199,7 +2292,8 @@ cannot subscript requested type: cannot call user defined functions"));
|
|||||||
name comes from a list of local variables of a function. */
|
name comes from a list of local variables of a function. */
|
||||||
|
|
||||||
struct agent_expr *
|
struct agent_expr *
|
||||||
gen_trace_for_var (CORE_ADDR scope, struct symbol *var)
|
gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
|
||||||
|
struct symbol *var)
|
||||||
{
|
{
|
||||||
struct cleanup *old_chain = 0;
|
struct cleanup *old_chain = 0;
|
||||||
struct agent_expr *ax = new_agent_expr (scope);
|
struct agent_expr *ax = new_agent_expr (scope);
|
||||||
@ -2208,10 +2302,18 @@ gen_trace_for_var (CORE_ADDR scope, struct symbol *var)
|
|||||||
old_chain = make_cleanup_free_agent_expr (ax);
|
old_chain = make_cleanup_free_agent_expr (ax);
|
||||||
|
|
||||||
trace_kludge = 1;
|
trace_kludge = 1;
|
||||||
gen_var_ref (NULL, ax, &value, var);
|
gen_var_ref (gdbarch, ax, &value, var);
|
||||||
|
|
||||||
|
/* If there is no actual variable to trace, flag it by returning
|
||||||
|
an empty agent expression. */
|
||||||
|
if (value.optimized_out)
|
||||||
|
{
|
||||||
|
do_cleanups (old_chain);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure we record the final object, and get rid of it. */
|
/* Make sure we record the final object, and get rid of it. */
|
||||||
gen_traced_pop (ax, &value);
|
gen_traced_pop (gdbarch, ax, &value);
|
||||||
|
|
||||||
/* Oh, and terminate. */
|
/* Oh, and terminate. */
|
||||||
ax_simple (ax, aop_end);
|
ax_simple (ax, aop_end);
|
||||||
@ -2245,7 +2347,7 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
|
|||||||
gen_expr (expr, &pc, ax, &value);
|
gen_expr (expr, &pc, ax, &value);
|
||||||
|
|
||||||
/* Make sure we record the final object, and get rid of it. */
|
/* Make sure we record the final object, and get rid of it. */
|
||||||
gen_traced_pop (ax, &value);
|
gen_traced_pop (expr->gdbarch, ax, &value);
|
||||||
|
|
||||||
/* Oh, and terminate. */
|
/* Oh, and terminate. */
|
||||||
ax_simple (ax, aop_end);
|
ax_simple (ax, aop_end);
|
||||||
|
@ -81,6 +81,10 @@ struct axs_value
|
|||||||
"pointer to" an object of this type. */
|
"pointer to" an object of this type. */
|
||||||
struct type *type;
|
struct type *type;
|
||||||
|
|
||||||
|
/* If nonzero, this is a variable which does not actually exist in
|
||||||
|
the program. */
|
||||||
|
char optimized_out;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
/* if kind == axs_lvalue_register, this is the register number */
|
/* if kind == axs_lvalue_register, this is the register number */
|
||||||
@ -99,7 +103,8 @@ struct axs_value
|
|||||||
function to discover which registers the expression uses. */
|
function to discover which registers the expression uses. */
|
||||||
extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
|
extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
|
||||||
|
|
||||||
extern struct agent_expr *gen_trace_for_var (CORE_ADDR, struct symbol *);
|
extern struct agent_expr *gen_trace_for_var (CORE_ADDR, struct gdbarch *,
|
||||||
|
struct symbol *);
|
||||||
|
|
||||||
extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
|
extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
|
||||||
|
|
||||||
|
@ -619,11 +619,11 @@ dwarf2_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
|||||||
struct agent_expr *ax, struct axs_value *value,
|
struct agent_expr *ax, struct axs_value *value,
|
||||||
gdb_byte *data, int size)
|
gdb_byte *data, int size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (!data || size == 0)
|
||||||
error (_("Symbol \"%s\" has been optimized out."),
|
{
|
||||||
SYMBOL_PRINT_NAME (symbol));
|
value->optimized_out = 1;
|
||||||
|
}
|
||||||
if (size == 1
|
else if (size == 1
|
||||||
&& data[0] >= DW_OP_reg0
|
&& data[0] >= DW_OP_reg0
|
||||||
&& data[0] <= DW_OP_reg31)
|
&& data[0] <= DW_OP_reg31)
|
||||||
{
|
{
|
||||||
@ -883,8 +883,6 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
|||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
data = find_location_expression (dlbaton, &size, ax->scope);
|
data = find_location_expression (dlbaton, &size, ax->scope);
|
||||||
if (data == NULL)
|
|
||||||
error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol));
|
|
||||||
|
|
||||||
dwarf2_tracepoint_var_ref (symbol, gdbarch, ax, value, data, size);
|
dwarf2_tracepoint_var_ref (symbol, gdbarch, ax, value, data, size);
|
||||||
}
|
}
|
||||||
|
103
gdb/tracepoint.c
103
gdb/tracepoint.c
@ -949,6 +949,7 @@ collect_symbol (struct collection_list *collect,
|
|||||||
unsigned long len;
|
unsigned long len;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
bfd_signed_vma offset;
|
bfd_signed_vma offset;
|
||||||
|
int treat_as_expr = 0;
|
||||||
|
|
||||||
len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
|
len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
|
||||||
switch (SYMBOL_CLASS (sym))
|
switch (SYMBOL_CLASS (sym))
|
||||||
@ -973,7 +974,12 @@ collect_symbol (struct collection_list *collect,
|
|||||||
SYMBOL_PRINT_NAME (sym), len,
|
SYMBOL_PRINT_NAME (sym), len,
|
||||||
tmp /* address */);
|
tmp /* address */);
|
||||||
}
|
}
|
||||||
add_memrange (collect, memrange_absolute, offset, len);
|
/* A struct may be a C++ class with static fields, go to general
|
||||||
|
expression handling. */
|
||||||
|
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
|
||||||
|
treat_as_expr = 1;
|
||||||
|
else
|
||||||
|
add_memrange (collect, memrange_absolute, offset, len);
|
||||||
break;
|
break;
|
||||||
case LOC_REGISTER:
|
case LOC_REGISTER:
|
||||||
reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
|
reg = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
|
||||||
@ -1038,49 +1044,62 @@ collect_symbol (struct collection_list *collect,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LOC_COMPUTED:
|
case LOC_COMPUTED:
|
||||||
{
|
treat_as_expr = 1;
|
||||||
struct agent_expr *aexpr;
|
|
||||||
struct cleanup *old_chain1 = NULL;
|
|
||||||
struct agent_reqs areqs;
|
|
||||||
|
|
||||||
aexpr = gen_trace_for_var (scope, sym);
|
|
||||||
|
|
||||||
old_chain1 = make_cleanup_free_agent_expr (aexpr);
|
|
||||||
|
|
||||||
ax_reqs (aexpr, &areqs);
|
|
||||||
if (areqs.flaw != agent_flaw_none)
|
|
||||||
error (_("malformed expression"));
|
|
||||||
|
|
||||||
if (areqs.min_height < 0)
|
|
||||||
error (_("gdb: Internal error: expression has min height < 0"));
|
|
||||||
if (areqs.max_height > 20)
|
|
||||||
error (_("expression too complicated, try simplifying"));
|
|
||||||
|
|
||||||
discard_cleanups (old_chain1);
|
|
||||||
add_aexpr (collect, aexpr);
|
|
||||||
|
|
||||||
/* take care of the registers */
|
|
||||||
if (areqs.reg_mask_len > 0)
|
|
||||||
{
|
|
||||||
int ndx1, ndx2;
|
|
||||||
|
|
||||||
for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
|
|
||||||
{
|
|
||||||
QUIT; /* allow user to bail out with ^C */
|
|
||||||
if (areqs.reg_mask[ndx1] != 0)
|
|
||||||
{
|
|
||||||
/* assume chars have 8 bits */
|
|
||||||
for (ndx2 = 0; ndx2 < 8; ndx2++)
|
|
||||||
if (areqs.reg_mask[ndx1] & (1 << ndx2))
|
|
||||||
/* it's used -- record it */
|
|
||||||
add_register (collect,
|
|
||||||
ndx1 * 8 + ndx2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expressions are the most general case. */
|
||||||
|
if (treat_as_expr)
|
||||||
|
{
|
||||||
|
struct agent_expr *aexpr;
|
||||||
|
struct cleanup *old_chain1 = NULL;
|
||||||
|
struct agent_reqs areqs;
|
||||||
|
|
||||||
|
aexpr = gen_trace_for_var (scope, gdbarch, sym);
|
||||||
|
|
||||||
|
/* It can happen that the symbol is recorded as a computed
|
||||||
|
location, but it's been optimized away and doesn't actually
|
||||||
|
have a location expression. */
|
||||||
|
if (!aexpr)
|
||||||
|
{
|
||||||
|
printf_filtered ("%s has been optimized out of existence.\n",
|
||||||
|
SYMBOL_PRINT_NAME (sym));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_chain1 = make_cleanup_free_agent_expr (aexpr);
|
||||||
|
|
||||||
|
ax_reqs (aexpr, &areqs);
|
||||||
|
if (areqs.flaw != agent_flaw_none)
|
||||||
|
error (_("malformed expression"));
|
||||||
|
|
||||||
|
if (areqs.min_height < 0)
|
||||||
|
error (_("gdb: Internal error: expression has min height < 0"));
|
||||||
|
if (areqs.max_height > 20)
|
||||||
|
error (_("expression too complicated, try simplifying"));
|
||||||
|
|
||||||
|
discard_cleanups (old_chain1);
|
||||||
|
add_aexpr (collect, aexpr);
|
||||||
|
|
||||||
|
/* take care of the registers */
|
||||||
|
if (areqs.reg_mask_len > 0)
|
||||||
|
{
|
||||||
|
int ndx1, ndx2;
|
||||||
|
|
||||||
|
for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
|
||||||
|
{
|
||||||
|
QUIT; /* allow user to bail out with ^C */
|
||||||
|
if (areqs.reg_mask[ndx1] != 0)
|
||||||
|
{
|
||||||
|
/* assume chars have 8 bits */
|
||||||
|
for (ndx2 = 0; ndx2 < 8; ndx2++)
|
||||||
|
if (areqs.reg_mask[ndx1] & (1 << ndx2))
|
||||||
|
/* it's used -- record it */
|
||||||
|
add_register (collect, ndx1 * 8 + ndx2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add all locals (or args) symbols to collection list */
|
/* Add all locals (or args) symbols to collection list */
|
||||||
|
Loading…
Reference in New Issue
Block a user