X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fstap-probe.c;h=d96cb9fd6d316becc36e211275357b8683c463fe;hb=35fd2deb6916e972248d52b1bc1d584fa9059f8f;hp=23202d7ca83fdacc30abc66f4f814c2bb0f17cf0;hpb=474ca4f6871d4addb7ce6a177245bce79c89550e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index 23202d7ca8..d96cb9fd6d 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -1,6 +1,6 @@ /* SystemTap probe support for GDB. - Copyright (C) 2012-2014 Free Software Foundation, Inc. + Copyright (C) 2012-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -28,7 +28,6 @@ #include "gdbcmd.h" #include "filenames.h" #include "value.h" -#include "exceptions.h" #include "ax.h" #include "ax-gdb.h" #include "complaints.h" @@ -48,7 +47,7 @@ /* Forward declaration. */ -static const struct probe_ops stap_probe_ops; +extern const struct probe_ops stap_probe_ops; /* Should we display debug information for the probe's argument expression parsing? */ @@ -314,9 +313,8 @@ stap_get_opcode (const char **s) break; default: - internal_error (__FILE__, __LINE__, - _("Invalid opcode in expression `%s' for SystemTap" - "probe"), *s); + error (_("Invalid opcode in expression `%s' for SystemTap" + "probe"), *s); } return op; @@ -327,7 +325,8 @@ stap_get_opcode (const char **s) static struct type * stap_get_expected_argument_type (struct gdbarch *gdbarch, - enum stap_arg_bitness b) + enum stap_arg_bitness b, + const struct stap_probe *probe) { switch (b) { @@ -362,8 +361,8 @@ stap_get_expected_argument_type (struct gdbarch *gdbarch, return builtin_type (gdbarch)->builtin_uint64; default: - internal_error (__FILE__, __LINE__, - _("Undefined bitness for probe.")); + error (_("Undefined bitness for probe '%s'."), + probe->p.name); break; } } @@ -654,7 +653,7 @@ stap_parse_register_operand (struct stap_parse_info *p) len = p->arg - start; - regname = alloca (len + gdb_reg_prefix_len + gdb_reg_suffix_len + 1); + regname = (char *) alloca (len + gdb_reg_prefix_len + gdb_reg_suffix_len + 1); regname[0] = '\0'; /* We only add the GDB's register prefix/suffix if we are dealing with @@ -1051,9 +1050,9 @@ stap_parse_argument (const char **arg, struct type *atype, struct cleanup *back_to; /* We need to initialize the expression buffer, in order to begin - our parsing efforts. The language here does not matter, since we - are using our own parser. */ - initialize_expout (&p.pstate, 10, current_language, gdbarch); + our parsing efforts. We use language_c here because we may need + to do pointer arithmetics. */ + initialize_expout (&p.pstate, 10, language_def (language_c), gdbarch); back_to = make_cleanup (free_current_contents, &p.pstate.expout); p.saved_arg = *arg; @@ -1173,7 +1172,8 @@ stap_parse_probe_arguments (struct stap_probe *probe, struct gdbarch *gdbarch) else arg.bitness = STAP_ARG_BITNESS_UNDEFINED; - arg.atype = stap_get_expected_argument_type (gdbarch, arg.bitness); + arg.atype = stap_get_expected_argument_type (gdbarch, arg.bitness, + probe); expr = stap_parse_argument (&cur, arg.atype, gdbarch); @@ -1279,12 +1279,26 @@ stap_is_operator (const char *op) return ret; } +/* Return argument N of probe PROBE. + + If the probe's arguments have not been parsed yet, parse them. If + there are no arguments, throw an exception (error). Otherwise, + return the requested argument. */ + static struct stap_probe_arg * stap_get_arg (struct stap_probe *probe, unsigned n, struct gdbarch *gdbarch) { if (!probe->args_parsed) stap_parse_probe_arguments (probe, gdbarch); + gdb_assert (probe->args_parsed); + if (probe->args_u.vec == NULL) + internal_error (__FILE__, __LINE__, + _("Probe '%s' apparently does not have arguments, but \n" + "GDB is requesting its argument number %u anyway. " + "This should not happen. Please report this bug."), + probe->p.name, n); + return VEC_index (stap_probe_arg_s, probe->args_u.vec, n); } @@ -1366,79 +1380,6 @@ stap_probe_destroy (struct probe *probe_generic) -/* This is called to compute the value of one of the $_probe_arg* - convenience variables. */ - -static struct value * -compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar, - void *data) -{ - struct frame_info *frame = get_selected_frame (_("No frame selected")); - CORE_ADDR pc = get_frame_pc (frame); - int sel = (int) (uintptr_t) data; - struct bound_probe pc_probe; - const struct sym_probe_fns *pc_probe_fns; - unsigned n_args; - - /* SEL == -1 means "_probe_argc". */ - gdb_assert (sel >= -1); - - pc_probe = find_probe_by_pc (pc); - if (pc_probe.probe == NULL) - error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc)); - - n_args = get_probe_argument_count (pc_probe.probe, frame); - if (sel == -1) - return value_from_longest (builtin_type (arch)->builtin_int, n_args); - - if (sel >= n_args) - error (_("Invalid probe argument %d -- probe has %u arguments available"), - sel, n_args); - - return evaluate_probe_argument (pc_probe.probe, sel, frame); -} - -/* This is called to compile one of the $_probe_arg* convenience - variables into an agent expression. */ - -static void -compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr, - struct axs_value *value, void *data) -{ - CORE_ADDR pc = expr->scope; - int sel = (int) (uintptr_t) data; - struct bound_probe pc_probe; - const struct sym_probe_fns *pc_probe_fns; - int n_args; - struct frame_info *frame = get_selected_frame (NULL); - - /* SEL == -1 means "_probe_argc". */ - gdb_assert (sel >= -1); - - pc_probe = find_probe_by_pc (pc); - if (pc_probe.probe == NULL) - error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc)); - - n_args = get_probe_argument_count (pc_probe.probe, frame); - - if (sel == -1) - { - value->kind = axs_rvalue; - value->type = builtin_type (expr->gdbarch)->builtin_int; - ax_const_l (expr, n_args); - return; - } - - gdb_assert (sel >= 0); - if (sel >= n_args) - error (_("Invalid probe argument %d -- probe has %d arguments available"), - sel, n_args); - - pc_probe.probe->pops->compile_to_ax (pc_probe.probe, expr, value, sel); -} - - - /* Set or clear a SystemTap semaphore. ADDRESS is the semaphore's address. SET is zero if the semaphore should be cleared, or one if it should be set. This is a helper function for `stap_semaphore_down' @@ -1515,15 +1456,6 @@ stap_clear_semaphore (struct probe *probe_generic, struct objfile *objfile, stap_modify_semaphore (addr, 0, gdbarch); } -/* Implementation of `$_probe_arg*' set of variables. */ - -static const struct internalvar_funcs probe_funcs = -{ - compute_probe_arg, - compile_probe_arg, - NULL -}; - /* Helper function that parses the information contained in a SystemTap's probe. Basically, the information consists in: @@ -1550,14 +1482,15 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el, const char *probe_args = NULL; struct stap_probe *ret; - ret = obstack_alloc (&objfile->per_bfd->storage_obstack, sizeof (*ret)); + ret = XOBNEW (&objfile->per_bfd->storage_obstack, struct stap_probe); ret->p.pops = &stap_probe_ops; ret->p.arch = gdbarch; /* Provider and the name of the probe. */ ret->p.provider = (char *) &el->data[3 * size]; - ret->p.name = memchr (ret->p.provider, '\0', - (char *) el->data + el->size - ret->p.provider); + ret->p.name = ((const char *) + memchr (ret->p.provider, '\0', + (char *) el->data + el->size - ret->p.provider)); /* Making sure there is a name. */ if (ret->p.name == NULL) { @@ -1587,8 +1520,9 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el, /* Arguments. We can only extract the argument format if there is a valid name for this probe. */ - probe_args = memchr (ret->p.name, '\0', - (char *) el->data + el->size - ret->p.name); + probe_args = ((const char*) + memchr (ret->p.name, '\0', + (char *) el->data + el->size - ret->p.name)); if (probe_args != NULL) ++probe_args; @@ -1606,7 +1540,7 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el, } ret->args_parsed = 0; - ret->args_u.text = (void *) probe_args; + ret->args_u.text = probe_args; /* Successfully created probe. */ VEC_safe_push (probe_p, *probesp, (struct probe *) ret); @@ -1618,7 +1552,7 @@ handle_stap_probe (struct objfile *objfile, struct sdt_note *el, static void get_stap_base_address_1 (bfd *abfd, asection *sect, void *obj) { - asection **ret = obj; + asection **ret = (asection **) obj; if ((sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS)) && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME)) @@ -1704,6 +1638,15 @@ stap_get_probes (VEC (probe_p) **probesp, struct objfile *objfile) } } +/* Implementation of the type_name method. */ + +static const char * +stap_type_name (struct probe *probe) +{ + gdb_assert (probe->pops == &stap_probe_ops); + return "stap"; +} + static int stap_probe_is_linespec (const char **linespecp) { @@ -1743,7 +1686,7 @@ stap_gen_info_probes_table_values (struct probe *probe_generic, /* SystemTap probe_ops. */ -static const struct probe_ops stap_probe_ops = +const struct probe_ops stap_probe_ops = { stap_probe_is_linespec, stap_get_probes, @@ -1755,8 +1698,11 @@ static const struct probe_ops stap_probe_ops = stap_set_semaphore, stap_clear_semaphore, stap_probe_destroy, + stap_type_name, stap_gen_info_probes_table_header, stap_gen_info_probes_table_values, + NULL, /* enable_probe */ + NULL /* disable_probe */ }; /* Implementation of the `info probes stap' command. */ @@ -1784,33 +1730,6 @@ _initialize_stap_probe (void) show_stapexpressiondebug, &setdebuglist, &showdebuglist); - create_internalvar_type_lazy ("_probe_argc", &probe_funcs, - (void *) (uintptr_t) -1); - create_internalvar_type_lazy ("_probe_arg0", &probe_funcs, - (void *) (uintptr_t) 0); - create_internalvar_type_lazy ("_probe_arg1", &probe_funcs, - (void *) (uintptr_t) 1); - create_internalvar_type_lazy ("_probe_arg2", &probe_funcs, - (void *) (uintptr_t) 2); - create_internalvar_type_lazy ("_probe_arg3", &probe_funcs, - (void *) (uintptr_t) 3); - create_internalvar_type_lazy ("_probe_arg4", &probe_funcs, - (void *) (uintptr_t) 4); - create_internalvar_type_lazy ("_probe_arg5", &probe_funcs, - (void *) (uintptr_t) 5); - create_internalvar_type_lazy ("_probe_arg6", &probe_funcs, - (void *) (uintptr_t) 6); - create_internalvar_type_lazy ("_probe_arg7", &probe_funcs, - (void *) (uintptr_t) 7); - create_internalvar_type_lazy ("_probe_arg8", &probe_funcs, - (void *) (uintptr_t) 8); - create_internalvar_type_lazy ("_probe_arg9", &probe_funcs, - (void *) (uintptr_t) 9); - create_internalvar_type_lazy ("_probe_arg10", &probe_funcs, - (void *) (uintptr_t) 10); - create_internalvar_type_lazy ("_probe_arg11", &probe_funcs, - (void *) (uintptr_t) 11); - add_cmd ("stap", class_info, info_probes_stap_command, _("\ Show information about SystemTap static probes.\n\