public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap: add UI support for compiling $_probe_arg* to agent expressions
@ 2011-02-17 19:50 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2011-02-17 19:50 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap has been updated
       via  4b5b3ba9b4c57886aefdade01ffc39dead67c761 (commit)
       via  490e707ca344dd0b3b927136fc87f36c8e61f37b (commit)
      from  5aa8ec25412e39d9c99df5a7a274b47403aef824 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 4b5b3ba9b4c57886aefdade01ffc39dead67c761
Author: Tom Tromey <tromey@redhat.com>
Date:   Thu Feb 17 12:49:59 2011 -0700

    add UI support for compiling $_probe_arg* to agent expressions

commit 490e707ca344dd0b3b927136fc87f36c8e61f37b
Author: Tom Tromey <tromey@redhat.com>
Date:   Thu Feb 17 12:35:27 2011 -0700

    fix bug in $_probe_argc; the magic number is 10, not 0

-----------------------------------------------------------------------

Summary of changes:
 gdb/ax-gdb.c       |    5 ++-
 gdb/elfread.c      |    1 +
 gdb/infrun.c       |    9 ++++-
 gdb/stap-probe.c   |   95 +++++++++++++++++++++++++++++++++++++++------------
 gdb/symfile.h      |   13 +++++++
 gdb/thread.c       |    9 ++++-
 gdb/tracepoint.c   |    9 ++++-
 gdb/value.c        |   37 +++++++++++++-------
 gdb/value.h        |   50 ++++++++++++++++++++++++---
 gdb/windows-tdep.c |    9 ++++-
 10 files changed, 190 insertions(+), 47 deletions(-)

First 500 lines of diff:
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 2908431..1d7513f 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2001,7 +2001,8 @@ gen_expr (struct expression *exp, union exp_element **pc,
 
     case OP_INTERNALVAR:
       {
-	const char *name = internalvar_name ((*pc)[1].internalvar);
+	struct internalvar *var = (*pc)[1].internalvar;
+	const char *name = internalvar_name (var);
 	struct trace_state_variable *tsv;
 
 	(*pc) += 3;
@@ -2015,7 +2016,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
 	    value->kind = axs_rvalue;
 	    value->type = builtin_type (exp->gdbarch)->builtin_long_long;
 	  }
-	else
+	else if (! compile_internalvar_to_ax (var, ax, value))
 	  error (_("$%s is not a trace state variable; GDB agent "
 		   "expressions cannot use convenience variables."), name);
       }
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 1b1df1b..674fac5 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1263,6 +1263,7 @@ static const struct sym_probe_fns elf_probe_fns =
   elf_get_probes,		/* sym_get_probes */
   NULL,				/* sym_get_probe_argument_count */
   NULL,				/* sym_evaluate_probe_argument */
+  NULL,				/* sym_compile_to_ax */
   elf_symfile_relocate_probe,	/* sym_relocate_probe */
 };
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 8bf8a57..3911b35 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -6858,6 +6858,13 @@ show_schedule_multiple (struct ui_file *file, int from_tty,
 			    "of all processes is %s.\n"), value);
 }
 
+static const struct internalvar_funcs siginfo_funcs =
+{
+  siginfo_make_value,
+  NULL,
+  NULL
+};
+
 void
 _initialize_infrun (void)
 {
@@ -7130,7 +7137,7 @@ Tells gdb whether to detach the child of a fork."),
      value with a void typed value, and when we get here, gdbarch
      isn't initialized yet.  At this point, we're quite sure there
      isn't another convenience variable of the same name.  */
-  create_internalvar_type_lazy ("_siginfo", siginfo_make_value, NULL, NULL);
+  create_internalvar_type_lazy ("_siginfo", &siginfo_funcs, NULL);
 
   add_setshow_boolean_cmd ("observer", no_class,
 			   &observer_mode_1, _("\
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 3967f04..bef49c1 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -28,6 +28,8 @@
 #include "filenames.h"
 #include "value.h"
 #include "exceptions.h"
+#include "ax.h"
+#include "ax-gdb.h"
 
 #include <ctype.h>
 
@@ -457,7 +459,7 @@ compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
   n_probes
     = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile,
 								pc_probe);
-  if (sel == 0)
+  if (sel == 10)
     return value_from_longest (builtin_type (arch)->builtin_int, n_probes);
 
   gdb_assert (sel >= 0);
@@ -470,8 +472,55 @@ compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
 								  frame, sel);
 }
 
