diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/ax-general.c | 14 | ||||
-rw-r--r-- | gdb/ax.h | 6 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/doc/agentexpr.texi | 10 | ||||
-rw-r--r-- | gdb/dwarf2loc.c | 26 | ||||
-rw-r--r-- | gdb/gdbserver/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/gdbserver/tracepoint.c | 22 |
8 files changed, 76 insertions, 23 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 330065b..42c868f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 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> + * Makefile.in (HFILES_NO_SRCDIR): Don't mention ada-operator.inc. 2011-02-18 Jan Kratochvil <jan.kratochvil@redhat.com> diff --git a/gdb/ax-general.c b/gdb/ax-general.c index 71d23f1..8d95855 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,9 @@ struct aop_map aop_map[] = {"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 */ }; @@ -204,6 +204,8 @@ enum agent_op aop_setv = 0x2d, aop_tracev = 0x2e, aop_trace16 = 0x30, + aop_pick = 0x32, + aop_rot = 0x33, 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/ChangeLog b/gdb/doc/ChangeLog index ca8f3bb..58f2814 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2011-02-18 Tom Tromey <tromey@redhat.com> + + * agentexpr.texi (Bytecode Descriptions): Document pick and rot. + 2011-02-14 Michael Snyder <msnyder@vmware.com> * gdb.texinfo (threads): Document argument for "info threads" cmd. diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi index 7b3fe5a..f2d51b7 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} (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 diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 4d31afa..a439f72 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1740,7 +1740,7 @@ dwarf2_compile_expr_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: @@ -1748,31 +1748,11 @@ dwarf2_compile_expr_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/ChangeLog b/gdb/gdbserver/ChangeLog index 55e7ad1..e5caba5 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,11 @@ +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. + 2011-02-15 Jan Kratochvil <jan.kratochvil@redhat.com> * aclocal.m4: Regenerated with aclocal-1.11.1. diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index fb5f522..36a92b2 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 = 0x32, + gdb_agent_op_rot = 0x33, gdb_agent_op_last }; @@ -571,6 +573,9 @@ static const char *gdb_agent_op_names [gdb_agent_op_last] = "tracev", "?undef?", "trace16", + "?undef?", + "pick", + "rot" }; struct agent_expr @@ -4598,6 +4603,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: + { + 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)) |