X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fax-gdb.c;h=9e27265eed1209874f3ae764d37d7d24bfa9a726;hb=9f1b45b0da430a7a7abf9e54acbe6f2ef9d3a763;hp=f0e33cb009e0f347df9a57fef59f3363328f8e5b;hpb=28e7fd62340426746f9c896cbc40c5d374ec47aa;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index f0e33cb009..9e27265eed 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1,6 +1,6 @@ /* GDB-specific functions for operating on agent expressions. - Copyright (C) 1998-2013 Free Software Foundation, Inc. + Copyright (C) 1998-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -30,11 +30,10 @@ #include "target.h" #include "ax.h" #include "ax-gdb.h" -#include "gdb_string.h" +#include #include "block.h" #include "regcache.h" #include "user-regs.h" -#include "language.h" #include "dictionary.h" #include "breakpoint.h" #include "tracepoint.h" @@ -312,36 +311,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 +370,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 +410,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 +428,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 +438,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 +478,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)); @@ -662,6 +631,12 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, value->type = check_typedef (SYMBOL_TYPE (var)); value->optimized_out = 0; + if (SYMBOL_COMPUTED_OPS (var) != NULL) + { + SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, gdbarch, ax, value); + return; + } + /* I'm imitating the code in read_var_value. */ switch (SYMBOL_CLASS (var)) { @@ -750,13 +725,7 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, break; case LOC_COMPUTED: - /* FIXME: cagney/2004-01-26: It should be possible to - unconditionally call the SYMBOL_COMPUTED_OPS method when available. - Unfortunately DWARF 2 stores the frame-base (instead of the - function) location in a function's symbol. Oops! For the - moment enable this when/where applicable. */ - SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, gdbarch, ax, value); - break; + gdb_assert_not_reached (_("LOC_COMPUTED variable missing a method")); case LOC_OPTIMIZED_OUT: /* Flag this, but don't say anything; leave it up to callers to @@ -1361,7 +1330,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 +1899,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 +1926,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 +1935,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 +2016,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 +2393,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 +2401,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 +2434,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 +2445,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 +2481,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 +2498,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 +2507,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); @@ -2558,27 +2532,26 @@ gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch) struct agent_expr * gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch, CORE_ADDR function, LONGEST channel, - char *format, int fmtlen, + const char *format, int fmtlen, struct format_piece *frags, int nargs, struct expression **exprs) { - struct expression *expr; struct cleanup *old_chain = 0; struct agent_expr *ax = new_agent_expr (gdbarch, scope); union exp_element *pc; struct axs_value value; - int i, tem, bot, fr, flen; - char *fmt; + int tem; 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); @@ -2605,32 +2578,38 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch, } static void -agent_eval_command_one (char *exp, int eval, CORE_ADDR pc) +agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc) { struct cleanup *old_chain = 0; 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); } - if (!eval && strcmp (exp, "$_ret") == 0) + 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 { - expr = parse_exp_1 (&exp, pc, block_for_pc (pc), 0); + 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); } @@ -2718,8 +2697,8 @@ maint_agent_printf_command (char *exp, int from_tty) struct expression *argvec[100]; struct agent_expr *agent; struct frame_info *fi = get_current_frame (); /* need current scope */ - char *cmdrest; - char *format_start, *format_end; + const char *cmdrest; + const char *format_start, *format_end; struct format_piece *fpieces; int nargs; @@ -2735,7 +2714,7 @@ maint_agent_printf_command (char *exp, int from_tty) cmdrest = exp; - cmdrest = skip_spaces (cmdrest); + cmdrest = skip_spaces_const (cmdrest); if (*cmdrest++ != '"') error (_("Must start with a format string.")); @@ -2751,19 +2730,19 @@ maint_agent_printf_command (char *exp, int from_tty) if (*cmdrest++ != '"') error (_("Bad format string, non-terminated '\"'.")); - cmdrest = skip_spaces (cmdrest); + cmdrest = skip_spaces_const (cmdrest); if (*cmdrest != ',' && *cmdrest != 0) error (_("Invalid argument syntax")); if (*cmdrest == ',') cmdrest++; - cmdrest = skip_spaces (cmdrest); + cmdrest = skip_spaces_const (cmdrest); nargs = 0; while (*cmdrest != '\0') { - char *cmd1; + const char *cmd1; cmd1 = cmdrest; expr = parse_exp_1 (&cmd1, 0, (struct block *) 0, 1);