+/* 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 objfile *objfile;
+  const struct stap_probe *pc_probe;
+  int n_probes;
+
+  /* SEL==10 means "_probe_argc".  */
+  gdb_assert (sel >= 0 && sel <= 10);
+
+  pc_probe = find_probe_by_pc (pc, &objfile);
+  if (pc_probe == NULL)
+    error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
+
+  n_probes
+    = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile,
+								pc_probe);
+  if (sel == 10)
+    {
+      value->kind = axs_rvalue;
+      value->type = builtin_type (expr->gdbarch)->builtin_int;
+      ax_const_l (expr, n_probes);
+      return;
+    }
+
+  gdb_assert (sel >= 0);
+  if (sel >= n_probes)
+    error (_("Invalid probe argument %d -- probe has %d arguments available"),
+	   sel, n_probes);
+
+  objfile->sf->sym_probe_fns->sym_compile_to_ax (objfile, pc_probe,
+						 expr, value, sel);
+}
+
 \f
 
+static const struct internalvar_funcs probe_funcs =
+{
+  compute_probe_arg,
+  compile_probe_arg,
+  NULL
+};
+
 void
 _initialize_stap_probe (void)
 {
@@ -483,26 +532,26 @@ PROVIDER matches probe provider names.\n\
 NAME matches the probe names.\n\
 OBJECT match the executable or shared library name."));
 
-  create_internalvar_type_lazy ("_probe_argc", compute_probe_arg,
-				(void *) (uintptr_t) 10, NULL);
-  create_internalvar_type_lazy ("_probe_arg0", compute_probe_arg,
-				(void *) (uintptr_t) 0, NULL);
-  create_internalvar_type_lazy ("_probe_arg1", compute_probe_arg,
-				(void *) (uintptr_t) 1, NULL);
-  create_internalvar_type_lazy ("_probe_arg2", compute_probe_arg,
-				(void *) (uintptr_t) 2, NULL);
-  create_internalvar_type_lazy ("_probe_arg3", compute_probe_arg,
-				(void *) (uintptr_t) 3, NULL);
-  create_internalvar_type_lazy ("_probe_arg4", compute_probe_arg,
-				(void *) (uintptr_t) 4, NULL);
-  create_internalvar_type_lazy ("_probe_arg5", compute_probe_arg,
-				(void *) (uintptr_t) 5, NULL);
-  create_internalvar_type_lazy ("_probe_arg6", compute_probe_arg,
-				(void *) (uintptr_t) 6, NULL);
-  create_internalvar_type_lazy ("_probe_arg7", compute_probe_arg,
-				(void *) (uintptr_t) 7, NULL);
-  create_internalvar_type_lazy ("_probe_arg8", compute_probe_arg,
-				(void *) (uintptr_t) 8, NULL);
-  create_internalvar_type_lazy ("_probe_arg9", compute_probe_arg,
-				(void *) (uintptr_t) 9, NULL);
+  create_internalvar_type_lazy ("_probe_argc", &probe_funcs,
+				(void *) (uintptr_t) 10);
+  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);
 }
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 167b3b4..1d87fd6 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -34,6 +34,8 @@ struct block;
 struct stap_probe;
 struct value;
 struct frame_info;
+struct agent_expr;
+struct axs_value;
 
 /* Comparison function for symbol look ups.  */
 
@@ -328,6 +330,17 @@ struct sym_probe_fns
 						struct frame_info *frame,
 						int n);
 
