From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4026 invoked by alias); 18 Feb 2011 20:55:25 -0000 Received: (qmail 4014 invoked by uid 22791); 18 Feb 2011 20:55:24 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 18 Feb 2011 20:55:18 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p1IKt9hT023742 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 18 Feb 2011 15:55:09 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p1IKt8kX027045; Fri, 18 Feb 2011 15:55:08 -0500 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p1IKt7iG015435; Fri, 18 Feb 2011 15:55:08 -0500 Received: by opsy.redhat.com (Postfix, from userid 500) id 0517F378BE1; Fri, 18 Feb 2011 13:55:06 -0700 (MST) From: Tom Tromey To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: RFC: add pick and roll agent expression operations References: <201102181840.30554.pedro@codesourcery.com> Date: Fri, 18 Feb 2011 20:58:00 -0000 In-Reply-To: <201102181840.30554.pedro@codesourcery.com> (Pedro Alves's message of "Fri, 18 Feb 2011 18:40:30 +0000") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-02/txt/msg00499.txt.bz2 >>>>> "Pedro" == Pedro Alves 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 * ax-general.c (aop_map): Add pick and rot. * dwarf2loc.c (compile_dwarf_to_ax) : Reimplement. : Implement. * ax.h (enum agent_op) : New constants. (ax_pick): Declare. * ax-general.c (ax_pick): New function. 2011-02-18 Tom Tromey * agentexpr.texi (Bytecode Descriptions): Document pick and rot. 2011-02-18 Tom Tromey * tracepoint.c (enum gdb_agent_op) : New constants. (gdb_agent_op_names): Add pick and roll. (eval_agent_expr) : 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))