diff options
Diffstat (limited to 'gdb/ax-gdb.c')
-rw-r--r-- | gdb/ax-gdb.c | 119 |
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); } |