+  /* Compile the Nth probe argument to an agent expression.  PROBE
+     will have come from a call to this objfile's sym_get_probes
+     method.  N will be between 0 and the number of arguments
+     available to this probe.  EXPR and VALUE are the agent expression
+     that is being updated.  */
+  void (*sym_compile_to_ax) (struct objfile *objfile,
+			     const struct stap_probe *probe,
+			     struct agent_expr *expr,
+			     struct axs_value *value,
+			     int n);
+
   /* Relocate the probe section of OBJFILE.  */
   void (*sym_relocate_probe) (struct objfile *objfile,
 			      struct section_offsets *new_offsets,
diff --git a/gdb/thread.c b/gdb/thread.c
index 8efb2cc..0f1dc16 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1351,6 +1351,13 @@ thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var,
 /* Commands with a prefix of `thread'.  */
 struct cmd_list_element *thread_cmd_list = NULL;
 
+static struct internalvar_funcs thread_funcs =
+{
+  thread_id_make_value,
+  NULL,
+  NULL
+};
+
 void
 _initialize_thread (void)
 {
@@ -1382,5 +1389,5 @@ Show printing of thread events (such as thread start and exit)."), NULL,
          show_print_thread_events,
          &setprintlist, &showprintlist);
 
-  create_internalvar_type_lazy ("_thread", thread_id_make_value, NULL, NULL);
+  create_internalvar_type_lazy ("_thread", &thread_funcs, NULL);
 }
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 4a42f40..fe086c8 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4415,6 +4415,13 @@ sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
     return allocate_value (builtin_type (gdbarch)->builtin_void);
 }
 
+static const struct internalvar_funcs sdata_funcs =
+{
+  sdata_make_value,
+  NULL,
+  NULL
+};
+
 /* module initialization */
 void
 _initialize_tracepoint (void)
@@ -4425,7 +4432,7 @@ _initialize_tracepoint (void)
      value with a void typed value, and when we get here, gdbarch
      isn't initialized yet.  At this point, we're quite sure there
      isn't another convenience variable of the same name.  */
-  create_internalvar_type_lazy ("_sdata", sdata_make_value, NULL, NULL);
+  create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL);
 
   traceframe_number = -1;
   tracepoint_number = -1;
diff --git a/gdb/value.c b/gdb/value.c
index 1b3cfe5..2475b72 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1060,14 +1060,11 @@ struct internalvar
       /* The call-back routine used with INTERNALVAR_MAKE_VALUE.  */
       struct
         {
-	  /* The function to call.  */
-	  internalvar_make_value function;
+	  /* The functions to call.  */
+	  const struct internalvar_funcs *functions;
 
 	  /* The function's user-data.  */
 	  void *data;
-
-	  /* The cleanup function for DATA.  */
-	  make_cleanup_ftype *cleanup;
         } make_value;
 
       /* The internal function used with INTERNALVAR_FUNCTION.  */
@@ -1179,18 +1176,32 @@ create_internalvar (const char *name)
    is destroyed.  It is passed DATA as its only argument.  */
 
 struct internalvar *
-create_internalvar_type_lazy (char *name, internalvar_make_value fun,
-			      void *data, make_cleanup_ftype *cleanup)
+create_internalvar_type_lazy (const char *name,
+			      const struct internalvar_funcs *funcs,
+			      void *data)
 {
   struct internalvar *var = create_internalvar (name);
 
   var->kind = INTERNALVAR_MAKE_VALUE;
-  var->u.make_value.function = fun;
+  var->u.make_value.functions = funcs;
   var->u.make_value.data = data;
-  var->u.make_value.cleanup = cleanup;
   return var;
 }
 
