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]

RFC: add pick and roll agent expression operations


I'd appreciate comments on this.
It at least needs a documentation review.

While looking into agent expressions today, I decided to fix a few bugs
in DWARF -> AX compilation.  This patch adds two new agent expressions,
pick and roll.

I wanted comments since I was not sure if there is some approved method
for rolling out AX changes.  Do we need some kind of version test in
remote.c or in the AX translators?  If not, should we somehow add this?

I haven't run the test suite for this yet.

Tom

2011-02-16  Tom Tromey  <tromey@redhat.com>

	* ax-general.c (aop_map): Add pick and roll.
	* dwarf2loc.c (compile_dwarf_to_ax) <DW_OP_over>: Reimplement.
	<DW_OP_rot>: Implement.
	* ax.h (enum agent_op) <aop_pick, aop_roll>: New constants.
	(ax_pick): Declare.
	* ax-general.c (ax_pick): New function.

2011-02-16  Tom Tromey  <tromey@redhat.com>

	* agentexpr.texi (Bytecode Descriptions): Document pick and roll.

2011-02-16  Tom Tromey  <tromey@redhat.com>

	* tracepoint.c (enum gdb_agent_op) <gdb_agent_op_pick,
	gdb_agent_op_roll>: New constants.
	(gdb_agent_op_names): Add pick and roll.
	(eval_agent_expr) <gdb_agent_op_pick, gdb_agent_op_roll>: New
	cases.

diff --git a/gdb/ax-general.c b/gdb/ax-general.c
index 71d23f1..06ff958 100644
--- a/gdb/ax-general.c
+++ b/gdb/ax-general.c
@@ -143,6 +143,17 @@ ax_simple (struct agent_expr *x, enum agent_op op)
   x->buf[x->len++] = op;
 }
 
+/* Append a pick operator to EXPR.  DEPTH is the stack item to pick,
+   with 0 being top of stack.  */
+void
+ax_pick (struct agent_expr *x, int depth)
+{
+  if (depth < 0 || depth > 255)
+    error (_("GDB bug: ax-general.c (ax_pick): stack depth out of range"));
+  ax_simple (x, aop_pick);
+  append_const (x, 1, depth);
+}
+
 
 /* Append a sign-extension or zero-extension instruction to EXPR, to
    extend an N-bit value.  */
@@ -376,6 +387,8 @@ struct aop_map aop_map[] =
   {"tracev", 2, 0, 0, 1},	/* 0x2e */
   {0, 0, 0, 0, 0},		/* 0x2f */
   {"trace16", 2, 0, 1, 1},	/* 0x30 */
+  {"pick", 1, 0, 0, 1},		/* 0x31 */
+  {"roll", 0, 0, 3, 3},		/* 0x32 */
 };
 
 
diff --git a/gdb/ax.h b/gdb/ax.h
index cd1088d..e34aa07 100644
--- a/gdb/ax.h
+++ b/gdb/ax.h
@@ -204,6 +204,8 @@ enum agent_op
     aop_setv = 0x2d,
     aop_tracev = 0x2e,
     aop_trace16 = 0x30,
+    aop_pick = 0x31,
+    aop_rot = 0x32,
     aop_last
   };
 
@@ -221,6 +223,10 @@ extern struct cleanup *make_cleanup_free_agent_expr (struct agent_expr *);
 /* Append a simple operator OP to EXPR.  */
 extern void ax_simple (struct agent_expr *EXPR, enum agent_op OP);
 
+/* Append a pick operator to EXPR.  DEPTH is the stack item to pick,
+   with 0 being top of stack.  */
+extern void ax_pick (struct agent_expr *EXPR, int DEPTH);
+
 /* Append the floating-point prefix, for the next bytecode.  */
 #define ax_float(EXPR) (ax_simple ((EXPR), aop_float))
 
diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi
index 7b3fe5a..b33ccaa 100644
--- a/gdb/doc/agentexpr.texi
+++ b/gdb/doc/agentexpr.texi
@@ -391,6 +391,16 @@ Exchange the top two items on the stack.
 @item @code{pop} (0x29): @var{a} =>
 Discard the top value on the stack.
 
+@item @code{pick} (0x31) @var{n}: @var{a} @dots{} @var{b} => @var{a} @dots{} @var{b} @var{a}
+Duplicate an item from the stack and push it on the top of the stack.
+@var{n}, a single byte, indicates the stack item to copy.  If @var{n}
+is zero, this is the same as @code{dup}; if @var{n} is one, it copies
+the item under the top item, etc.  If @var{n} exceeds the number of
+items on the stack, terminate with an error.
+
+@item @code{rot} (0x32): @var{a} @var{b} @var{c} => @var{c} @var{b} @var{a}
+Rotate the top three items on the stack.
+
 @item @code{if_goto} (0x20) @var{offset}: @var{a} @result{}
 Pop an integer off the stack; if it is non-zero, branch to the given
 offset in the bytecode string.  Otherwise, continue to the next
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index f90335d..7ae5513 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1739,7 +1739,7 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  unimplemented (op);
+	  ax_pick (expr, offset);
 	  break;
 	  
 	case DW_OP_swap:
@@ -1747,31 +1747,11 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
 	  break;
 
 	case DW_OP_over:
-	  /* We can't directly support DW_OP_over, but GCC emits it as
-	     part of a sequence to implement signed modulus.  As a
-	     hack, we recognize this sequence.  Note that if GCC ever
-	     generates a branch to the middle of this sequence, then
-	     we will die somehow.  */
-	  if (op_end - op_ptr >= 4
-	      && op_ptr[0] == DW_OP_over
-	      && op_ptr[1] == DW_OP_div
-	      && op_ptr[2] == DW_OP_mul
-	      && op_ptr[3] == DW_OP_minus)
-	    {
-	      /* Sign extend the operands.  */
-	      ax_ext (expr, addr_size_bits);
-	      ax_simple (expr, aop_swap);
-	      ax_ext (expr, addr_size_bits);
-	      ax_simple (expr, aop_swap);
-	      ax_simple (expr, aop_rem_signed);
-	      op_ptr += 4;
-	    }
-	  else
-	    unimplemented (op);
+	  ax_pick (expr, 1);
 	  break;
 
 	case DW_OP_rot:
-	  unimplemented (op);
+	  ax_simple (expr, aop_rot);
 	  break;
 
 	case DW_OP_deref:
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index fb5f522..660cf3c 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -517,6 +517,8 @@ enum gdb_agent_op
     gdb_agent_op_setv = 0x2d,
     gdb_agent_op_tracev = 0x2e,
     gdb_agent_op_trace16 = 0x30,
+    gdb_agent_op_pick = 0x31,
+    gdb_agent_op_rot = 0x32,
     gdb_agent_op_last
   };
 
@@ -571,6 +573,8 @@ static const char *gdb_agent_op_names [gdb_agent_op_last] =
     "tracev",
     "?undef?",
     "trace16",
+    "pick",
+    "rot"
   };
 
 struct agent_expr
@@ -4598,6 +4602,23 @@ eval_agent_expr (struct tracepoint_hit_ctx *ctx,
 	    top = stack[sp];
 	  break;
 
+	case gdb_agent_op_pick:
+	  arg = aexpr->bytes[pc++];
+	  stack[sp] = top;
+	  top = stack[sp - arg];
+	  ++sp;
+	  break;
+
+	case gdb_agent_op_rot:
+	  {
+	    int tem = stack[sp - 1];
+
+	    stack[sp - 1] = stack[sp - 2];
+	    stack[sp - 2] = top;
+	    top = tem;
+	  }
+	  break;
+
 	case gdb_agent_op_zero_ext:
 	  arg = aexpr->bytes[pc++];
 	  if (arg < (sizeof (LONGEST) * 8))


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