aboutsummaryrefslogtreecommitdiff
path: root/gdb/ax-gdb.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2013-03-21 16:09:27 +0000
committerTom Tromey <tromey@redhat.com>2013-03-21 16:09:27 +0000
commit92bc6a206434a8b6922846d064e9c701a5a10a0e (patch)
tree028fd4cec6f31f542d202e4294faa70a66383abd /gdb/ax-gdb.c
parent81f5558e3d93654ed79b6ea28850a4798ea1404f (diff)
downloadgdb-92bc6a206434a8b6922846d064e9c701a5a10a0e.zip
gdb-92bc6a206434a8b6922846d064e9c701a5a10a0e.tar.gz
gdb-92bc6a206434a8b6922846d064e9c701a5a10a0e.tar.bz2
* tracepoint.h (decode_agent_options): Add 'trace_string'
argument. * tracepoint.c (decode_agent_options): Add 'trace_string' argument. (validate_actionline): Update. (collect_symbol): Add 'trace_string' argument. (struct add_local_symbols_data) <trace_string>: New field. (do_collect_symbol): Update. (add_local_symbols): Add 'trace_string' argument. (encode_actions_1): Update. (trace_dump_actions): Update. * dwarf2loc.c (access_memory): Update. * ax.h (struct agent_expr) <tracing, trace_string>: New fields. * ax-general.c (new_agent_expr): Update. * ax-gdb.h (gen_trace_for_expr, gen_trace_for_var) (gen_trace_for_return_address): Add argument. (trace_kludge, trace_string_kludge): Remove. * ax-gdb.c (trace_kludge, trace_string_kludge): Remove. (gen_traced_pop, gen_fetch, gen_bitfield_ref, gen_expr): Update. (gen_trace_for_var): Add 'trace_string' argument. (gen_trace_for_expr, gen_trace_for_return_address): Likewise. (gen_printf, agent_eval_command_one): Update.
Diffstat (limited to 'gdb/ax-gdb.c')
-rw-r--r--gdb/ax-gdb.c92
1 files changed, 36 insertions, 56 deletions
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 25179ad..4196655 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -312,36 +312,6 @@ maybe_const_expr (union exp_element **pc)
sizes), and this is simpler.) */
-/* Generating bytecode from GDB expressions: the `trace' kludge */
-
-/* The compiler in this file is a general-purpose mechanism for
- translating GDB expressions into bytecode. One ought to be able to
- find a million and one uses for it.
-
- However, at the moment it is HOPELESSLY BRAIN-DAMAGED for the sake
- of expediency. Let he who is without sin cast the first stone.
-
- For the data tracing facility, we need to insert `trace' bytecodes
- before each data fetch; this records all the memory that the
- expression touches in the course of evaluation, so that memory will
- be available when the user later tries to evaluate the expression
- in GDB.
-
- This should be done (I think) in a post-processing pass, that walks
- an arbitrary agent expression and inserts `trace' operations at the
- appropriate points. But it's much faster to just hack them
- directly into the code. And since we're in a crunch, that's what
- I've done.
-
- Setting the flag trace_kludge to non-zero enables the code that
- emits the trace bytecodes at the appropriate points. */
-int trace_kludge;
-
-/* Inspired by trace_kludge, this indicates that pointers to chars
- should get an added tracenz bytecode to record nonzero bytes, up to
- a length that is the value of trace_string_kludge. */
-int trace_string_kludge;
-
/* Scan for all static fields in the given class, including any base
classes, and generate tracing bytecodes for each. */
@@ -401,19 +371,19 @@ gen_traced_pop (struct gdbarch *gdbarch,
struct agent_expr *ax, struct axs_value *value)
{
int string_trace = 0;
- if (trace_string_kludge
+ if (ax->trace_string
&& TYPE_CODE (value->type) == TYPE_CODE_PTR
&& c_textual_element_type (check_typedef (TYPE_TARGET_TYPE (value->type)),
's'))
string_trace = 1;
- if (trace_kludge)
+ if (ax->tracing)
switch (value->kind)
{
case axs_rvalue:
if (string_trace)
{
- ax_const_l (ax, trace_string_kludge);
+ ax_const_l (ax, ax->trace_string);
ax_simple (ax, aop_tracenz);
}
else
@@ -441,7 +411,7 @@ gen_traced_pop (struct gdbarch *gdbarch,
if (string_trace)
{
ax_simple (ax, aop_ref32);
- ax_const_l (ax, trace_string_kludge);
+ ax_const_l (ax, ax->trace_string);
ax_simple (ax, aop_tracenz);
}
}
@@ -459,7 +429,7 @@ gen_traced_pop (struct gdbarch *gdbarch,
if (string_trace)
{
ax_reg (ax, value->u.reg);
- ax_const_l (ax, trace_string_kludge);
+ ax_const_l (ax, ax->trace_string);
ax_simple (ax, aop_tracenz);
}
break;
@@ -469,7 +439,7 @@ gen_traced_pop (struct gdbarch *gdbarch,
ax_simple (ax, aop_pop);
/* To trace C++ classes with static fields stored elsewhere. */
- if (trace_kludge
+ if (ax->tracing
&& (TYPE_CODE (value->type) == TYPE_CODE_STRUCT
|| TYPE_CODE (value->type) == TYPE_CODE_UNION))
gen_trace_static_fields (gdbarch, ax, value->type);
@@ -509,7 +479,7 @@ gen_extend (struct agent_expr *ax, struct type *type)
static void
gen_fetch (struct agent_expr *ax, struct type *type)
{
- if (trace_kludge)
+ if (ax->tracing)
{
/* Record the area of memory we're about to fetch. */
ax_trace_quick (ax, TYPE_LENGTH (type));
@@ -1361,7 +1331,7 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
/* Add the offset. */
gen_offset (ax, offset / TARGET_CHAR_BIT);
- if (trace_kludge)
+ if (ax->tracing)
{
/* Record the area of memory we're about to fetch. */
ax_trace_quick (ax, op_size / TARGET_CHAR_BIT);
@@ -1930,7 +1900,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
if (tsv)
{
ax_tsv (ax, aop_setv, tsv->number);
- if (trace_kludge)
+ if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
}
else
@@ -1957,7 +1927,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
{
/* The tsv will be the left half of the binary operation. */
ax_tsv (ax, aop_getv, tsv->number);
- if (trace_kludge)
+ if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
/* Trace state variables are always 64-bit integers. */
value1.kind = axs_rvalue;
@@ -1966,7 +1936,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
gen_expr_binop_rest (exp, op2, pc, ax, value, &value1, &value2);
/* We have a result of the binary op, set the tsv. */
ax_tsv (ax, aop_setv, tsv->number);
- if (trace_kludge)
+ if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
}
else
@@ -2047,7 +2017,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
if (tsv)
{
ax_tsv (ax, aop_getv, tsv->number);
- if (trace_kludge)
+ if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
/* Trace state variables are always 64-bit integers. */
value->kind = axs_rvalue;
@@ -2424,7 +2394,7 @@ gen_expr_binop_rest (struct expression *exp,
struct agent_expr *
gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
- struct symbol *var)
+ struct symbol *var, int trace_string)
{
struct cleanup *old_chain = 0;
struct agent_expr *ax = new_agent_expr (gdbarch, scope);
@@ -2432,7 +2402,8 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
old_chain = make_cleanup_free_agent_expr (ax);
- trace_kludge = 1;
+ ax->tracing = 1;
+ ax->trace_string = trace_string;
gen_var_ref (gdbarch, ax, &value, var);
/* If there is no actual variable to trace, flag it by returning
@@ -2464,7 +2435,8 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
caller can then use the ax_reqs function to discover which
registers it relies upon. */
struct agent_expr *
-gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
+gen_trace_for_expr (CORE_ADDR scope, struct expression *expr,
+ int trace_string)
{
struct cleanup *old_chain = 0;
struct agent_expr *ax = new_agent_expr (expr->gdbarch, scope);
@@ -2474,7 +2446,8 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
old_chain = make_cleanup_free_agent_expr (ax);
pc = expr->elts;
- trace_kludge = 1;
+ ax->tracing = 1;
+ ax->trace_string = trace_string;
value.optimized_out = 0;
gen_expr (expr, &pc, ax, &value);
@@ -2509,7 +2482,7 @@ gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
old_chain = make_cleanup_free_agent_expr (ax);
pc = expr->elts;
- trace_kludge = 0;
+ ax->tracing = 0;
value.optimized_out = 0;
gen_expr (expr, &pc, ax, &value);
@@ -2526,7 +2499,8 @@ gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
}
struct agent_expr *
-gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch)
+gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch,
+ int trace_string)
{
struct cleanup *old_chain = 0;
struct agent_expr *ax = new_agent_expr (gdbarch, scope);
@@ -2534,7 +2508,8 @@ gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch)
old_chain = make_cleanup_free_agent_expr (ax);
- trace_kludge = 1;
+ ax->tracing = 1;
+ ax->trace_string = trace_string;
gdbarch_gen_return_address (gdbarch, ax, &value, scope);
@@ -2570,13 +2545,14 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
old_chain = make_cleanup_free_agent_expr (ax);
+ /* We're computing values, not doing side effects. */
+ ax->tracing = 0;
+
/* Evaluate and push the args on the stack in reverse order,
for simplicity of collecting them on the target side. */
for (tem = nargs - 1; tem >= 0; --tem)
{
pc = exprs[tem]->elts;
- /* We're computing values, not doing side effects. */
- trace_kludge = 0;
value.optimized_out = 0;
gen_expr (exprs[tem], &pc, ax, &value);
require_rvalue (ax, &value);
@@ -2609,18 +2585,19 @@ agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc)
struct expression *expr;
struct agent_expr *agent;
const char *arg;
+ int trace_string = 0;
if (!eval)
{
- trace_string_kludge = 0;
if (*exp == '/')
- exp = decode_agent_options (exp);
+ exp = decode_agent_options (exp, &trace_string);
}
arg = exp;
if (!eval && strcmp (arg, "$_ret") == 0)
{
- agent = gen_trace_for_return_address (pc, get_current_arch ());
+ agent = gen_trace_for_return_address (pc, get_current_arch (),
+ trace_string);
old_chain = make_cleanup_free_agent_expr (agent);
}
else
@@ -2628,9 +2605,12 @@ agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc)
expr = parse_exp_1 (&arg, pc, block_for_pc (pc), 0);
old_chain = make_cleanup (free_current_contents, &expr);
if (eval)
- agent = gen_eval_for_expr (pc, expr);
+ {
+ gdb_assert (trace_string == 0);
+ agent = gen_eval_for_expr (pc, expr);
+ }
else
- agent = gen_trace_for_expr (pc, expr);
+ agent = gen_trace_for_expr (pc, expr, trace_string);
make_cleanup_free_agent_expr (agent);
}