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:
Stan Shebs 2009-12-24 00:40:49 +00:00
parent 81e9e6e6ea
commit 0936ad1d22
5 changed files with 143 additions and 12 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

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

View File

@ -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 */