public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap: Implementing the compilation for agent expressions, and fixing a bug.
@ 2011-03-18  7:30 sergiodj
  0 siblings, 0 replies; only message in thread
From: sergiodj @ 2011-03-18  7:30 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap has been updated
       via  7938adaa88d884b0a0bf81a213ed0d100222214e (commit)
      from  3d0f221b6a17aa114b9e1bf52f62306ceae9b72d (commit)

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

- Log -----------------------------------------------------------------
commit 7938adaa88d884b0a0bf81a213ed0d100222214e
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Fri Mar 18 04:27:40 2011 -0300

    Implementing the compilation for agent expressions, and fixing a bug.
    
    This commit implements the basic features for compiling probe's
    arguments into agent expressions, for tracepoint support.  It still has
    some questionable points, which I intend to fix ASAP.
    
    I have also fixed a bug in the evaluation code, which were causing
    expressions like `(~(2) * 3)' to be evaluated like `~(2 * 3)'.

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

Summary of changes:
 gdb/elfread.c    |   12 ++-
 gdb/stap-probe.c |  288 ++++++++++++++++++++++++++++++++++++++++++++++++------
 gdb/stap-probe.h |   17 +++-
 3 files changed, 284 insertions(+), 33 deletions(-)

First 500 lines of diff:
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 37e19e7..cf41fbf 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1273,6 +1273,16 @@ elf_evaluate_probe_argument (struct objfile *objfile,
 }
 
 static void
+elf_compile_to_ax (struct objfile *objfile,
+		   const struct stap_probe *probe,
+		   struct agent_expr *expr,
+		   struct axs_value *value,
+		   int n)
+{
+  stap_compile_to_ax (objfile, probe, expr, value, n);
+}
+
+static void
 elf_symfile_relocate_probe (struct objfile *objfile,
 			    struct section_offsets *new_offsets,
 			    struct section_offsets *delta)
@@ -1312,7 +1322,7 @@ static const struct sym_probe_fns elf_probe_fns =
   elf_get_probes,		/* sym_get_probes */
   elf_get_probe_argument_count,	/* sym_get_probe_argument_count */
   elf_evaluate_probe_argument,	/* sym_evaluate_probe_argument */
-  NULL,				/* sym_compile_to_ax */
+  elf_compile_to_ax,		/* sym_compile_to_ax */
   elf_symfile_relocate_probe,	/* sym_relocate_probe */
 };
 
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 7613400..eb2fb7f 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -70,6 +70,7 @@ struct stap_args_info
 
 /* Struct that contains all the necessary information to evaluate
    an expression.  */
+
 struct stap_evaluation_info
 {
   /* The constant pointer which holds the expression. This is primarily
@@ -90,21 +91,36 @@ struct stap_evaluation_info
 
   /* The bitness specified for this argument.  */
   enum stap_arg_bitness bitness;
+
+  /* Flag to indicate if we are compiling an agent expression.  */
+  int compiling_p;
+
+  /* If the above flag is true (one), this field will contain the
+     pointer to the agent expression.  */
+  struct agent_expr *aexpr;
+
+  /* The value we are modifying (for agent expression).  */
+  struct axs_value *value;
 };
 
 /* This dummy variable is used when parsing a probe's argument fails.
    In this case, the number of arguments for this probe is zero, so that's
    why this variable is useful.  */
+
 static struct stap_args_info dummy_stap_args_info =
   { 0, NULL, NULL };
 
 /* Evaluation function for probe's argument expressions.  LHS represents
    the left side of the expression, and PREC is the precedence of the
    last operator identified before calling the function.  */
+
 static struct value *
 stap_evaluate_probe_argument_2 (struct stap_evaluation_info *eval_info,
 				struct value *lhs, int prec);
 
+static struct value *
+stap_evaluate_conditionally (struct stap_evaluation_info *eval_info);
+
 static void
 stap_skip_whitespace_cond (char **s, int inside_paren)
 {
@@ -625,6 +641,106 @@ stap_get_opcode (char **s, enum exp_opcode *op)
   return ret;
 }
 
