* RFC: add pick and roll agent expression operations @ 2011-02-16 22:01 Tom Tromey 2011-02-17 5:33 ` Eli Zaretskii 2011-02-18 18:44 ` Pedro Alves 0 siblings, 2 replies; 5+ messages in thread From: Tom Tromey @ 2011-02-16 22:01 UTC (permalink / raw) To: gdb-patches 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 }; \f @@ -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)) ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFC: add pick and roll agent expression operations 2011-02-16 22:01 RFC: add pick and roll agent expression operations Tom Tromey @ 2011-02-17 5:33 ` Eli Zaretskii 2011-02-18 18:44 ` Pedro Alves 1 sibling, 0 replies; 5+ messages in thread From: Eli Zaretskii @ 2011-02-17 5:33 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches > From: Tom Tromey <tromey@redhat.com> > Date: Wed, 16 Feb 2011 14:59:04 -0700 > > It at least needs a documentation review. The documentation part is okay. Thanks. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFC: add pick and roll agent expression operations 2011-02-16 22:01 RFC: add pick and roll agent expression operations Tom Tromey 2011-02-17 5:33 ` Eli Zaretskii @ 2011-02-18 18:44 ` Pedro Alves 2011-02-18 20:58 ` Tom Tromey 1 sibling, 1 reply; 5+ messages in thread From: Pedro Alves @ 2011-02-18 18:44 UTC (permalink / raw) To: gdb-patches; +Cc: Tom Tromey On Wednesday 16 February 2011 21:59:04, Tom Tromey wrote: > 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 think we can get by without it in this case. Without the patch you can't even compile the agent expressions. After the patch, against an older server/stub, we risk the user only noticing that the expression didn't work until late in the trace cycle. But then again, in a super controlled environment where that matters, you should only use a client/server pair that's been verified to work. Here's an idea for posterity: what if gdbserver made a quick validating pass over the expressions at tracepoint download time, and errored out if it found opcodes it didn't grok? > /* 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 */ Hmm, you used rot everywhere else? Looks like you end up fixing it in the next patch. > --- 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 > }; > > struct agent_expr > @@ -4598,6 +4602,23 @@ eval_agent_expr (struct tracepoint_hit_ctx *ctx, > + case gdb_agent_op_rot: > + { > + int tem = stack[sp - 1]; > + > + stack[sp - 1] = stack[sp - 2]; > + stack[sp - 2] = top; > + top = tem; tem should be ULONGEST. Otherwise looks okay to me. Thanks. -- Pedro Alves ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFC: add pick and roll agent expression operations 2011-02-18 18:44 ` Pedro Alves @ 2011-02-18 20:58 ` Tom Tromey 2011-02-18 21:11 ` Pedro Alves 0 siblings, 1 reply; 5+ messages in thread From: Tom Tromey @ 2011-02-18 20:58 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches >>>>> "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 }; \f @@ -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)) ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFC: add pick and roll agent expression operations 2011-02-18 20:58 ` Tom Tromey @ 2011-02-18 21:11 ` Pedro Alves 0 siblings, 0 replies; 5+ messages in thread From: Pedro Alves @ 2011-02-18 21:11 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb-patches On Friday 18 February 2011 20:55:05, Tom Tromey wrote: > 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. Yeah, it's not a correctness issue: we'll just fallback to bytecode intepreting, and things still work, just not super fast. -- Pedro Alves ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-02-18 21:02 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-02-16 22:01 RFC: add pick and roll agent expression operations Tom Tromey 2011-02-17 5:33 ` Eli Zaretskii 2011-02-18 18:44 ` Pedro Alves 2011-02-18 20:58 ` Tom Tromey 2011-02-18 21:11 ` Pedro Alves
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox