This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2] Sanitize access to gdbarch on the probe API (and fix ARM bug)
- From: Sergio Durigan Junior <sergiodj at redhat dot com>
- To: GDB Patches <gdb-patches at sourceware dot org>
- Cc: Pedro Alves <palves at redhat dot com>
- Date: Fri, 06 Dec 2013 18:31:42 -0200
- Subject: [PATCH v2] Sanitize access to gdbarch on the probe API (and fix ARM bug)
- Authentication-results: sourceware.org; auth=none
This is the second attempt of this patch. After Tom's cleanup, the
patch became much clearer! Thanks, Tom!
The first message on the thread is:
<https://sourceware.org/ml/gdb-patches/2013-12/msg00173.html>
Well, basically the idea is to sanitize the way the probe API (and
SystemTap's API) access gdbarch. Currently, as explained in the first
attempt, the gdbarch being used comes from the objfile, which causes a
bug on ARM systems because the SDT code needs to know the target's
registers and such, and with the objfile's gdbarch on ARM the knowledge
about pseudo-registers is not present. Therefore, after discussions
with Pedro, the decision was to use the selected frame's gdbarch. This
patch does that.
The code has been tested on x86_64 Fedora 17 and ARM Fedora 19.
--
Sergio
2013-12-06 Sergio Durigan Junior <sergiodj@redhat.com>
* probe.c (get_probe_argument_count, can_evaluate_probe_arguments)
(evaluate_probe_argument): Pass selected frame to the
corresponding probe_ops method being called.
* probe.h (struct probe_ops) <get_probe_argument_count,
can_evaluate_probe_arguments, evaluate_probe_argument>: Adjust
declarations to accept frame as argument.
* stap-probe.c (stap_parse_probe_arguments): Adjust declaration to
accept gdbarch as argument. Remove call to get_objfile_arch.
(stap_get_probe_argument_count): Adjust declaration to accept
frame as argument. Obtain gdbarch from frame. Call
can_evaluate_probe_arguments directly instead of the corresponding
probe_ops method. Provide gdbarch to stap_parse_probe_arguments.
(stap_get_arg): Adjust declaration to accept gdbarch as argument.
Pass it to stap_parse_probe_arguments.
(stap_can_evaluate_probe_arguments): Adjust declaration to accept
frame as argument. Obtain gdbarch from it.
(stap_evaluate_probe_argument): Likewise. Pass gdbarch to
stap_get_arg.
(stap_compile_to_ax): Use gdbarch from agent_expr.
(compute_probe_arg): Get gdbarch from frame.
diff --git a/gdb/probe.c b/gdb/probe.c
index c1e0111..b611282 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -616,7 +616,9 @@ info_probes_command (char *arg, int from_tty)
unsigned
get_probe_argument_count (struct probe *probe)
{
- return probe->pops->get_probe_argument_count (probe);
+ struct frame_info *frame = get_selected_frame (_("No frame selected"));
+
+ return probe->pops->get_probe_argument_count (probe, frame);
}
/* See comments in probe.h. */
@@ -624,7 +626,9 @@ get_probe_argument_count (struct probe *probe)
int
can_evaluate_probe_arguments (struct probe *probe)
{
- return probe->pops->can_evaluate_probe_arguments (probe);
+ struct frame_info *frame = get_selected_frame (_("No frame selected"));
+
+ return probe->pops->can_evaluate_probe_arguments (probe, frame);
}
/* See comments in probe.h. */
@@ -632,7 +636,9 @@ can_evaluate_probe_arguments (struct probe *probe)
struct value *
evaluate_probe_argument (struct probe *probe, unsigned n)
{
- return probe->pops->evaluate_probe_argument (probe, n);
+ struct frame_info *frame = get_selected_frame (_("No frame selected"));
+
+ return probe->pops->evaluate_probe_argument (probe, n, frame);
}
/* See comments in probe.h. */
diff --git a/gdb/probe.h b/gdb/probe.h
index dd5387b..6184f6a 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -71,19 +71,22 @@ struct probe_ops
/* Return the number of arguments of PROBE. */
- unsigned (*get_probe_argument_count) (struct probe *probe);
+ unsigned (*get_probe_argument_count) (struct probe *probe,
+ struct frame_info *frame);
/* Return 1 if the probe interface can evaluate the arguments of probe
PROBE, zero otherwise. See the comments on
sym_probe_fns:can_evaluate_probe_arguments for more details. */
- int (*can_evaluate_probe_arguments) (struct probe *probe);
+ int (*can_evaluate_probe_arguments) (struct probe *probe,
+ struct frame_info *frame);
/* Evaluate the Nth argument from the PROBE, returning a value
corresponding to it. The argument number is represented N. */
struct value *(*evaluate_probe_argument) (struct probe *probe,
- unsigned n);
+ unsigned n,
+ struct frame_info *frame);
/* Compile the Nth argument of the PROBE to an agent expression.
The argument number is represented by N. */
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index e09d5d6..9cc2a38 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -914,10 +914,9 @@ stap_parse_argument (const char **arg, struct type *atype,
this information. */
static void
-stap_parse_probe_arguments (struct stap_probe *probe)
+stap_parse_probe_arguments (struct stap_probe *probe, struct gdbarch *gdbarch)
{
const char *cur;
- struct gdbarch *gdbarch = get_objfile_arch (probe->p.objfile);
gdb_assert (!probe->args_parsed);
cur = probe->args_u.text;
@@ -1002,16 +1001,18 @@ stap_parse_probe_arguments (struct stap_probe *probe)
argument string. */
static unsigned
-stap_get_probe_argument_count (struct probe *probe_generic)
+stap_get_probe_argument_count (struct probe *probe_generic,
+ struct frame_info *frame)
{
struct stap_probe *probe = (struct stap_probe *) probe_generic;
+ struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_assert (probe_generic->pops == &stap_probe_ops);
if (!probe->args_parsed)
{
- if (probe_generic->pops->can_evaluate_probe_arguments (probe_generic))
- stap_parse_probe_arguments (probe);
+ if (can_evaluate_probe_arguments (probe_generic))
+ stap_parse_probe_arguments (probe, gdbarch);
else
{
static int have_warned_stap_incomplete = 0;
@@ -1072,10 +1073,10 @@ stap_is_operator (const char *op)
}
static struct stap_probe_arg *
-stap_get_arg (struct stap_probe *probe, unsigned n)
+stap_get_arg (struct stap_probe *probe, unsigned n, struct gdbarch *gdbarch)
{
if (!probe->args_parsed)
- stap_parse_probe_arguments (probe);
+ stap_parse_probe_arguments (probe, gdbarch);
return VEC_index (stap_probe_arg_s, probe->args_u.vec, n);
}
@@ -1083,10 +1084,11 @@ stap_get_arg (struct stap_probe *probe, unsigned n)
/* Implement the `can_evaluate_probe_arguments' method of probe_ops. */
static int
-stap_can_evaluate_probe_arguments (struct probe *probe_generic)
+stap_can_evaluate_probe_arguments (struct probe *probe_generic,
+ struct frame_info *frame)
{
struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
- struct gdbarch *gdbarch = get_objfile_arch (stap_probe->p.objfile);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
/* For SystemTap probes, we have to guarantee that the method
stap_is_single_operand is defined on gdbarch. If it is not, then it
@@ -1098,15 +1100,17 @@ stap_can_evaluate_probe_arguments (struct probe *probe_generic)
corresponding to it. Assertion is thrown if N does not exist. */
static struct value *
-stap_evaluate_probe_argument (struct probe *probe_generic, unsigned n)
+stap_evaluate_probe_argument (struct probe *probe_generic, unsigned n,
+ struct frame_info *frame)
{
struct stap_probe *stap_probe = (struct stap_probe *) probe_generic;
+ struct gdbarch *gdbarch = get_frame_arch (frame);
struct stap_probe_arg *arg;
int pos = 0;
gdb_assert (probe_generic->pops == &stap_probe_ops);
- arg = stap_get_arg (stap_probe, n);
+ arg = stap_get_arg (stap_probe, n, gdbarch);
return evaluate_subexp_standard (arg->atype, arg->aexpr, &pos, EVAL_NORMAL);
}
@@ -1123,7 +1127,7 @@ stap_compile_to_ax (struct probe *probe_generic, struct agent_expr *expr,
gdb_assert (probe_generic->pops == &stap_probe_ops);
- arg = stap_get_arg (stap_probe, n);
+ arg = stap_get_arg (stap_probe, n, expr->gdbarch);
pc = arg->aexpr->elts;
gen_expr (arg->aexpr, &pc, expr, value);
@@ -1165,6 +1169,7 @@ compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
{
struct frame_info *frame = get_selected_frame (_("No frame selected"));
CORE_ADDR pc = get_frame_pc (frame);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
int sel = (int) (uintptr_t) data;
struct probe *pc_probe;
const struct sym_probe_fns *pc_probe_fns;