X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fax-gdb.c;h=a60603f7b65f7755f2af55185d875fadcf8af6c4;hb=fab39d55fa914ad1cea809848899c76c64eaab9d;hp=9cb8fe9a873b4ddace1bb63ca6c73d60a78893e3;hpb=744a80590447619c1c58d7d6a6e780ae6bd29777;p=platform%2Fupstream%2Fbinutils.git diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 9cb8fe9..a60603f 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1,7 +1,6 @@ /* GDB-specific functions for operating on agent expressions. - Copyright (C) 1998-2001, 2003, 2007-2012 Free Software Foundation, - Inc. + Copyright (C) 1998-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -31,11 +30,9 @@ #include "target.h" #include "ax.h" #include "ax-gdb.h" -#include "gdb_string.h" #include "block.h" #include "regcache.h" #include "user-regs.h" -#include "language.h" #include "dictionary.h" #include "breakpoint.h" #include "tracepoint.h" @@ -43,6 +40,7 @@ #include "arch-utils.h" #include "cli/cli-utils.h" #include "linespec.h" +#include "objfiles.h" #include "valprint.h" #include "c-lang.h" @@ -313,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. */ @@ -402,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 @@ -442,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); } } @@ -460,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; @@ -470,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); @@ -510,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)); @@ -663,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)) { @@ -738,26 +712,20 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, case LOC_UNRESOLVED: { - struct minimal_symbol *msym + struct bound_minimal_symbol msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL); - if (!msym) + if (!msym.minsym) error (_("Couldn't resolve symbol `%s'."), SYMBOL_PRINT_NAME (var)); /* Push the address of the variable. */ - ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym)); + ax_const_l (ax, BMSYMBOL_VALUE_ADDRESS (msym)); value->kind = axs_lvalue_memory; } 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 @@ -1362,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); @@ -1931,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 @@ -1958,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; @@ -1967,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 @@ -2048,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; @@ -2219,7 +2187,7 @@ gen_expr (struct expression *exp, union exp_element **pc, case OP_THIS: { struct symbol *sym, *func; - struct block *b; + const struct block *b; const struct language_defn *lang; b = block_for_pc (ax->scope); @@ -2425,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); @@ -2433,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 @@ -2465,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); @@ -2475,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); @@ -2510,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); @@ -2527,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); @@ -2535,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); @@ -2559,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); @@ -2606,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); } @@ -2719,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; @@ -2736,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.")); @@ -2752,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);