+int
+compile_internalvar_to_ax (struct internalvar *var,
+			   struct agent_expr *expr,
+			   struct axs_value *value)
+{
+  if (var->kind != INTERNALVAR_MAKE_VALUE
+      || var->u.make_value.functions->compile_to_ax == NULL)
+    return 0;
+
+  var->u.make_value.functions->compile_to_ax (var, expr, value,
+					      var->u.make_value.data);
+  return 1;
+}
+
 /* Look up an internal variable with name NAME.  NAME should not
    normally include a dollar sign.
 
@@ -1267,8 +1278,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
       break;
 
     case INTERNALVAR_MAKE_VALUE:
-      val = (*var->u.make_value.function) (gdbarch, var,
-					   var->u.make_value.data);
+      val = (*var->u.make_value.functions->make_value) (gdbarch, var,
+							var->u.make_value.data);
       break;
 
     default:
@@ -1468,8 +1479,8 @@ clear_internalvar (struct internalvar *var)
       break;
 
     case INTERNALVAR_MAKE_VALUE:
-      if (var->u.make_value.cleanup != NULL)
-	var->u.make_value.cleanup (var->u.make_value.data);
+      if (var->u.make_value.functions->destroy != NULL)
+	var->u.make_value.functions->destroy (var->u.make_value.data);
       break;
 
     default:
diff --git a/gdb/value.h b/gdb/value.h
index dabc668..93ca811 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -609,12 +609,52 @@ extern struct internalvar *lookup_only_internalvar (const char *name);
 
 extern struct internalvar *create_internalvar (const char *name);
 
-typedef struct value * (*internalvar_make_value) (struct gdbarch *,
-						  struct internalvar *,
-						  void *);
+/* An internalvar can be dynamically computed by supplying a vector of
+   function pointers to perform various operations.  */
+
+struct internalvar_funcs
+{
+  /* Compute the value of the variable.  The DATA argument passed to
+     the function is the same argument that was passed to
+     `create_internalvar_type_lazy'.  */
+
+  struct value *(*make_value) (struct gdbarch *arch,
+			       struct internalvar *var,
+			       void *data);
+
+  /* Update the agent expression EXPR with bytecode to compute the
+     value.  VALUE is the agent value we are updating.  The DATA
+     argument passed to this function is the same argument that was
+     passed to `create_internalvar_type_lazy'.  If this pointer is
+     NULL, then the internalvar cannot be compiled to an agent
+     expression.  */
+
+  void (*compile_to_ax) (struct internalvar *var,
+			 struct agent_expr *expr,
+			 struct axs_value *value,
+			 void *data);
+
+  /* If non-NULL, this is called to destroy DATA.  The DATA argument
+     passed to this function is the same argument that was passed to
+     `create_internalvar_type_lazy'.  */
+
+  void (*destroy) (void *data);
+};
+
 extern struct internalvar *
-create_internalvar_type_lazy (char *name, internalvar_make_value fun,
-			      void *data, make_cleanup_ftype *cleanup);
+create_internalvar_type_lazy (const char *name,
+			      const struct internalvar_funcs *funcs,
+			      void *data);
+
+/* Compile an internal variable to an agent expression.  VAR is the
+   variable to compile; EXPR and VALUE are the agent expression we are
+   updating.  This will return 0 if there is no known way to compile
+   VAR, and 1 if VAR was successfully compiled.  It may also throw an
+   exception on error.  */
+
+extern int compile_internalvar_to_ax (struct internalvar *var,
+				      struct agent_expr *expr,
+				      struct axs_value *value);
 
 extern struct internalvar *lookup_internalvar (const char *name);
 
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 7d489ee..00fc641 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -420,6 +420,13 @@ init_w32_command_list (void)
     }
 }
 
+static const struct internalvar_funcs tlb_funcs =
+{
+  tlb_make_value,
+  NULL,
+  NULL
+};
+
 void
 _initialize_windows_tdep (void)
 {
@@ -446,5 +453,5 @@ even if their meaning is unknown."),
      value with a void typed value, and when we get here, gdbarch
      isn't initialized yet.  At this point, we're quite sure there
      isn't another convenience variable of the same name.  */
-  create_internalvar_type_lazy ("_tlb", tlb_make_value, NULL, NULL);
+  create_internalvar_type_lazy ("_tlb", &tlb_funcs, NULL);
 }


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-02-17 19:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-17 19:50 [SCM] archer-sergiodj-stap: add UI support for compiling $_probe_arg* to agent expressions tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).