+static void
+stap_opcode_to_ax (struct stap_evaluation_info *eval_info,
+		   enum exp_opcode opcode)
+{
+  struct agent_expr *expr = eval_info->aexpr;
+
+  switch (opcode)
+    {
+    case BINOP_MUL:
+      ax_simple (expr, aop_mul);
+      break;
+
+    case BINOP_DIV:
+      /* FIXME: Should we sign-extend the operands?  */
+      ax_simple (expr, aop_div_signed);
+      break;
+
+    case BINOP_REM:
+      ax_simple (expr, aop_rem_unsigned);
+      break;
+
+    case BINOP_LESS:
+      /* FIXME: Should we sign-extend the operands?  */
+      ax_simple (expr, aop_less_signed);
+      break;
+
+    case BINOP_LEQ:
+      /* A <= B is !(B < A) */
+      ax_simple (expr, aop_swap);
+      ax_simple (expr, aop_less_signed);
+      ax_simple (expr, aop_log_not);
+      break;
+
+    case BINOP_GTR:
+      /* A > B is B < A */
+      ax_simple (expr, aop_swap);
+      ax_simple (expr, aop_less_signed);
+      break;
+
+    case BINOP_GEQ:
+      /* A >= B is !(A < B) */
+      ax_simple (expr, aop_less_signed);
+      ax_simple (expr, aop_log_not);
+      break;
+
+    case BINOP_NOTEQUAL:
+      ax_simple (expr, aop_equal);
+      ax_simple (expr, aop_log_not);
+      break;
+
+    case BINOP_LSH:
+      ax_simple (expr, aop_lsh);
+      break;
+
+    case BINOP_RSH:
+      ax_simple (expr, aop_rsh_unsigned);
+      break;
+
+    case BINOP_BITWISE_IOR:
+      ax_simple (expr, aop_bit_or);
+      break;
+     
+    case BINOP_LOGICAL_OR:
+      /* FIXME: ????? */
+//      ax_simple (expr, aop_
+      break;
+
+    case BINOP_BITWISE_AND:
+      ax_simple (expr, aop_bit_and);
+      break;
+
+    case BINOP_LOGICAL_AND:
+      /* FIXME: ???? */
+      break;
+
+    case BINOP_BITWISE_XOR:
+      ax_simple (expr, aop_bit_xor);
+      break;
+
+    case UNOP_LOGICAL_NOT:
+      ax_simple (expr, aop_log_not);
+      break;
+
+    case BINOP_ADD:
+      ax_simple (expr, aop_add);
+      break;
+
+    case BINOP_SUB:
+      ax_simple (expr, aop_sub);
+      break;
+
+    case BINOP_EQUAL:
+      ax_simple (expr, aop_equal);
+      break;
+
+    default:
+      error (_("Invalid operator."));
+    }
+}
+
 /* Returns 1 if *S is an operator, zero otherwise.  */
 
 static int
@@ -727,11 +843,15 @@ stap_fetch_reg_value (struct stap_evaluation_info *eval_info,
     error (_("Invalid register name `%s' on expression `%s'."),
 	   regname, eval_info->saved_expr);
 
-  ret = value_of_register (regnum, frame);
+  if (eval_info->compiling_p)
+    ax_reg (eval_info->aexpr, regnum);
+  else
+    ret = value_of_register (regnum, frame);
 
   if (indirect_p)
     {
       struct type *t = NULL;
+      enum agent_op aop;
 
       /* If the user has specified that the register must be indirected,
 	 we should know what's the correct type to cast it before making
@@ -742,28 +862,43 @@ stap_fetch_reg_value (struct stap_evaluation_info *eval_info,
       switch (bitness)
 	{
 	case STAP_ARG_BITNESS_UNDEFINED:
-	  t = lookup_pointer_type
-	    (builtin_type (gdbarch)->builtin_unsigned_long);
+	  if (eval_info->compiling_p)
+	    aop = aop_ref32;
+	  else
+	    t = lookup_pointer_type
+	      (builtin_type (gdbarch)->builtin_unsigned_long);
 	  break;
 
 	case STAP_ARG_BITNESS_32BIT_SIGNED:
-	  t = lookup_pointer_type
-	    (builtin_type (gdbarch)->builtin_int32);
+	  if (eval_info->compiling_p)
+	    aop = aop_ref32;
+	  else
+	    t = lookup_pointer_type
+	      (builtin_type (gdbarch)->builtin_int32);
 	  break;
 
 	case STAP_ARG_BITNESS_32BIT_UNSIGNED:
-	  t = lookup_pointer_type
-	    (builtin_type (gdbarch)->builtin_uint32);
+	  if (eval_info->compiling_p)
+	    aop = aop_ref32;
+	  else
+	    t = lookup_pointer_type
+	      (builtin_type (gdbarch)->builtin_uint32);
 	  break;
 
 	case STAP_ARG_BITNESS_64BIT_SIGNED:
-	  t = lookup_pointer_type
-	    (builtin_type (gdbarch)->builtin_int64);
+	  if (eval_info->compiling_p)
+	    aop = aop_ref64;
+	  else
+	    t = lookup_pointer_type
+	      (builtin_type (gdbarch)->builtin_int64);
 	  break;
 
 	case STAP_ARG_BITNESS_64BIT_UNSIGNED:
-	  t = lookup_pointer_type
-	    (builtin_type (gdbarch)->builtin_uint64);
+	  if (eval_info->compiling_p)
+	    aop = aop_ref64;
+	  else
+	    t = lookup_pointer_type
+	      (builtin_type (gdbarch)->builtin_uint64);
 	  break;
 
 	default:
@@ -773,17 +908,31 @@ stap_fetch_reg_value (struct stap_evaluation_info *eval_info,
 	}
 
       if (displacement)
-	ret = value_ptradd (ret, value_as_long (displacement));
+	{
+	  if (eval_info->compiling_p)
+	    {
+	      ax_const_l (eval_info->aexpr, value_as_long (displacement));
+	      /* FIXME: Is this correct?  */
+	      ax_simple (eval_info->aexpr, aop_add);
+	    }
+	  else
+	    ret = value_ptradd (ret, value_as_long (displacement));
+	}
 
