diff options
author | Tom Tromey <tromey@redhat.com> | 2013-03-21 16:09:27 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2013-03-21 16:09:27 +0000 |
commit | 92bc6a206434a8b6922846d064e9c701a5a10a0e (patch) | |
tree | 028fd4cec6f31f542d202e4294faa70a66383abd /gdb/ax-gdb.c | |
parent | 81f5558e3d93654ed79b6ea28850a4798ea1404f (diff) | |
download | gdb-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.c | 92 |
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); } |