From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12577 invoked by alias); 16 Feb 2011 21:59:16 -0000 Received: (qmail 12566 invoked by uid 22791); 16 Feb 2011 21:59:14 -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; Wed, 16 Feb 2011 21:59:07 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p1GLx6Y2027836 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 16 Feb 2011 16:59:06 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p1GLx5q6021432; Wed, 16 Feb 2011 16:59:06 -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 p1GLx4JU001431; Wed, 16 Feb 2011 16:59:05 -0500 Received: by opsy.redhat.com (Postfix, from userid 500) id A1165378CAD; Wed, 16 Feb 2011 14:59:04 -0700 (MST) From: Tom Tromey To: gdb-patches@sourceware.org Subject: RFC: add pick and roll agent expression operations Date: Wed, 16 Feb 2011 22:01:00 -0000 Message-ID: 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/msg00396.txt.bz2 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 * ax-general.c (aop_map): Add pick and roll. * 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-16 Tom Tromey * agentexpr.texi (Bytecode Descriptions): Document pick and roll. 2011-02-16 Tom Tromey * tracepoint.c (enum gdb_agent_op) : New constants. (gdb_agent_op_names): Add pick and roll. (eval_agent_expr) : 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))