-      ret = value_cast (t, ret);
-      ret = value_ind (ret);
+      if (eval_info->compiling_p)
+	ax_simple (eval_info->aexpr, aop);
+      else
+	{
+	  ret = value_cast (t, ret);
+	  ret = value_ind (ret);
+	}
     }
 
   /* Updating the expression buffer pointer, because we have made
      some modifications to it before.  */
   eval_info->exp_buf = s;
 
-  return ret;
+  return eval_info->compiling_p ? (struct value *) 1 : ret;
 }
 
 /* This function tries to evaluate a single operand of the expression.
@@ -800,7 +949,7 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
   struct gdbarch *gdbarch = eval_info->gdbarch;
   struct frame_info *frame = eval_info->frame;
   enum stap_arg_bitness bitness = eval_info->bitness;
-  struct value *res = NULL;
+  struct value *res;
 
   switch (*eval_info->exp_buf)
     {
@@ -836,14 +985,27 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
 		 to evaluate the right side of the expression (i.e., the
 		 parenthesis), and then apply the specified operation
 		 (either `-' or `~') to it.  */
-	      tmp_res = stap_evaluate_probe_argument_2 (eval_info,
-							/*lhs=*/NULL,
-							/*prec=*/0);
+	      tmp_res = stap_evaluate_conditionally (eval_info);
 
 	      if (c == '-')
-		res = value_neg (tmp_res);
+		{
+		  if (eval_info->compiling_p)
+		    {
+		      /* We have to add `-1' to the stack, and multiply
+			 the two values.  */
+		      ax_const_l (eval_info->aexpr, -1);
+		      ax_simple (eval_info->aexpr, aop_mul);
+		    }
+		  else
+		    res = value_neg (tmp_res);
+		}
 	      else
-		res = value_complement (tmp_res);
+		{
+		  if (eval_info->compiling_p)
+		    ax_simple (eval_info->aexpr, aop_bit_not);
+		  else
+		    res = value_complement (tmp_res);
+		}
 	    }
 	  else if (isdigit (*eval_info->exp_buf))
 	    {
@@ -884,16 +1046,30 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
 	      number = strtol (eval_info->exp_buf,
 			       &eval_info->exp_buf, 0);
 
-	      res
-		= value_from_longest (builtin_type (gdbarch)->builtin_int,
-				      number);
+	      if (!eval_info->compiling_p)
+		res
+		  = value_from_longest (builtin_type (gdbarch)->builtin_int,
+					number);
+
+	      if (eval_info->compiling_p)
+		ax_const_l (eval_info->aexpr, number);
 
 	      eval_info->exp_buf = skip_spaces (eval_info->exp_buf);
 
 	      if (c == '-')
-		res = value_neg (res);
+		{
+		  if (eval_info->compiling_p)
+		    ax_simple (eval_info->aexpr, aop_log_not);
+		  else
+		    res = value_neg (res);
+		}
 	      else
-		res = value_complement (res);
+		{
+		  if (eval_info->compiling_p)
+		    ax_simple (eval_info->aexpr, aop_bit_not);
+		  else
+		    res = value_complement (res);
+		}
 	    }
 	  else
 	    error (_("Invalid operand to unary operator `%c' on "
@@ -932,8 +1108,11 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
 
 	number = strtol (eval_info->exp_buf, &eval_info->exp_buf, 0);
 
-	res = value_from_longest (builtin_type (gdbarch)->builtin_int,
-				  number);
+	if (eval_info->compiling_p)
+	  ax_const_l (eval_info->aexpr, number);
+	else
+	  res = value_from_longest (builtin_type (gdbarch)->builtin_int,
+				    number);
 
 	eval_info->exp_buf = skip_spaces (eval_info->exp_buf);
       }
@@ -953,7 +1132,7 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
       }
     }
 
