aboutsummaryrefslogtreecommitdiff
path: root/gdbserver/ax.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gdbserver/ax.cc')
-rw-r--r--gdbserver/ax.cc1591
1 files changed, 791 insertions, 800 deletions
diff --git a/gdbserver/ax.cc b/gdbserver/ax.cc
index 38ebfbb..76f2fa1 100644
--- a/gdbserver/ax.cc
+++ b/gdbserver/ax.cc
@@ -44,40 +44,38 @@ ax_vdebug (const char *fmt, ...)
va_end (ap);
}
-#define ax_debug(fmt, args...) \
- do { \
- if (debug_threads) \
- ax_vdebug ((fmt), ##args); \
- } while (0)
+#define ax_debug(fmt, args...) \
+ do \
+ { \
+ if (debug_threads) \
+ ax_vdebug ((fmt), ##args); \
+ } \
+ while (0)
/* This enum must exactly match what is documented in
gdb/doc/agentexpr.texi, including all the numerical values. */
enum gdb_agent_op
- {
-#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \
- gdb_agent_op_ ## NAME = VALUE,
+{
+#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \
+ gdb_agent_op_##NAME = VALUE,
#include "gdbsupport/ax.def"
#undef DEFOP
- gdb_agent_op_last
- };
+ gdb_agent_op_last
+};
-static const char * const gdb_agent_op_names [gdb_agent_op_last] =
- {
- "?undef?"
-#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) , # NAME
+static const char *const gdb_agent_op_names[gdb_agent_op_last] = { "?undef?"
+#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) , #NAME
#include "gdbsupport/ax.def"
#undef DEFOP
- };
+};
#ifndef IN_PROCESS_AGENT
-static const unsigned char gdb_agent_op_sizes [gdb_agent_op_last] =
- {
- 0
-#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) , SIZE
+static const unsigned char gdb_agent_op_sizes[gdb_agent_op_last] = { 0
+#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) , SIZE
#include "gdbsupport/ax.def"
#undef DEFOP
- };
+};
#endif
/* A wrapper for gdb_agent_op_names that does some bounds-checking. */
@@ -102,9 +100,9 @@ gdb_parse_agent_expr (const char **actparm)
ULONGEST xlen;
struct agent_expr *aexpr;
- ++act; /* skip the X */
+ ++act; /* skip the X */
act = unpack_varlen_hex (act, &xlen);
- ++act; /* skip a comma */
+ ++act; /* skip a comma */
aexpr = XNEW (struct agent_expr);
aexpr->length = xlen;
aexpr->bytes = (unsigned char *) xmalloc (xlen);
@@ -387,11 +385,11 @@ is_goto_target (struct agent_expr *aexpr, int pc)
op = aexpr->bytes[i];
if (op == gdb_agent_op_goto || op == gdb_agent_op_if_goto)
- {
- int target = (aexpr->bytes[i + 1] << 8) + aexpr->bytes[i + 2];
- if (target == pc)
- return 1;
- }
+ {
+ int target = (aexpr->bytes[i + 1] << 8) + aexpr->bytes[i + 2];
+ if (target == pc)
+ return 1;
+ }
}
return 0;
@@ -410,12 +408,13 @@ compile_bytecodes (struct agent_expr *aexpr)
ULONGEST top;
struct bytecode_address *aentry, *aentry2;
-#define UNHANDLED \
- do \
- { \
- ax_debug ("Cannot compile op 0x%x\n", op); \
- return expr_eval_unhandled_opcode; \
- } while (0)
+#define UNHANDLED \
+ do \
+ { \
+ ax_debug ("Cannot compile op 0x%x\n", op); \
+ return expr_eval_unhandled_opcode; \
+ } \
+ while (0)
if (aexpr->length == 0)
{
@@ -446,322 +445,318 @@ compile_bytecodes (struct agent_expr *aexpr)
emit_error = 0;
switch (op)
- {
- case gdb_agent_op_add:
- emit_add ();
- break;
-
- case gdb_agent_op_sub:
- emit_sub ();
- break;
-
- case gdb_agent_op_mul:
- emit_mul ();
- break;
-
- case gdb_agent_op_div_signed:
- UNHANDLED;
- break;
-
- case gdb_agent_op_div_unsigned:
- UNHANDLED;
- break;
-
- case gdb_agent_op_rem_signed:
- UNHANDLED;
- break;
-
- case gdb_agent_op_rem_unsigned:
- UNHANDLED;
- break;
-
- case gdb_agent_op_lsh:
- emit_lsh ();
- break;
-
- case gdb_agent_op_rsh_signed:
- emit_rsh_signed ();
- break;
-
- case gdb_agent_op_rsh_unsigned:
- emit_rsh_unsigned ();
- break;
-
- case gdb_agent_op_trace:
- UNHANDLED;
- break;
-
- case gdb_agent_op_trace_quick:
- UNHANDLED;
- break;
-
- case gdb_agent_op_log_not:
- emit_log_not ();
- break;
-
- case gdb_agent_op_bit_and:
- emit_bit_and ();
- break;
-
- case gdb_agent_op_bit_or:
- emit_bit_or ();
- break;
-
- case gdb_agent_op_bit_xor:
- emit_bit_xor ();
- break;
-
- case gdb_agent_op_bit_not:
- emit_bit_not ();
- break;
-
- case gdb_agent_op_equal:
- next_op = aexpr->bytes[pc];
- if (next_op == gdb_agent_op_if_goto
- && !is_goto_target (aexpr, pc)
- && target_emit_ops ()->emit_eq_goto)
- {
- ax_debug ("Combining equal & if_goto");
- pc += 1;
- aentry->pc = pc;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_eq_goto (&(aentry->from_offset), &(aentry->from_size));
- }
- else if (next_op == gdb_agent_op_log_not
- && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
- && !is_goto_target (aexpr, pc + 1)
- && target_emit_ops ()->emit_ne_goto)
- {
- ax_debug ("Combining equal & log_not & if_goto");
- pc += 2;
- aentry->pc = pc;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_ne_goto (&(aentry->from_offset), &(aentry->from_size));
- }
- else
- emit_equal ();
- break;
-
- case gdb_agent_op_less_signed:
- next_op = aexpr->bytes[pc];
- if (next_op == gdb_agent_op_if_goto
- && !is_goto_target (aexpr, pc))
- {
- ax_debug ("Combining less_signed & if_goto");
- pc += 1;
- aentry->pc = pc;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_lt_goto (&(aentry->from_offset), &(aentry->from_size));
- }
- else if (next_op == gdb_agent_op_log_not
- && !is_goto_target (aexpr, pc)
- && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
- && !is_goto_target (aexpr, pc + 1))
- {
- ax_debug ("Combining less_signed & log_not & if_goto");
- pc += 2;
- aentry->pc = pc;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_ge_goto (&(aentry->from_offset), &(aentry->from_size));
- }
- else
- emit_less_signed ();
- break;
-
- case gdb_agent_op_less_unsigned:
- emit_less_unsigned ();
- break;
-
- case gdb_agent_op_ext:
- arg = aexpr->bytes[pc++];
- if (arg < (sizeof (LONGEST) * 8))
- emit_ext (arg);
- break;
-
- case gdb_agent_op_ref8:
- emit_ref (1);
- break;
-
- case gdb_agent_op_ref16:
- emit_ref (2);
- break;
-
- case gdb_agent_op_ref32:
- emit_ref (4);
- break;
-
- case gdb_agent_op_ref64:
- emit_ref (8);
- break;
-
- case gdb_agent_op_if_goto:
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_if_goto (&(aentry->from_offset), &(aentry->from_size));
- break;
-
- case gdb_agent_op_goto:
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_goto (&(aentry->from_offset), &(aentry->from_size));
- break;
-
- case gdb_agent_op_const8:
- emit_stack_flush ();
- top = aexpr->bytes[pc++];
- emit_const (top);
- break;
-
- case gdb_agent_op_const16:
- emit_stack_flush ();
- top = aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- emit_const (top);
- break;
-
- case gdb_agent_op_const32:
- emit_stack_flush ();
- top = aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- emit_const (top);
- break;
-
- case gdb_agent_op_const64:
- emit_stack_flush ();
- top = aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- emit_const (top);
- break;
-
- case gdb_agent_op_reg:
- emit_stack_flush ();
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- emit_reg (arg);
- break;
-
- case gdb_agent_op_end:
- ax_debug ("At end of expression\n");
-
- /* Assume there is one stack element left, and that it is
+ {
+ case gdb_agent_op_add:
+ emit_add ();
+ break;
+
+ case gdb_agent_op_sub:
+ emit_sub ();
+ break;
+
+ case gdb_agent_op_mul:
+ emit_mul ();
+ break;
+
+ case gdb_agent_op_div_signed:
+ UNHANDLED;
+ break;
+
+ case gdb_agent_op_div_unsigned:
+ UNHANDLED;
+ break;
+
+ case gdb_agent_op_rem_signed:
+ UNHANDLED;
+ break;
+
+ case gdb_agent_op_rem_unsigned:
+ UNHANDLED;
+ break;
+
+ case gdb_agent_op_lsh:
+ emit_lsh ();
+ break;
+
+ case gdb_agent_op_rsh_signed:
+ emit_rsh_signed ();
+ break;
+
+ case gdb_agent_op_rsh_unsigned:
+ emit_rsh_unsigned ();
+ break;
+
+ case gdb_agent_op_trace:
+ UNHANDLED;
+ break;
+
+ case gdb_agent_op_trace_quick:
+ UNHANDLED;
+ break;
+
+ case gdb_agent_op_log_not:
+ emit_log_not ();
+ break;
+
+ case gdb_agent_op_bit_and:
+ emit_bit_and ();
+ break;
+
+ case gdb_agent_op_bit_or:
+ emit_bit_or ();
+ break;
+
+ case gdb_agent_op_bit_xor:
+ emit_bit_xor ();
+ break;
+
+ case gdb_agent_op_bit_not:
+ emit_bit_not ();
+ break;
+
+ case gdb_agent_op_equal:
+ next_op = aexpr->bytes[pc];
+ if (next_op == gdb_agent_op_if_goto && !is_goto_target (aexpr, pc)
+ && target_emit_ops ()->emit_eq_goto)
+ {
+ ax_debug ("Combining equal & if_goto");
+ pc += 1;
+ aentry->pc = pc;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_eq_goto (&(aentry->from_offset), &(aentry->from_size));
+ }
+ else if (next_op == gdb_agent_op_log_not
+ && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
+ && !is_goto_target (aexpr, pc + 1)
+ && target_emit_ops ()->emit_ne_goto)
+ {
+ ax_debug ("Combining equal & log_not & if_goto");
+ pc += 2;
+ aentry->pc = pc;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_ne_goto (&(aentry->from_offset), &(aentry->from_size));
+ }
+ else
+ emit_equal ();
+ break;
+
+ case gdb_agent_op_less_signed:
+ next_op = aexpr->bytes[pc];
+ if (next_op == gdb_agent_op_if_goto && !is_goto_target (aexpr, pc))
+ {
+ ax_debug ("Combining less_signed & if_goto");
+ pc += 1;
+ aentry->pc = pc;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_lt_goto (&(aentry->from_offset), &(aentry->from_size));
+ }
+ else if (next_op == gdb_agent_op_log_not
+ && !is_goto_target (aexpr, pc)
+ && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
+ && !is_goto_target (aexpr, pc + 1))
+ {
+ ax_debug ("Combining less_signed & log_not & if_goto");
+ pc += 2;
+ aentry->pc = pc;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_ge_goto (&(aentry->from_offset), &(aentry->from_size));
+ }
+ else
+ emit_less_signed ();
+ break;
+
+ case gdb_agent_op_less_unsigned:
+ emit_less_unsigned ();
+ break;
+
+ case gdb_agent_op_ext:
+ arg = aexpr->bytes[pc++];
+ if (arg < (sizeof (LONGEST) * 8))
+ emit_ext (arg);
+ break;
+
+ case gdb_agent_op_ref8:
+ emit_ref (1);
+ break;
+
+ case gdb_agent_op_ref16:
+ emit_ref (2);
+ break;
+
+ case gdb_agent_op_ref32:
+ emit_ref (4);
+ break;
+
+ case gdb_agent_op_ref64:
+ emit_ref (8);
+ break;
+
+ case gdb_agent_op_if_goto:
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_if_goto (&(aentry->from_offset), &(aentry->from_size));
+ break;
+
+ case gdb_agent_op_goto:
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_goto (&(aentry->from_offset), &(aentry->from_size));
+ break;
+
+ case gdb_agent_op_const8:
+ emit_stack_flush ();
+ top = aexpr->bytes[pc++];
+ emit_const (top);
+ break;
+
+ case gdb_agent_op_const16:
+ emit_stack_flush ();
+ top = aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ emit_const (top);
+ break;
+
+ case gdb_agent_op_const32:
+ emit_stack_flush ();
+ top = aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ emit_const (top);
+ break;
+
+ case gdb_agent_op_const64:
+ emit_stack_flush ();
+ top = aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ emit_const (top);
+ break;
+
+ case gdb_agent_op_reg:
+ emit_stack_flush ();
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ emit_reg (arg);
+ break;
+
+ case gdb_agent_op_end:
+ ax_debug ("At end of expression\n");
+
+ /* Assume there is one stack element left, and that it is
cached in "top" where emit_epilogue can get to it. */
- emit_stack_adjust (1);
-
- done = 1;
- break;
-
- case gdb_agent_op_dup:
- /* In our design, dup is equivalent to stack flushing. */
- emit_stack_flush ();
- break;
-
- case gdb_agent_op_pop:
- emit_pop ();
- break;
-
- case gdb_agent_op_zero_ext:
- arg = aexpr->bytes[pc++];
- if (arg < (sizeof (LONGEST) * 8))
- emit_zero_ext (arg);
- break;
-
- case gdb_agent_op_swap:
- next_op = aexpr->bytes[pc];
- /* Detect greater-than comparison sequences. */
- if (next_op == gdb_agent_op_less_signed
- && !is_goto_target (aexpr, pc)
- && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
- && !is_goto_target (aexpr, pc + 1))
- {
- ax_debug ("Combining swap & less_signed & if_goto");
- pc += 2;
- aentry->pc = pc;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_gt_goto (&(aentry->from_offset), &(aentry->from_size));
- }
- else if (next_op == gdb_agent_op_less_signed
- && !is_goto_target (aexpr, pc)
- && (aexpr->bytes[pc + 1] == gdb_agent_op_log_not)
- && !is_goto_target (aexpr, pc + 1)
- && (aexpr->bytes[pc + 2] == gdb_agent_op_if_goto)
- && !is_goto_target (aexpr, pc + 2))
- {
- ax_debug ("Combining swap & less_signed & log_not & if_goto");
- pc += 3;
- aentry->pc = pc;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- aentry->goto_pc = arg;
- emit_le_goto (&(aentry->from_offset), &(aentry->from_size));
- }
- else
- emit_swap ();
- break;
-
- case gdb_agent_op_getv:
- emit_stack_flush ();
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- emit_int_call_1 (get_get_tsv_func_addr (),
- arg);
- break;
-
- case gdb_agent_op_setv:
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- emit_void_call_2 (get_set_tsv_func_addr (),
- arg);
- break;
-
- case gdb_agent_op_tracev:
- UNHANDLED;
- break;
-
- /* GDB never (currently) generates any of these ops. */
- case gdb_agent_op_float:
- case gdb_agent_op_ref_float:
- case gdb_agent_op_ref_double:
- case gdb_agent_op_ref_long_double:
- case gdb_agent_op_l_to_d:
- case gdb_agent_op_d_to_l:
- case gdb_agent_op_trace16:
- UNHANDLED;
- break;
-
- default:
- ax_debug ("Agent expression op 0x%x not recognized\n", op);
- /* Don't struggle on, things will just get worse. */
- return expr_eval_unrecognized_opcode;
- }
+ emit_stack_adjust (1);
+
+ done = 1;
+ break;
+
+ case gdb_agent_op_dup:
+ /* In our design, dup is equivalent to stack flushing. */
+ emit_stack_flush ();
+ break;
+
+ case gdb_agent_op_pop:
+ emit_pop ();
+ break;
+
+ case gdb_agent_op_zero_ext:
+ arg = aexpr->bytes[pc++];
+ if (arg < (sizeof (LONGEST) * 8))
+ emit_zero_ext (arg);
+ break;
+
+ case gdb_agent_op_swap:
+ next_op = aexpr->bytes[pc];
+ /* Detect greater-than comparison sequences. */
+ if (next_op == gdb_agent_op_less_signed
+ && !is_goto_target (aexpr, pc)
+ && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
+ && !is_goto_target (aexpr, pc + 1))
+ {
+ ax_debug ("Combining swap & less_signed & if_goto");
+ pc += 2;
+ aentry->pc = pc;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_gt_goto (&(aentry->from_offset), &(aentry->from_size));
+ }
+ else if (next_op == gdb_agent_op_less_signed
+ && !is_goto_target (aexpr, pc)
+ && (aexpr->bytes[pc + 1] == gdb_agent_op_log_not)
+ && !is_goto_target (aexpr, pc + 1)
+ && (aexpr->bytes[pc + 2] == gdb_agent_op_if_goto)
+ && !is_goto_target (aexpr, pc + 2))
+ {
+ ax_debug ("Combining swap & less_signed & log_not & if_goto");
+ pc += 3;
+ aentry->pc = pc;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ aentry->goto_pc = arg;
+ emit_le_goto (&(aentry->from_offset), &(aentry->from_size));
+ }
+ else
+ emit_swap ();
+ break;
+
+ case gdb_agent_op_getv:
+ emit_stack_flush ();
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ emit_int_call_1 (get_get_tsv_func_addr (), arg);
+ break;
+
+ case gdb_agent_op_setv:
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ emit_void_call_2 (get_set_tsv_func_addr (), arg);
+ break;
+
+ case gdb_agent_op_tracev:
+ UNHANDLED;
+ break;
+
+ /* GDB never (currently) generates any of these ops. */
+ case gdb_agent_op_float:
+ case gdb_agent_op_ref_float:
+ case gdb_agent_op_ref_double:
+ case gdb_agent_op_ref_long_double:
+ case gdb_agent_op_l_to_d:
+ case gdb_agent_op_d_to_l:
+ case gdb_agent_op_trace16:
+ UNHANDLED;
+ break;
+
+ default:
+ ax_debug ("Agent expression op 0x%x not recognized\n", op);
+ /* Don't struggle on, things will just get worse. */
+ return expr_eval_unrecognized_opcode;
+ }
/* This catches errors that occur in target-specific code
emission. */
if (emit_error)
- {
- ax_debug ("Error %d while emitting code for %s\n",
- emit_error, gdb_agent_op_name (op));
- return expr_eval_unhandled_opcode;
- }
+ {
+ ax_debug ("Error %d while emitting code for %s\n", emit_error,
+ gdb_agent_op_name (op));
+ return expr_eval_unhandled_opcode;
+ }
ax_debug ("Op %s compiled\n", gdb_agent_op_name (op));
}
@@ -772,32 +767,31 @@ compile_bytecodes (struct agent_expr *aexpr)
int written = 0;
if (aentry->goto_pc < 0)
- continue;
+ continue;
/* Find the location that we are going to, and call back into
target-specific code to write the actual address or
displacement. */
for (aentry2 = bytecode_address_table; aentry2; aentry2 = aentry2->next)
- {
- if (aentry2->pc == aentry->goto_pc)
- {
- ax_debug ("Want to jump from %s to %s\n",
- paddress (aentry->address),
- paddress (aentry2->address));
- write_goto_address (aentry->address + aentry->from_offset,
- aentry2->address, aentry->from_size);
- written = 1;
- break;
- }
- }
+ {
+ if (aentry2->pc == aentry->goto_pc)
+ {
+ ax_debug ("Want to jump from %s to %s\n",
+ paddress (aentry->address),
+ paddress (aentry2->address));
+ write_goto_address (aentry->address + aentry->from_offset,
+ aentry2->address, aentry->from_size);
+ written = 1;
+ break;
+ }
+ }
/* Error out if we didn't find a destination. */
if (!written)
- {
- ax_debug ("Destination of goto %d not found\n",
- aentry->goto_pc);
- return expr_eval_invalid_goto;
- }
+ {
+ ax_debug ("Destination of goto %d not found\n", aentry->goto_pc);
+ return expr_eval_invalid_goto;
+ }
}
return expr_eval_no_error;
@@ -813,8 +807,8 @@ compile_bytecodes (struct agent_expr *aexpr)
in. */
static void
-ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format,
- int nargs, ULONGEST *args)
+ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format, int nargs,
+ ULONGEST *args)
{
const char *f = format;
int i;
@@ -831,86 +825,86 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format,
++nargs_wanted;
if (nargs != nargs_wanted)
- error (_("Wrong number of arguments for specified format-string"));
+ error (_ ("Wrong number of arguments for specified format-string"));
i = 0;
for (auto &&piece : fpieces)
{
current_substring = piece.string;
- ax_debug ("current substring is '%s', class is %d",
- current_substring, piece.argclass);
+ ax_debug ("current substring is '%s', class is %d", current_substring,
+ piece.argclass);
switch (piece.argclass)
- {
- case string_arg:
- {
- gdb_byte *str;
- CORE_ADDR tem;
- int j;
-
- tem = args[i];
- if (tem == 0)
- {
- printf (current_substring, "(null)");
- break;
- }
-
- /* This is a %s argument. Find the length of the string. */
- for (j = 0;; j++)
- {
- gdb_byte c;
-
- read_inferior_memory (tem + j, &c, 1);
- if (c == 0)
- break;
- }
-
- /* Copy the string contents into a string inside GDB. */
- str = (gdb_byte *) alloca (j + 1);
- if (j != 0)
- read_inferior_memory (tem, str, j);
- str[j] = 0;
-
- printf (current_substring, (char *) str);
- }
- break;
-
- case long_long_arg:
-#if defined (PRINTF_HAS_LONG_LONG)
- {
- long long val = args[i];
-
- printf (current_substring, val);
- break;
- }
+ {
+ case string_arg:
+ {
+ gdb_byte *str;
+ CORE_ADDR tem;
+ int j;
+
+ tem = args[i];
+ if (tem == 0)
+ {
+ printf (current_substring, "(null)");
+ break;
+ }
+
+ /* This is a %s argument. Find the length of the string. */
+ for (j = 0;; j++)
+ {
+ gdb_byte c;
+
+ read_inferior_memory (tem + j, &c, 1);
+ if (c == 0)
+ break;
+ }
+
+ /* Copy the string contents into a string inside GDB. */
+ str = (gdb_byte *) alloca (j + 1);
+ if (j != 0)
+ read_inferior_memory (tem, str, j);
+ str[j] = 0;
+
+ printf (current_substring, (char *) str);
+ }
+ break;
+
+ case long_long_arg:
+#if defined(PRINTF_HAS_LONG_LONG)
+ {
+ long long val = args[i];
+
+ printf (current_substring, val);
+ break;
+ }
#else
- error (_("long long not supported in agent printf"));
+ error (_ ("long long not supported in agent printf"));
#endif
- case int_arg:
- {
- int val = args[i];
+ case int_arg:
+ {
+ int val = args[i];
- printf (current_substring, val);
- break;
- }
+ printf (current_substring, val);
+ break;
+ }
- case long_arg:
- {
- long val = args[i];
+ case long_arg:
+ {
+ long val = args[i];
- printf (current_substring, val);
- break;
- }
+ printf (current_substring, val);
+ break;
+ }
- case size_t_arg:
- {
- size_t val = args[i];
+ case size_t_arg:
+ {
+ size_t val = args[i];
- printf (current_substring, val);
- break;
- }
+ printf (current_substring, val);
+ break;
+ }
- case literal_piece:
- /* Print a portion of the format string that has no
+ case literal_piece:
+ /* Print a portion of the format string that has no
directives. Note that this will not include any
ordinary %-specs, but it might include "%%". That is
why we use printf_filtered and not puts_filtered here.
@@ -918,17 +912,17 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format,
have modified GCC to include -Wformat-security by
default, which will warn here if there is no
argument. */
- printf (current_substring, 0);
- break;
+ printf (current_substring, 0);
+ break;
- default:
- error (_("Format directive in '%s' not supported in agent printf"),
- current_substring);
- }
+ default:
+ error (_ ("Format directive in '%s' not supported in agent printf"),
+ current_substring);
+ }
/* Maybe advance to the next argument. */
if (piece.argclass != literal_piece)
- ++i;
+ ++i;
}
fflush (stdout);
@@ -940,8 +934,7 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format,
enum eval_result_type
gdb_eval_agent_expr (struct eval_agent_expr_context *ctx,
- struct agent_expr *aexpr,
- ULONGEST *rslt)
+ struct agent_expr *aexpr, ULONGEST *rslt)
{
int pc = 0;
#define STACK_MAX 100
@@ -996,377 +989,375 @@ gdb_eval_agent_expr (struct eval_agent_expr_context *ctx,
ax_debug ("About to interpret byte 0x%x", op);
switch (op)
- {
- case gdb_agent_op_add:
- top += stack[--sp];
- break;
-
- case gdb_agent_op_sub:
- top = stack[--sp] - top;
- break;
-
- case gdb_agent_op_mul:
- top *= stack[--sp];
- break;
-
- case gdb_agent_op_div_signed:
- if (top == 0)
- {
- ax_debug ("Attempted to divide by zero");
- return expr_eval_divide_by_zero;
- }
- top = ((LONGEST) stack[--sp]) / ((LONGEST) top);
- break;
-
- case gdb_agent_op_div_unsigned:
- if (top == 0)
- {
- ax_debug ("Attempted to divide by zero");
- return expr_eval_divide_by_zero;
- }
- top = stack[--sp] / top;
- break;
-
- case gdb_agent_op_rem_signed:
- if (top == 0)
- {
- ax_debug ("Attempted to divide by zero");
- return expr_eval_divide_by_zero;
- }
- top = ((LONGEST) stack[--sp]) % ((LONGEST) top);
- break;
-
- case gdb_agent_op_rem_unsigned:
- if (top == 0)
- {
- ax_debug ("Attempted to divide by zero");
- return expr_eval_divide_by_zero;
- }
- top = stack[--sp] % top;
- break;
-
- case gdb_agent_op_lsh:
- top = stack[--sp] << top;
- break;
-
- case gdb_agent_op_rsh_signed:
- top = ((LONGEST) stack[--sp]) >> top;
- break;
-
- case gdb_agent_op_rsh_unsigned:
- top = stack[--sp] >> top;
- break;
-
- case gdb_agent_op_trace:
- agent_mem_read (ctx, NULL, (CORE_ADDR) stack[--sp],
- (ULONGEST) top);
- if (--sp >= 0)
- top = stack[sp];
- break;
-
- case gdb_agent_op_trace_quick:
- arg = aexpr->bytes[pc++];
- agent_mem_read (ctx, NULL, (CORE_ADDR) top, (ULONGEST) arg);
- break;
-
- case gdb_agent_op_log_not:
- top = !top;
- break;
-
- case gdb_agent_op_bit_and:
- top &= stack[--sp];
- break;
-
- case gdb_agent_op_bit_or:
- top |= stack[--sp];
- break;
-
- case gdb_agent_op_bit_xor:
- top ^= stack[--sp];
- break;
-
- case gdb_agent_op_bit_not:
- top = ~top;
- break;
-
- case gdb_agent_op_equal:
- top = (stack[--sp] == top);
- break;
-
- case gdb_agent_op_less_signed:
- top = (((LONGEST) stack[--sp]) < ((LONGEST) top));
- break;
-
- case gdb_agent_op_less_unsigned:
- top = (stack[--sp] < top);
- break;
-
- case gdb_agent_op_ext:
- arg = aexpr->bytes[pc++];
- if (arg < (sizeof (LONGEST) * 8))
- {
- LONGEST mask = 1 << (arg - 1);
- top &= ((LONGEST) 1 << arg) - 1;
- top = (top ^ mask) - mask;
- }
- break;
-
- case gdb_agent_op_ref8:
- agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1);
- top = cnv.u8.val;
- break;
-
- case gdb_agent_op_ref16:
- agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2);
- top = cnv.u16.val;
- break;
-
- case gdb_agent_op_ref32:
- agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4);
- top = cnv.u32.val;
- break;
-
- case gdb_agent_op_ref64:
- agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8);
- top = cnv.u64.val;
- break;
-
- case gdb_agent_op_if_goto:
- if (top)
- pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]);
- else
- pc += 2;
- if (--sp >= 0)
- top = stack[sp];
- break;
-
- case gdb_agent_op_goto:
- pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]);
- break;
-
- case gdb_agent_op_const8:
- /* Flush the cached stack top. */
- stack[sp++] = top;
- top = aexpr->bytes[pc++];
- break;
-
- case gdb_agent_op_const16:
- /* Flush the cached stack top. */
- stack[sp++] = top;
- top = aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- break;
-
- case gdb_agent_op_const32:
- /* Flush the cached stack top. */
- stack[sp++] = top;
- top = aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- break;
-
- case gdb_agent_op_const64:
- /* Flush the cached stack top. */
- stack[sp++] = top;
- top = aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- top = (top << 8) + aexpr->bytes[pc++];
- break;
-
- case gdb_agent_op_reg:
- /* Flush the cached stack top. */
- stack[sp++] = top;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- {
- int regnum = arg;
- struct regcache *regcache = ctx->regcache;
-
- switch (register_size (regcache->tdesc, regnum))
- {
- case 8:
- collect_register (regcache, regnum, cnv.u64.bytes);
- top = cnv.u64.val;
- break;
- case 4:
- collect_register (regcache, regnum, cnv.u32.bytes);
- top = cnv.u32.val;
- break;
- case 2:
- collect_register (regcache, regnum, cnv.u16.bytes);
- top = cnv.u16.val;
- break;
- case 1:
- collect_register (regcache, regnum, cnv.u8.bytes);
- top = cnv.u8.val;
- break;
- default:
- internal_error ("unhandled register size");
- }
- }
- break;
-
- case gdb_agent_op_end:
- ax_debug ("At end of expression, sp=%d, stack top cache=0x%s",
- sp, pulongest (top));
- if (rslt)
- {
- if (sp <= 0)
- {
- /* This should be an error */
- ax_debug ("Stack is empty, nothing to return");
- return expr_eval_empty_stack;
- }
- *rslt = top;
- }
- return expr_eval_no_error;
-
- case gdb_agent_op_dup:
- stack[sp++] = top;
- break;
-
- case gdb_agent_op_pop:
- if (--sp >= 0)
- 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))
- top &= ((LONGEST) 1 << arg) - 1;
- break;
-
- case gdb_agent_op_swap:
- /* Interchange top two stack elements, making sure top gets
+ {
+ case gdb_agent_op_add:
+ top += stack[--sp];
+ break;
+
+ case gdb_agent_op_sub:
+ top = stack[--sp] - top;
+ break;
+
+ case gdb_agent_op_mul:
+ top *= stack[--sp];
+ break;
+
+ case gdb_agent_op_div_signed:
+ if (top == 0)
+ {
+ ax_debug ("Attempted to divide by zero");
+ return expr_eval_divide_by_zero;
+ }
+ top = ((LONGEST) stack[--sp]) / ((LONGEST) top);
+ break;
+
+ case gdb_agent_op_div_unsigned:
+ if (top == 0)
+ {
+ ax_debug ("Attempted to divide by zero");
+ return expr_eval_divide_by_zero;
+ }
+ top = stack[--sp] / top;
+ break;
+
+ case gdb_agent_op_rem_signed:
+ if (top == 0)
+ {
+ ax_debug ("Attempted to divide by zero");
+ return expr_eval_divide_by_zero;
+ }
+ top = ((LONGEST) stack[--sp]) % ((LONGEST) top);
+ break;
+
+ case gdb_agent_op_rem_unsigned:
+ if (top == 0)
+ {
+ ax_debug ("Attempted to divide by zero");
+ return expr_eval_divide_by_zero;
+ }
+ top = stack[--sp] % top;
+ break;
+
+ case gdb_agent_op_lsh:
+ top = stack[--sp] << top;
+ break;
+
+ case gdb_agent_op_rsh_signed:
+ top = ((LONGEST) stack[--sp]) >> top;
+ break;
+
+ case gdb_agent_op_rsh_unsigned:
+ top = stack[--sp] >> top;
+ break;
+
+ case gdb_agent_op_trace:
+ agent_mem_read (ctx, NULL, (CORE_ADDR) stack[--sp], (ULONGEST) top);
+ if (--sp >= 0)
+ top = stack[sp];
+ break;
+
+ case gdb_agent_op_trace_quick:
+ arg = aexpr->bytes[pc++];
+ agent_mem_read (ctx, NULL, (CORE_ADDR) top, (ULONGEST) arg);
+ break;
+
+ case gdb_agent_op_log_not:
+ top = !top;
+ break;
+
+ case gdb_agent_op_bit_and:
+ top &= stack[--sp];
+ break;
+
+ case gdb_agent_op_bit_or:
+ top |= stack[--sp];
+ break;
+
+ case gdb_agent_op_bit_xor:
+ top ^= stack[--sp];
+ break;
+
+ case gdb_agent_op_bit_not:
+ top = ~top;
+ break;
+
+ case gdb_agent_op_equal:
+ top = (stack[--sp] == top);
+ break;
+
+ case gdb_agent_op_less_signed:
+ top = (((LONGEST) stack[--sp]) < ((LONGEST) top));
+ break;
+
+ case gdb_agent_op_less_unsigned:
+ top = (stack[--sp] < top);
+ break;
+
+ case gdb_agent_op_ext:
+ arg = aexpr->bytes[pc++];
+ if (arg < (sizeof (LONGEST) * 8))
+ {
+ LONGEST mask = 1 << (arg - 1);
+ top &= ((LONGEST) 1 << arg) - 1;
+ top = (top ^ mask) - mask;
+ }
+ break;
+
+ case gdb_agent_op_ref8:
+ agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1);
+ top = cnv.u8.val;
+ break;
+
+ case gdb_agent_op_ref16:
+ agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2);
+ top = cnv.u16.val;
+ break;
+
+ case gdb_agent_op_ref32:
+ agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4);
+ top = cnv.u32.val;
+ break;
+
+ case gdb_agent_op_ref64:
+ agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8);
+ top = cnv.u64.val;
+ break;
+
+ case gdb_agent_op_if_goto:
+ if (top)
+ pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]);
+ else
+ pc += 2;
+ if (--sp >= 0)
+ top = stack[sp];
+ break;
+
+ case gdb_agent_op_goto:
+ pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]);
+ break;
+
+ case gdb_agent_op_const8:
+ /* Flush the cached stack top. */
+ stack[sp++] = top;
+ top = aexpr->bytes[pc++];
+ break;
+
+ case gdb_agent_op_const16:
+ /* Flush the cached stack top. */
+ stack[sp++] = top;
+ top = aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ break;
+
+ case gdb_agent_op_const32:
+ /* Flush the cached stack top. */
+ stack[sp++] = top;
+ top = aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ break;
+
+ case gdb_agent_op_const64:
+ /* Flush the cached stack top. */
+ stack[sp++] = top;
+ top = aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ top = (top << 8) + aexpr->bytes[pc++];
+ break;
+
+ case gdb_agent_op_reg:
+ /* Flush the cached stack top. */
+ stack[sp++] = top;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ {
+ int regnum = arg;
+ struct regcache *regcache = ctx->regcache;
+
+ switch (register_size (regcache->tdesc, regnum))
+ {
+ case 8:
+ collect_register (regcache, regnum, cnv.u64.bytes);
+ top = cnv.u64.val;
+ break;
+ case 4:
+ collect_register (regcache, regnum, cnv.u32.bytes);
+ top = cnv.u32.val;
+ break;
+ case 2:
+ collect_register (regcache, regnum, cnv.u16.bytes);
+ top = cnv.u16.val;
+ break;
+ case 1:
+ collect_register (regcache, regnum, cnv.u8.bytes);
+ top = cnv.u8.val;
+ break;
+ default:
+ internal_error ("unhandled register size");
+ }
+ }
+ break;
+
+ case gdb_agent_op_end:
+ ax_debug ("At end of expression, sp=%d, stack top cache=0x%s", sp,
+ pulongest (top));
+ if (rslt)
+ {
+ if (sp <= 0)
+ {
+ /* This should be an error */
+ ax_debug ("Stack is empty, nothing to return");
+ return expr_eval_empty_stack;
+ }
+ *rslt = top;
+ }
+ return expr_eval_no_error;
+
+ case gdb_agent_op_dup:
+ stack[sp++] = top;
+ break;
+
+ case gdb_agent_op_pop:
+ if (--sp >= 0)
+ 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))
+ top &= ((LONGEST) 1 << arg) - 1;
+ break;
+
+ case gdb_agent_op_swap:
+ /* Interchange top two stack elements, making sure top gets
copied back onto stack. */
- stack[sp] = top;
- top = stack[sp - 1];
- stack[sp - 1] = stack[sp];
- break;
-
- case gdb_agent_op_getv:
- /* Flush the cached stack top. */
- stack[sp++] = top;
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- top = agent_get_trace_state_variable_value (arg);
- break;
-
- case gdb_agent_op_setv:
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- agent_set_trace_state_variable_value (arg, top);
- /* Note that we leave the value on the stack, for the
+ stack[sp] = top;
+ top = stack[sp - 1];
+ stack[sp - 1] = stack[sp];
+ break;
+
+ case gdb_agent_op_getv:
+ /* Flush the cached stack top. */
+ stack[sp++] = top;
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ top = agent_get_trace_state_variable_value (arg);
+ break;
+
+ case gdb_agent_op_setv:
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ agent_set_trace_state_variable_value (arg, top);
+ /* Note that we leave the value on the stack, for the
benefit of later/enclosing expressions. */
- break;
-
- case gdb_agent_op_tracev:
- arg = aexpr->bytes[pc++];
- arg = (arg << 8) + aexpr->bytes[pc++];
- agent_tsv_read (ctx, arg);
- break;
-
- case gdb_agent_op_tracenz:
- agent_mem_read_string (ctx, NULL, (CORE_ADDR) stack[--sp],
- (ULONGEST) top);
- if (--sp >= 0)
- top = stack[sp];
- break;
-
- case gdb_agent_op_printf:
- {
- int nargs, slen, i;
- CORE_ADDR fn = 0, chan = 0;
- /* Can't have more args than the entire size of the stack. */
- ULONGEST args[STACK_MAX];
- char *format;
-
- nargs = aexpr->bytes[pc++];
- slen = aexpr->bytes[pc++];
- slen = (slen << 8) + aexpr->bytes[pc++];
- format = (char *) &(aexpr->bytes[pc]);
- pc += slen;
- /* Pop function and channel. */
- fn = top;
- if (--sp >= 0)
- top = stack[sp];
- chan = top;
- if (--sp >= 0)
- top = stack[sp];
- /* Pop arguments into a dedicated array. */
- for (i = 0; i < nargs; ++i)
- {
- args[i] = top;
- if (--sp >= 0)
- top = stack[sp];
- }
-
- /* A bad format string means something is very wrong; give
+ break;
+
+ case gdb_agent_op_tracev:
+ arg = aexpr->bytes[pc++];
+ arg = (arg << 8) + aexpr->bytes[pc++];
+ agent_tsv_read (ctx, arg);
+ break;
+
+ case gdb_agent_op_tracenz:
+ agent_mem_read_string (ctx, NULL, (CORE_ADDR) stack[--sp],
+ (ULONGEST) top);
+ if (--sp >= 0)
+ top = stack[sp];
+ break;
+
+ case gdb_agent_op_printf:
+ {
+ int nargs, slen, i;
+ CORE_ADDR fn = 0, chan = 0;
+ /* Can't have more args than the entire size of the stack. */
+ ULONGEST args[STACK_MAX];
+ char *format;
+
+ nargs = aexpr->bytes[pc++];
+ slen = aexpr->bytes[pc++];
+ slen = (slen << 8) + aexpr->bytes[pc++];
+ format = (char *) &(aexpr->bytes[pc]);
+ pc += slen;
+ /* Pop function and channel. */
+ fn = top;
+ if (--sp >= 0)
+ top = stack[sp];
+ chan = top;
+ if (--sp >= 0)
+ top = stack[sp];
+ /* Pop arguments into a dedicated array. */
+ for (i = 0; i < nargs; ++i)
+ {
+ args[i] = top;
+ if (--sp >= 0)
+ top = stack[sp];
+ }
+
+ /* A bad format string means something is very wrong; give
up immediately. */
- if (format[slen - 1] != '\0')
- error (_("Unterminated format string in printf bytecode"));
-
- ax_printf (fn, chan, format, nargs, args);
- }
- break;
-
- /* GDB never (currently) generates any of these ops. */
- case gdb_agent_op_float:
- case gdb_agent_op_ref_float:
- case gdb_agent_op_ref_double:
- case gdb_agent_op_ref_long_double:
- case gdb_agent_op_l_to_d:
- case gdb_agent_op_d_to_l:
- case gdb_agent_op_trace16:
- ax_debug ("Agent expression op 0x%x valid, but not handled",
- op);
- /* If ever GDB generates any of these, we don't have the
+ if (format[slen - 1] != '\0')
+ error (_ ("Unterminated format string in printf bytecode"));
+
+ ax_printf (fn, chan, format, nargs, args);
+ }
+ break;
+
+ /* GDB never (currently) generates any of these ops. */
+ case gdb_agent_op_float:
+ case gdb_agent_op_ref_float:
+ case gdb_agent_op_ref_double:
+ case gdb_agent_op_ref_long_double:
+ case gdb_agent_op_l_to_d:
+ case gdb_agent_op_d_to_l:
+ case gdb_agent_op_trace16:
+ ax_debug ("Agent expression op 0x%x valid, but not handled", op);
+ /* If ever GDB generates any of these, we don't have the
option of ignoring. */
- return expr_eval_unhandled_opcode;
+ return expr_eval_unhandled_opcode;
- default:
- ax_debug ("Agent expression op 0x%x not recognized", op);
- /* Don't struggle on, things will just get worse. */
- return expr_eval_unrecognized_opcode;
- }
+ default:
+ ax_debug ("Agent expression op 0x%x not recognized", op);
+ /* Don't struggle on, things will just get worse. */
+ return expr_eval_unrecognized_opcode;
+ }
/* Check for stack badness. */
if (sp >= (STACK_MAX - 1))
- {
- ax_debug ("Expression stack overflow");
- return expr_eval_stack_overflow;
- }
+ {
+ ax_debug ("Expression stack overflow");
+ return expr_eval_stack_overflow;
+ }
if (sp < 0)
- {
- ax_debug ("Expression stack underflow");
- return expr_eval_stack_underflow;
- }
+ {
+ ax_debug ("Expression stack underflow");
+ return expr_eval_stack_underflow;
+ }
- ax_debug ("Op %s -> sp=%d, top=0x%s",
- gdb_agent_op_name (op), sp, phex_nz (top, 0));
+ ax_debug ("Op %s -> sp=%d, top=0x%s", gdb_agent_op_name (op), sp,
+ phex_nz (top, 0));
}
}