aboutsummaryrefslogtreecommitdiff
path: root/gdb/ax-gdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/ax-gdb.c')
-rw-r--r--gdb/ax-gdb.c119
1 files changed, 118 insertions, 1 deletions
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 4edf8f2..999b27c 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -1468,6 +1468,12 @@ gen_expr (struct expression *exp, union exp_element **pc,
case BINOP_BITWISE_AND:
case BINOP_BITWISE_IOR:
case BINOP_BITWISE_XOR:
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
(*pc)++;
gen_expr (exp, pc, ax, &value1);
gen_usual_unary (exp, ax, &value1);
@@ -1537,6 +1543,47 @@ gen_expr (struct expression *exp, union exp_element **pc,
aop_bit_xor, aop_bit_xor, 0, "bitwise exclusive-or");
break;
+ case BINOP_EQUAL:
+ gen_binop (ax, value, &value1, &value2,
+ aop_equal, aop_equal, 0, "equal");
+ break;
+
+ case BINOP_NOTEQUAL:
+ gen_binop (ax, value, &value1, &value2,
+ aop_equal, aop_equal, 0, "equal");
+ gen_logical_not (ax, value,
+ language_bool_type (exp->language_defn,
+ exp->gdbarch));
+ break;
+
+ case BINOP_LESS:
+ gen_binop (ax, value, &value1, &value2,
+ aop_less_signed, aop_less_unsigned, 0, "less than");
+ break;
+
+ case BINOP_GTR:
+ ax_simple (ax, aop_swap);
+ gen_binop (ax, value, &value1, &value2,
+ aop_less_signed, aop_less_unsigned, 0, "less than");
+ break;
+
+ case BINOP_LEQ:
+ ax_simple (ax, aop_swap);
+ gen_binop (ax, value, &value1, &value2,
+ aop_less_signed, aop_less_unsigned, 0, "less than");
+ gen_logical_not (ax, value,
+ language_bool_type (exp->language_defn,
+ exp->gdbarch));
+ break;
+
+ case BINOP_GEQ:
+ gen_binop (ax, value, &value1, &value2,
+ aop_less_signed, aop_less_unsigned, 0, "less than");
+ gen_logical_not (ax, value,
+ language_bool_type (exp->language_defn,
+ exp->gdbarch));
+ break;
+
default:
/* We should only list operators in the outer case statement
that we actually handle in the inner case statement. */
@@ -1756,6 +1803,37 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
return ax;
}
+/* Given a GDB expression EXPR, return a bytecode sequence that will
+ evaluate and return a result. The bytecodes will do a direct
+ evaluation, using the current data on the target, rather than
+ recording blocks of memory and registers for later use, as
+ gen_trace_for_expr does. The generated bytecode sequence leaves
+ the result of expression evaluation on the top of the stack. */
+
+struct agent_expr *
+gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
+{
+ struct cleanup *old_chain = 0;
+ struct agent_expr *ax = new_agent_expr (scope);
+ union exp_element *pc;
+ struct axs_value value;
+
+ old_chain = make_cleanup_free_agent_expr (ax);
+
+ pc = expr->elts;
+ trace_kludge = 0;
+ gen_expr (expr, &pc, ax, &value);
+
+ /* Oh, and terminate. */
+ ax_simple (ax, aop_end);
+
+ /* We have successfully built the agent expr, so cancel the cleanup
+ request. If we add more cleanups that we always want done, this
+ will have to get more complicated. */
+ discard_cleanups (old_chain);
+ return ax;
+}
+
static void
agent_command (char *exp, int from_tty)
{
@@ -1786,6 +1864,41 @@ agent_command (char *exp, int from_tty)
do_cleanups (old_chain);
dont_repeat ();
}
+
+/* Parse the given expression, compile it into an agent expression
+ that does direct evaluation, and display the resulting
+ expression. */
+
+static void
+agent_eval_command (char *exp, int from_tty)
+{
+ struct cleanup *old_chain = 0;
+ struct expression *expr;
+ struct agent_expr *agent;
+ struct frame_info *fi = get_current_frame (); /* need current scope */
+
+ /* We don't deal with overlay debugging at the moment. We need to
+ think more carefully about this. If you copy this code into
+ another command, change the error message; the user shouldn't
+ have to know anything about agent expressions. */
+ if (overlay_debugging)
+ error (_("GDB can't do agent expression translation with overlays."));
+
+ if (exp == 0)
+ error_no_arg (_("expression to translate"));
+
+ expr = parse_expression (exp);
+ old_chain = make_cleanup (free_current_contents, &expr);
+ agent = gen_eval_for_expr (get_frame_pc (fi), expr);
+ make_cleanup_free_agent_expr (agent);
+ ax_print (gdb_stdout, agent);
+
+ /* It would be nice to call ax_reqs here to gather some general info
+ about the expression, and then print out the result. */
+
+ do_cleanups (old_chain);
+ dont_repeat ();
+}
/* Initialization code. */
@@ -1795,6 +1908,10 @@ void
_initialize_ax_gdb (void)
{
add_cmd ("agent", class_maintenance, agent_command,
- _("Translate an expression into remote agent bytecode."),
+ _("Translate an expression into remote agent bytecode for tracing."),
+ &maintenancelist);
+
+ add_cmd ("agent-eval", class_maintenance, agent_eval_command,
+ _("Translate an expression into remote agent bytecode for evaluation."),
&maintenancelist);
}