-  return res;
+  return eval_info->compiling_p ? (struct value *) 1 : res;
 }
 
 /* This function is responsible for checking the necessary type of evaluation
@@ -1006,6 +1185,7 @@ stap_evaluate_probe_argument_2 (struct stap_evaluation_info *eval_info,
 				struct value *lhs, int prec)
 {
   struct value *rhs = NULL;
+  int compiling_p = eval_info->compiling_p;
 
   /* This is an operator-precedence parser and evaluator.
 
@@ -1086,7 +1266,10 @@ stap_evaluate_probe_argument_2 (struct stap_evaluation_info *eval_info,
 
       /* Now, "join" both left and right sides into one left-side, using
 	 the specified operator.  */
-      lhs = value_binop (lhs, rhs, opcode);
+      if (compiling_p)
+	stap_opcode_to_ax (eval_info, opcode);
+      else
+	lhs = value_binop (lhs, rhs, opcode);
     }
 
   return lhs;
@@ -1103,7 +1286,6 @@ stap_evaluate_probe_argument_1 (struct objfile *objfile,
 				int n)
 {
   struct stap_evaluation_info eval_info;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   char *s = (char *) probe->parsed_args->arg[n].arg_str;
   struct value *res, *vs[4];
 #if TEST /*TESTING*/
@@ -1120,6 +1302,9 @@ stap_evaluate_probe_argument_1 (struct objfile *objfile,
   eval_info.gdbarch = get_objfile_arch (objfile);
   eval_info.frame = frame;
   eval_info.bitness = probe->parsed_args->arg[n].bitness;
+  /* We are not compiling to an agent expression.  */
+  eval_info.compiling_p = 0;
+  eval_info.aexpr = NULL;
 
   res = stap_evaluate_probe_argument_2 (&eval_info,
 					/*lhs=*/NULL, /*prec=*/0);
@@ -1158,6 +1343,47 @@ stap_evaluate_probe_argument (struct objfile *objfile,
   return stap_evaluate_probe_argument_1 (objfile, probe, frame, n);
 }
 
+static void
+stap_compile_to_ax_1 (struct objfile *objfile,
+		      const struct stap_probe *probe,
+		      struct agent_expr *expr,
+		      struct axs_value *value,
+		      int n)
+{
+  struct stap_evaluation_info eval_info;
+  char *s = (char *) probe->parsed_args->arg[n].arg_str;
+
+  /* Filling necessary information for evaluation function.  */
+  eval_info.saved_expr = s;
+  eval_info.exp_buf = s;
+  eval_info.gdbarch = expr->gdbarch;
+  eval_info.frame = NULL;
+  eval_info.bitness = probe->parsed_args->arg[n].bitness;
+  /* We are compiling to an agent expression.  */
+  eval_info.compiling_p = 1;
+  eval_info.aexpr = expr;
+
+  stap_evaluate_probe_argument_2 (&eval_info,
+				  /*lhs=*/NULL, /*prec=*/0);
+}
+
+void
+stap_compile_to_ax (struct objfile *objfile,
+		    const struct stap_probe *probe,
+		    struct agent_expr *expr,
+		    struct axs_value *value,
+		    int n)
+{
+  if (!probe->parsed_args)
+    stap_parse_probe_arguments ((struct stap_probe *) probe);
+
+  if (!probe->parsed_args->arg
+      || n >= probe->parsed_args->n_args)
+    return;
+
+  stap_compile_to_ax_1 (objfile, probe, expr, value, n);
+}
+
 /* See documentation in stap-probe.h.  */
 
 struct value *
diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h
index f6e67c2..3a7941f 100644
--- a/gdb/stap-probe.h
+++ b/gdb/stap-probe.h
@@ -21,6 +21,7 @@
 #define STAP_PROBE_H 1
 
 struct stap_args_info;
+struct axs_value;
 
 struct stap_probe
 {
@@ -70,25 +71,39 @@ extern const struct stap_probe *find_probe_by_pc (CORE_ADDR pc,
 
 /* Given PROBE, this function will parse its arguments and fill the
    `struct stap_args_info' with proper information about them.  */
+
 extern void stap_parse_probe_arguments (struct stap_probe *probe);
 
 /* Given PROBE, returns the number of arguments present in that probe's


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


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

only message in thread, other threads:[~2011-03-18  7:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-18  7:30 [SCM] archer-sergiodj-stap: Implementing the compilation for agent expressions, and fixing a bug sergiodj

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).