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]

Re: RFC: add pick and roll agent expression operations


>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:

Pedro> Here's an idea for posterity: what if gdbserver made
Pedro> a quick validating pass over the expressions at tracepoint
Pedro> download time, and errored out if it found opcodes it didn't
Pedro> grok?

That seems like a good idea.

>> +  {"roll", 0, 0, 3, 3},		/* 0x32 */

Pedro> Hmm, you used rot everywhere else?  Looks like
Pedro> you end up fixing it in the next patch.

Yeah, fixed.  Also, perplexingly, I used "roll" in the ChangeLogs.

Pedro> tem should be ULONGEST.

Fixed.


Also, I did not update the tracepoint JIT.  I did look and notice that
it is already incomplete, and that the one use I know of for DW_OP_over
in GCC's output won't be handled anyway, since it involves division.

Pedro> Otherwise looks okay to me.  Thanks.

Thanks, here is what I am checking in.
I updated the opcode numbers to avoid clashing with the printf patch.

I ran the gdb.trace tests against this locally.

Tom

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

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

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

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

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

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

Index: ax-general.c
===================================================================
RCS file: /cvs/src/src/gdb/ax-general.c,v
retrieving revision 1.23
diff -u -r1.23 ax-general.c
--- ax-general.c	5 Jan 2011 22:22:47 -0000	1.23
+++ ax-general.c	18 Feb 2011 20:51:07 -0000
@@ -143,6 +143,17 @@
   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,9 @@
   {"tracev", 2, 0, 0, 1},	/* 0x2e */
   {0, 0, 0, 0, 0},		/* 0x2f */
   {"trace16", 2, 0, 1, 1},	/* 0x30 */
+  {0, 0, 0, 0, 0},		/* 0x31 */
+  {"pick", 1, 0, 0, 1},		/* 0x32 */
+  {"rot", 0, 0, 3, 3},		/* 0x33 */
 };
 
 
Index: ax.h
===================================================================
RCS file: /cvs/src/src/gdb/ax.h,v
retrieving revision 1.15
diff -u -r1.15 ax.h
--- ax.h	16 Feb 2011 21:02:29 -0000	1.15
+++ ax.h	18 Feb 2011 20:51:07 -0000
@@ -204,6 +204,8 @@
     aop_setv = 0x2d,
     aop_tracev = 0x2e,
     aop_trace16 = 0x30,
+    aop_pick = 0x32,
+    aop_rot = 0x33,
     aop_last
   };
 
@@ -221,6 +223,10 @@
 /* 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))
 
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.107
diff -u -r1.107 dwarf2loc.c
--- dwarf2loc.c	17 Feb 2011 16:20:44 -0000	1.107
+++ dwarf2loc.c	18 Feb 2011 20:51:07 -0000
@@ -1740,7 +1740,7 @@
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  unimplemented (op);
+	  ax_pick (expr, offset);
 	  break;
 	  
 	case DW_OP_swap:
@@ -1748,31 +1748,11 @@
 	  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:
Index: doc/agentexpr.texi
===================================================================
RCS file: /cvs/src/src/gdb/doc/agentexpr.texi,v
retrieving revision 1.12
diff -u -r1.12 agentexpr.texi
--- doc/agentexpr.texi	5 Jan 2011 05:09:52 -0000	1.12
+++ doc/agentexpr.texi	18 Feb 2011 20:51:08 -0000
@@ -391,6 +391,16 @@
 @item @code{pop} (0x29): @var{a} =>
 Discard the top value on the stack.
 
+@item @code{pick} (0x32) @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} (0x33): @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
Index: gdbserver/tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/tracepoint.c,v
retrieving revision 1.17
diff -u -r1.17 tracepoint.c
--- gdbserver/tracepoint.c	14 Feb 2011 11:13:12 -0000	1.17
+++ gdbserver/tracepoint.c	18 Feb 2011 20:51:13 -0000
@@ -517,6 +517,8 @@
     gdb_agent_op_setv = 0x2d,
     gdb_agent_op_tracev = 0x2e,
     gdb_agent_op_trace16 = 0x30,
+    gdb_agent_op_pick = 0x32,
+    gdb_agent_op_rot = 0x33,
     gdb_agent_op_last
   };
 
@@ -571,6 +573,9 @@
     "tracev",
     "?undef?",
     "trace16",
+    "?undef?",
+    "pick",
+    "rot"
   };
 
 struct agent_expr
@@ -4598,6 +4603,23 @@
 	    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:
+	  {
+	    ULONGEST 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]