X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fax-gdb.c;h=a77c770aad896660daaf5e928ef2aeae3e77635d;hb=0c0adcc52478ebb707ed780173e18262df6eab7e;hp=6115772729eccda9e5a86b226a1b2166893d0fe2;hpb=40f4af2873b0631bc5f1d4ded2070abe2de2217c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 6115772729..a77c770aad 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-2017 Free Software Foundation, Inc. + Copyright (C) 1998-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -42,11 +42,11 @@ #include "linespec.h" #include "location.h" #include "objfiles.h" - +#include "typeprint.h" #include "valprint.h" #include "c-lang.h" -#include "format.h" +#include "gdbsupport/format.h" /* To make sense of this file, you should read doc/agentexpr.texi. Then look at the types and enums in ax-gdb.h. For the code itself, @@ -158,8 +158,6 @@ static void gen_expr_binop_rest (struct expression *exp, struct axs_value *value, struct axs_value *value1, struct axs_value *value2); - -static void agent_command (char *exp, int from_tty); /* Detecting constant expressions. */ @@ -677,11 +675,11 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) case LOC_TYPEDEF: error (_("Cannot compute value of typedef `%s'."), - SYMBOL_PRINT_NAME (var)); + var->print_name ()); break; case LOC_BLOCK: - ax_const_l (ax, BLOCK_START (SYMBOL_BLOCK_VALUE (var))); + ax_const_l (ax, BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (var))); value->kind = axs_rvalue; break; @@ -707,10 +705,10 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) case LOC_UNRESOLVED: { struct bound_minimal_symbol msym - = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL); + = lookup_minimal_symbol (var->linkage_name (), NULL, NULL); if (!msym.minsym) - error (_("Couldn't resolve symbol `%s'."), SYMBOL_PRINT_NAME (var)); + error (_("Couldn't resolve symbol `%s'."), var->print_name ()); /* Push the address of the variable. */ ax_const_l (ax, BMSYMBOL_VALUE_ADDRESS (msym)); @@ -729,10 +727,27 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) default: error (_("Cannot find value of botched symbol `%s'."), - SYMBOL_PRINT_NAME (var)); + var->print_name ()); break; } } + +/* Generate code for a minimal symbol variable reference to AX. The + variable is the symbol MINSYM, of OBJFILE. Set VALUE to describe + the result. */ + +static void +gen_msym_var_ref (agent_expr *ax, axs_value *value, + minimal_symbol *msymbol, objfile *objf) +{ + CORE_ADDR address; + type *t = find_minsym_type_and_address (msymbol, objf, &address); + value->type = t; + value->optimized_out = false; + ax_const_l (ax, address); + value->kind = axs_lvalue_memory; +} + @@ -1518,7 +1533,7 @@ gen_struct_ref (struct agent_expr *ax, struct axs_value *value, if (!found) error (_("Couldn't find member named `%s' in struct/union/class `%s'"), - field, TYPE_TAG_NAME (type)); + field, TYPE_NAME (type)); } static int @@ -1614,7 +1629,7 @@ gen_namespace_elt (struct agent_expr *ax, struct axs_value *value, if (!found) error (_("No symbol \"%s\" in namespace \"%s\"."), - name, TYPE_TAG_NAME (curtype)); + name, TYPE_NAME (curtype)); return found; } @@ -1629,7 +1644,7 @@ static int gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name) { - const char *namespace_name = TYPE_TAG_NAME (curtype); + const char *namespace_name = TYPE_NAME (curtype); struct block_symbol sym; sym = cp_lookup_symbol_namespace (namespace_name, name, @@ -1643,7 +1658,7 @@ gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), - SYMBOL_PRINT_NAME (sym.symbol)); + sym.symbol->print_name ()); return 1; } @@ -1651,9 +1666,7 @@ gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, static int gen_aggregate_elt_ref (struct agent_expr *ax, struct axs_value *value, - struct type *type, char *field, - const char *operator_name, - const char *operand_name) + struct type *type, char *field) { switch (TYPE_CODE (type)) { @@ -1750,6 +1763,40 @@ gen_sizeof (struct expression *exp, union exp_element **pc, } +/* Generate bytecode for a cast to TO_TYPE. Advance *PC over the + subexpression. */ + +static void +gen_expr_for_cast (struct expression *exp, union exp_element **pc, + struct agent_expr *ax, struct axs_value *value, + struct type *to_type) +{ + enum exp_opcode op = (*pc)[0].opcode; + + /* Don't let symbols be handled with gen_expr because that throws an + "unknown type" error for no-debug data symbols. Instead, we want + the cast to reinterpret such symbols. */ + if (op == OP_VAR_MSYM_VALUE || op == OP_VAR_VALUE) + { + if (op == OP_VAR_VALUE) + { + gen_var_ref (ax, value, (*pc)[2].symbol); + + if (value->optimized_out) + error (_("`%s' has been optimized out, cannot use"), + (*pc)[2].symbol->print_name ()); + } + else + gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile); + if (TYPE_CODE (value->type) == TYPE_CODE_ERROR) + value->type = to_type; + (*pc) += 4; + } + else + gen_expr (exp, pc, ax, value); + gen_cast (ax, value, to_type); +} + /* Generating bytecode from GDB expressions: general recursive thingy */ /* XXX: i18n */ @@ -1864,7 +1911,7 @@ gen_expr (struct expression *exp, union exp_element **pc, gen_expr (exp, pc, ax, &value3); gen_usual_unary (ax, &value3); ax_label (ax, end, ax->len); - /* This is arbitary - what if B and C are incompatible types? */ + /* This is arbitrary - what if B and C are incompatible types? */ value->type = value2.type; value->kind = value2.kind; break; @@ -1961,7 +2008,19 @@ gen_expr (struct expression *exp, union exp_element **pc, if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), - SYMBOL_PRINT_NAME ((*pc)[2].symbol)); + (*pc)[2].symbol->print_name ()); + + if (TYPE_CODE (value->type) == TYPE_CODE_ERROR) + error_unknown_type ((*pc)[2].symbol->print_name ()); + + (*pc) += 4; + break; + + case OP_VAR_MSYM_VALUE: + gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile); + + if (TYPE_CODE (value->type) == TYPE_CODE_ERROR) + error_unknown_type ((*pc)[2].msymbol->linkage_name ()); (*pc) += 4; break; @@ -1977,8 +2036,7 @@ gen_expr (struct expression *exp, union exp_element **pc, internal_error (__FILE__, __LINE__, _("Register $%s not available"), name); /* No support for tracing user registers yet. */ - if (reg >= gdbarch_num_regs (ax->gdbarch) - + gdbarch_num_pseudo_regs (ax->gdbarch)) + if (reg >= gdbarch_num_cooked_regs (ax->gdbarch)) error (_("'%s' is a user-register; " "GDB cannot yet trace user-register contents."), name); @@ -2023,8 +2081,7 @@ gen_expr (struct expression *exp, union exp_element **pc, struct type *type = (*pc)[1].type; (*pc) += 3; - gen_expr (exp, pc, ax, value); - gen_cast (ax, value, type); + gen_expr_for_cast (exp, pc, ax, value, type); } break; @@ -2039,9 +2096,7 @@ gen_expr (struct expression *exp, union exp_element **pc, val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS); type = value_type (val); *pc = &exp->elts[offset]; - - gen_expr (exp, pc, ax, value); - gen_cast (ax, value, type); + gen_expr_for_cast (exp, pc, ax, value, type); } break; @@ -2175,7 +2230,7 @@ gen_expr (struct expression *exp, union exp_element **pc, b = block_for_pc (ax->scope); func = block_linkage_function (b); - lang = language_def (SYMBOL_LANGUAGE (func)); + lang = language_def (func->language ()); sym = lookup_language_this (lang, b).symbol; if (!sym) @@ -2185,7 +2240,7 @@ gen_expr (struct expression *exp, union exp_element **pc, if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), - SYMBOL_PRINT_NAME (sym)); + sym->print_name ()); (*pc) += 2; } @@ -2198,7 +2253,7 @@ gen_expr (struct expression *exp, union exp_element **pc, char *name = &(*pc)[3].string; int found; - found = gen_aggregate_elt_ref (ax, value, type, name, "?", "??"); + found = gen_aggregate_elt_ref (ax, value, type, name); if (!found) error (_("There is no field named %s"), name); (*pc) += 5 + BYTES_TO_EXP_ELEM (length + 1); @@ -2485,7 +2540,6 @@ agent_expr_up gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch, CORE_ADDR function, LONGEST channel, const char *format, int fmtlen, - struct format_piece *frags, int nargs, struct expression **exprs) { agent_expr_up ax (new agent_expr (gdbarch, scope)); @@ -2564,7 +2618,7 @@ agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc) } static void -agent_command_1 (char *exp, int eval) +agent_command_1 (const char *exp, int eval) { /* We don't deal with overlay debugging at the moment. We need to think more carefully about this. If you copy this code into @@ -2579,14 +2633,11 @@ agent_command_1 (char *exp, int eval) if (check_for_argument (&exp, "-at", sizeof ("-at") - 1)) { struct linespec_result canonical; - int ix; - struct linespec_sals *iter; - - exp = skip_spaces (exp); - event_location_up location = new_linespec_location (&exp); + event_location_up location + = new_linespec_location (&exp, symbol_name_match_type::WILD); decode_line_full (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL, - (struct symtab *) NULL, 0, &canonical, + NULL, 0, &canonical, NULL, NULL); exp = skip_spaces (exp); if (exp[0] == ',') @@ -2594,13 +2645,9 @@ agent_command_1 (char *exp, int eval) exp++; exp = skip_spaces (exp); } - for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix) - { - int i; - - for (i = 0; i < iter->sals.nelts; i++) - agent_eval_command_one (exp, eval, iter->sals.sals[i].pc); - } + for (const auto &lsal : canonical.lsals) + for (const auto &sal : lsal.sals) + agent_eval_command_one (exp, eval, sal.pc); } else agent_eval_command_one (exp, eval, get_frame_pc (get_current_frame ())); @@ -2609,7 +2656,7 @@ agent_command_1 (char *exp, int eval) } static void -agent_command (char *exp, int from_tty) +agent_command (const char *exp, int from_tty) { agent_command_1 (exp, 0); } @@ -2619,7 +2666,7 @@ agent_command (char *exp, int from_tty) expression. */ static void -agent_eval_command (char *exp, int from_tty) +agent_eval_command (const char *exp, int from_tty) { agent_command_1 (exp, 1); } @@ -2628,15 +2675,10 @@ agent_eval_command (char *exp, int from_tty) that does a printf, and display the resulting expression. */ static void -maint_agent_printf_command (char *exp, int from_tty) +maint_agent_printf_command (const char *cmdrest, int from_tty) { - struct cleanup *old_chain = 0; - struct expression *argvec[100]; struct frame_info *fi = get_current_frame (); /* need current scope */ - const char *cmdrest; const char *format_start, *format_end; - struct format_piece *fpieces; - int nargs; /* We don't deal with overlay debugging at the moment. We need to think more carefully about this. If you copy this code into @@ -2645,45 +2687,40 @@ maint_agent_printf_command (char *exp, int from_tty) if (overlay_debugging) error (_("GDB can't do agent expression translation with overlays.")); - if (exp == 0) + if (cmdrest == 0) error_no_arg (_("expression to translate")); - cmdrest = exp; - - cmdrest = skip_spaces_const (cmdrest); + cmdrest = skip_spaces (cmdrest); if (*cmdrest++ != '"') error (_("Must start with a format string.")); format_start = cmdrest; - fpieces = parse_format_string (&cmdrest); - - old_chain = make_cleanup (free_format_pieces_cleanup, &fpieces); + format_pieces fpieces (&cmdrest); format_end = cmdrest; if (*cmdrest++ != '"') error (_("Bad format string, non-terminated '\"'.")); - cmdrest = skip_spaces_const (cmdrest); + cmdrest = skip_spaces (cmdrest); if (*cmdrest != ',' && *cmdrest != 0) error (_("Invalid argument syntax")); if (*cmdrest == ',') cmdrest++; - cmdrest = skip_spaces_const (cmdrest); + cmdrest = skip_spaces (cmdrest); - nargs = 0; + std::vector argvec; while (*cmdrest != '\0') { const char *cmd1; cmd1 = cmdrest; expression_up expr = parse_exp_1 (&cmd1, 0, (struct block *) 0, 1); - argvec[nargs] = expr.release (); - ++nargs; + argvec.push_back (expr.release ()); cmdrest = cmd1; if (*cmdrest == ',') ++cmdrest; @@ -2694,28 +2731,25 @@ maint_agent_printf_command (char *exp, int from_tty) agent_expr_up agent = gen_printf (get_frame_pc (fi), get_current_arch (), 0, 0, format_start, format_end - format_start, - fpieces, nargs, argvec); + argvec.size (), argvec.data ()); ax_reqs (agent.get ()); ax_print (gdb_stdout, agent.get ()); /* It would be nice to call ax_reqs here to gather some general info about the expression, and then print out the result. */ - do_cleanups (old_chain); dont_repeat (); } - /* Initialization code. */ -void _initialize_ax_gdb (void); void _initialize_ax_gdb (void) { add_cmd ("agent", class_maintenance, agent_command, _("\ Translate an expression into remote agent bytecode for tracing.\n\ -Usage: maint agent [-at location,] EXPRESSION\n\ +Usage: maint agent [-at LOCATION,] EXPRESSION\n\ If -at is given, generate remote agent bytecode for this location.\n\ If not, generate remote agent bytecode for current frame pc address."), &maintenancelist); @@ -2723,7 +2757,7 @@ If not, generate remote agent bytecode for current frame pc address."), add_cmd ("agent-eval", class_maintenance, agent_eval_command, _("\ Translate an expression into remote agent bytecode for evaluation.\n\ -Usage: maint agent-eval [-at location,] EXPRESSION\n\ +Usage: maint agent-eval [-at LOCATION,] EXPRESSION\n\ If -at is given, generate remote agent bytecode for this location.\n\ If not, generate remote agent bytecode for current frame pc address."), &maintenancelist);