summaryrefslogtreecommitdiff
path: root/gdb/probe.c
diff options
context:
space:
mode:
authorJose E. Marchesi <jose.marchesi@oracle.com>2015-02-17 15:50:19 +0100
committerJose E. Marchesi <jose.marchesi@oracle.com>2015-02-17 15:50:19 +0100
commit03e98035a2a5d928ceb36ddd7b43369fbf72a008 (patch)
treeb3173b4506e27e0e1fca3ecd82d73c36521445ef /gdb/probe.c
parent6f9b84910f8cabf565598f499258bbea51cc06d4 (diff)
Move `compute_probe_arg' and `compile_probe_arg' to probe.c
This patch moves the `compute_probe_arg' and `compile_probe_arg' functions from stap-probe.c to probe.c. The rationale is that it is reasonable to assume that all backends will provide the `$_probe_argN' convenience variables, and that the user must be placed on the PC of the probe when requesting that information. The value and type of the argument can still be determined by the probe backend via the `pops->evaluate_probe_argument' and `pops->compile_to_ax' handlers. Note that a test in gdb.base/stap-probe.exp had to be adjusted because the "No SystemTap probe at PC" messages are now "No probe at PC". gdb/ChangeLog: 2015-02-17 Jose E. Marchesi <jose.marchesi@oracle.com> * probe.c (compute_probe_arg): Moved from stap-probe.c (compile_probe_arg): Likewise. (probe_funcs): Likewise. * stap-probe.c (compute_probe_arg): Moved to probe.c. (compile_probe_arg): Likewise. (probe_funcs): Likewise. gdb/testsuite/ChangeLog: 2015-02-17 Jose E. Marchesi <jose.marchesi@oracle.com> * gdb.base/stap-probe.exp (stap_test): Remove "SystemTap" from expected message when trying to access $_probe_* convenience variables while not on a probe.
Diffstat (limited to 'gdb/probe.c')
-rw-r--r--gdb/probe.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/gdb/probe.c b/gdb/probe.c
index 5ab2593bf9..7a412776bf 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -30,6 +30,9 @@
#include "gdb_regex.h"
#include "frame.h"
#include "arch-utils.h"
+#include "value.h"
+#include "ax.h"
+#include "ax-gdb.h"
#include <ctype.h>
typedef struct bound_probe bound_probe_s;
@@ -826,6 +829,87 @@ will show information about all types of probes."),
return &info_probes_cmdlist;
}
+
+
+/* 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 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 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);
+}
+
+static const struct internalvar_funcs probe_funcs =
+{
+ compute_probe_arg,
+ compile_probe_arg,
+ NULL
+};
+
+
VEC (probe_ops_cp) *all_probe_ops;
void _initialize_probe (void);
@@ -835,6 +919,33 @@ _initialize_probe (void)
{
VEC_safe_push (probe_ops_cp, all_probe_ops, &probe_ops_any);
+ 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 ("all", class_info, info_probes_command,
_("\
Show information about all type of probes."),