2009-12-23 Stan Shebs <stan@codesourcery.com>
* ax-gdb.h (gen_trace_for_var): Declare. * ax-gdb.c (gen_trace_for_var): New function. * dwarf2loc.c (dwarf_expr_frame_base_1): New function, split from... (dwarf_expr_frame_base): ...here. (dwarf2_tracepoint_var_ref): Add computed location case. * tracepoint.c (collect_symbol): Add scope arg and LOC_COMPUTED case. (add_local_symbols): Update call to collect_symbol. (encode_actions): Ditto.
This commit is contained in:
parent
81e9e6e6ea
commit
0936ad1d22
@ -1,3 +1,15 @@
|
||||
2009-12-23 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* ax-gdb.h (gen_trace_for_var): Declare.
|
||||
* ax-gdb.c (gen_trace_for_var): New function.
|
||||
* dwarf2loc.c (dwarf_expr_frame_base_1): New function, split from...
|
||||
(dwarf_expr_frame_base): ...here.
|
||||
(dwarf2_tracepoint_var_ref): Add computed location case.
|
||||
* tracepoint.c (collect_symbol): Add scope arg and LOC_COMPUTED
|
||||
case.
|
||||
(add_local_symbols): Update call to collect_symbol.
|
||||
(encode_actions): Ditto.
|
||||
|
||||
2009-12-23 Dmitry Gorbachev <d.g.gorbachev@gmail.com>
|
||||
|
||||
PR gdb/11110
|
||||
|
29
gdb/ax-gdb.c
29
gdb/ax-gdb.c
@ -1768,6 +1768,35 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
||||
}
|
||||
|
||||
|
||||
/* Given a single variable and a scope, generate bytecodes to trace
|
||||
its value. This is for use in situations where we have only a
|
||||
variable's name, and no parsed expression; for instance, when the
|
||||
name comes from a list of local variables of a function. */
|
||||
|
||||
struct agent_expr *
|
||||
gen_trace_for_var (CORE_ADDR scope, struct symbol *var)
|
||||
{
|
||||
struct cleanup *old_chain = 0;
|
||||
struct agent_expr *ax = new_agent_expr (scope);
|
||||
struct axs_value value;
|
||||
|
||||
old_chain = make_cleanup_free_agent_expr (ax);
|
||||
|
||||
trace_kludge = 1;
|
||||
gen_var_ref (NULL, ax, &value, var);
|
||||
|
||||
/* Make sure we record the final object, and get rid of it. */
|
||||
gen_traced_pop (ax, &value);
|
||||
|
||||
/* Oh, and terminate. */
|
||||
ax_simple (ax, aop_end);
|
||||
|
||||
/* We have successfully built the agent expr, so cancel the cleanup
|
||||
request. If we add more cleanups that we always want done, this
|
||||
will have to get more complicated. */
|
||||
discard_cleanups (old_chain);
|
||||
return ax;
|
||||
}
|
||||
|
||||
/* Generating bytecode from GDB expressions: driver */
|
||||
|
||||
|
@ -99,6 +99,8 @@ struct axs_value
|
||||
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_var (CORE_ADDR, struct symbol *);
|
||||
|
||||
extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
|
||||
|
||||
#endif /* AX_GDB_H */
|
||||
|
@ -41,6 +41,10 @@
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
static void
|
||||
dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
|
||||
gdb_byte **start, size_t *length);
|
||||
|
||||
/* A helper function for dealing with location lists. Given a
|
||||
symbol baton (BATON) and a pc value (PC), find the appropriate
|
||||
location expression, set *LOCEXPR_LENGTH, and return a pointer
|
||||
@ -166,16 +170,23 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
|
||||
something has gone wrong. */
|
||||
gdb_assert (framefunc != NULL);
|
||||
|
||||
dwarf_expr_frame_base_1 (framefunc,
|
||||
get_frame_address_in_block (debaton->frame),
|
||||
start, length);
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
|
||||
gdb_byte **start, size_t *length)
|
||||
{
|
||||
if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
|
||||
*start = NULL;
|
||||
else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
|
||||
{
|
||||
struct dwarf2_loclist_baton *symbaton;
|
||||
struct frame_info *frame = debaton->frame;
|
||||
|
||||
symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
||||
*start = find_location_expression (symbaton, length,
|
||||
get_frame_address_in_block (frame));
|
||||
*start = find_location_expression (symbaton, length, pc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -617,21 +628,52 @@ dwarf2_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
||||
}
|
||||
else if (data[0] == DW_OP_fbreg)
|
||||
{
|
||||
/* And this is worse than just minimal; we should honor the frame base
|
||||
as above. */
|
||||
int frame_reg;
|
||||
struct block *b;
|
||||
struct symbol *framefunc;
|
||||
int frame_reg = 0;
|
||||
LONGEST frame_offset;
|
||||
gdb_byte *buf_end;
|
||||
gdb_byte *base_data;
|
||||
size_t base_size;
|
||||
LONGEST base_offset = 0;
|
||||
|
||||
b = block_for_pc (ax->scope);
|
||||
|
||||
if (!b)
|
||||
error (_("No block found for address"));
|
||||
|
||||
framefunc = block_linkage_function (b);
|
||||
|
||||
if (!framefunc)
|
||||
error (_("No function found for block"));
|
||||
|
||||
dwarf_expr_frame_base_1 (framefunc, ax->scope,
|
||||
&base_data, &base_size);
|
||||
|
||||
if (base_data[0] >= DW_OP_breg0
|
||||
&& base_data[0] <= DW_OP_breg31)
|
||||
{
|
||||
frame_reg = base_data[0] - DW_OP_breg0;
|
||||
buf_end = read_sleb128 (base_data + 1, base_data + base_size, &base_offset);
|
||||
if (buf_end != base_data + base_size)
|
||||
error (_("Unexpected opcode after DW_OP_breg%u for symbol \"%s\"."),
|
||||
frame_reg, SYMBOL_PRINT_NAME (symbol));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't know what to do with the frame base expression,
|
||||
so we can't trace this variable; give up. */
|
||||
error (_("Cannot generate expression to collect symbol \"%s\"; DWARF 2 encoding not handled"),
|
||||
SYMBOL_PRINT_NAME (symbol));
|
||||
}
|
||||
|
||||
buf_end = read_sleb128 (data + 1, data + size, &frame_offset);
|
||||
if (buf_end != data + size)
|
||||
error (_("Unexpected opcode after DW_OP_fbreg for symbol \"%s\"."),
|
||||
SYMBOL_PRINT_NAME (symbol));
|
||||
|
||||
gdbarch_virtual_frame_pointer (gdbarch,
|
||||
ax->scope, &frame_reg, &frame_offset);
|
||||
ax_reg (ax, frame_reg);
|
||||
ax_const_l (ax, frame_offset);
|
||||
ax_const_l (ax, base_offset + frame_offset);
|
||||
ax_simple (ax, aop_add);
|
||||
|
||||
value->kind = axs_lvalue_memory;
|
||||
|
@ -729,7 +729,8 @@ static void
|
||||
collect_symbol (struct collection_list *collect,
|
||||
struct symbol *sym,
|
||||
struct gdbarch *gdbarch,
|
||||
long frame_regno, long frame_offset)
|
||||
long frame_regno, long frame_offset,
|
||||
CORE_ADDR scope)
|
||||
{
|
||||
unsigned long len;
|
||||
unsigned int reg;
|
||||
@ -821,6 +822,50 @@ collect_symbol (struct collection_list *collect,
|
||||
printf_filtered ("%s has been optimized out of existence.\n",
|
||||
SYMBOL_PRINT_NAME (sym));
|
||||
break;
|
||||
|
||||
case LOC_COMPUTED:
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -847,7 +892,7 @@ add_local_symbols (struct collection_list *collect,
|
||||
{
|
||||
count++;
|
||||
collect_symbol (collect, sym, gdbarch,
|
||||
frame_regno, frame_offset);
|
||||
frame_regno, frame_offset, pc);
|
||||
}
|
||||
}
|
||||
if (BLOCK_FUNCTION (block))
|
||||
@ -1126,7 +1171,8 @@ encode_actions (struct breakpoint *t, char ***tdp_actions,
|
||||
exp->elts[2].symbol,
|
||||
t->gdbarch,
|
||||
frame_reg,
|
||||
frame_offset);
|
||||
frame_offset,
|
||||
t->loc->address);
|
||||
break;
|
||||
|
||||
default: /* full-fledged expression */
|
||||
|
Loading…
x
Reference in New Issue
Block a user