This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] Sanitize access to gdbarch on the probe API (and fix ARM bug)


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]