From c7f96d2b95d916a17453df2df3bff1b382420bc8 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 18 Feb 2011 20:55:45 +0000 Subject: [PATCH] gdb * 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. doc * agentexpr.texi (Bytecode Descriptions): Document pick and rot. gdbserver * tracepoint.c (enum gdb_agent_op) : New constants. (gdb_agent_op_names): Add pick and roll. (eval_agent_expr) : New cases. --- gdb/ChangeLog | 9 +++++++++ gdb/ax-general.c | 14 ++++++++++++++ gdb/ax.h | 6 ++++++ gdb/doc/ChangeLog | 4 ++++ gdb/doc/agentexpr.texi | 10 ++++++++++ gdb/dwarf2loc.c | 26 +++----------------------- gdb/gdbserver/ChangeLog | 8 ++++++++ gdb/gdbserver/tracepoint.c | 22 ++++++++++++++++++++++ 8 files changed, 76 insertions(+), 23 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 330065be27..42c868f322 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +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 * Makefile.in (HFILES_NO_SRCDIR): Don't mention ada-operator.inc. diff --git a/gdb/ax-general.c b/gdb/ax-general.c index 71d23f1a53..8d95855dcf 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 */ }; diff --git a/gdb/ax.h b/gdb/ax.h index a5d722b556..18b19c91c6 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 = 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 ca8f3bb725..58f2814a0d 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2011-02-18 Tom Tromey + + * agentexpr.texi (Bytecode Descriptions): Document pick and rot. + 2011-02-14 Michael Snyder * gdb.texinfo (threads): Document argument for "info threads" cmd. diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi index 7b3fe5aeee..f2d51b7405 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 4d31afa33c..a439f72747 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 55e7ad1ae1..e5caba5a61 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,11 @@ +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. + 2011-02-15 Jan Kratochvil * aclocal.m4: Regenerated with aclocal-1.11.1. diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index fb5f522ec6..36a92b21b5 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))