/* Agent expression code for remote server.
- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "server.h"
#include "ax.h"
#include "format.h"
+#include "tracepoint.h"
+#include "rsp-low.h"
static void ax_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
#undef DEFOP
};
+#ifndef IN_PROCESS_AGENT
static const unsigned char gdb_agent_op_sizes [gdb_agent_op_last] =
{
0
#include "ax.def"
#undef DEFOP
};
+#endif
/* A wrapper for gdb_agent_op_names that does some bounds-checking. */
of bytes in expression, a comma, and then the bytes. */
struct agent_expr *
-gdb_parse_agent_expr (char **actparm)
+gdb_parse_agent_expr (const char **actparm)
{
- char *act = *actparm;
+ const char *act = *actparm;
ULONGEST xlen;
struct agent_expr *aexpr;
++act; /* skip the X */
act = unpack_varlen_hex (act, &xlen);
++act; /* skip a comma */
- aexpr = xmalloc (sizeof (struct agent_expr));
+ aexpr = XNEW (struct agent_expr);
aexpr->length = xlen;
- aexpr->bytes = xmalloc (xlen);
- convert_ascii_to_int (act, aexpr->bytes, xlen);
+ aexpr->bytes = (unsigned char *) xmalloc (xlen);
+ hex2bin (act, aexpr->bytes, xlen);
*actparm = act + (xlen * 2);
return aexpr;
}
+void
+gdb_free_agent_expr (struct agent_expr *aexpr)
+{
+ if (aexpr != NULL)
+ {
+ free (aexpr->bytes);
+ free (aexpr);
+ }
+}
+
/* Convert the bytes of an agent expression back into hex digits, so
they can be printed or uploaded. This allocates the buffer,
callers should free when they are done with it. */
{
char *rslt;
- rslt = xmalloc (2 * aexpr->length + 1);
- convert_int_to_ascii (aexpr->bytes, rslt, aexpr->length);
+ rslt = (char *) xmalloc (2 * aexpr->length + 1);
+ bin2hex (aexpr->bytes, rslt, aexpr->length);
return rslt;
}
/* Scan an agent expression for any evidence that the given PC is the
target of a jump bytecode in the expression. */
-int
+static int
is_goto_target (struct agent_expr *aexpr, int pc)
{
int i;
/* Record the compiled-code address of the bytecode, for use by
jump instructions. */
- aentry = xmalloc (sizeof (struct bytecode_address));
+ aentry = XNEW (struct bytecode_address);
aentry->pc = pc;
aentry->address = current_insn_ptr;
aentry->goto_pc = -1;
int nargs, ULONGEST *args)
{
const char *f = format;
- struct format_piece *fpieces;
- int i, fp;
- char *current_substring;
+ int i;
+ const char *current_substring;
int nargs_wanted;
ax_debug ("Printf of \"%s\" with %d args", format, nargs);
- fpieces = parse_format_string (&f);
+ format_pieces fpieces (&f);
nargs_wanted = 0;
- for (fp = 0; fpieces[fp].string != NULL; fp++)
- if (fpieces[fp].argclass != literal_piece)
+ for (auto &&piece : fpieces)
+ if (piece.argclass != literal_piece)
++nargs_wanted;
if (nargs != nargs_wanted)
error (_("Wrong number of arguments for specified format-string"));
i = 0;
- for (fp = 0; fpieces[fp].string != NULL; fp++)
+ for (auto &&piece : fpieces)
{
- current_substring = fpieces[fp].string;
+ current_substring = piece.string;
ax_debug ("current substring is '%s', class is %d",
- current_substring, fpieces[fp].argclass);
- switch (fpieces[fp].argclass)
+ current_substring, piece.argclass);
+ switch (piece.argclass)
{
case string_arg:
{
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++)
}
/* Maybe advance to the next argument. */
- if (fpieces[fp].argclass != literal_piece)
+ if (piece.argclass != literal_piece)
++i;
}
- free_format_pieces (fpieces);
fflush (stdout);
}
int regnum = arg;
struct regcache *regcache = ctx->regcache;
- switch (register_size (regnum))
+ switch (register_size (regcache->tdesc, regnum))
{
case 8:
collect_register (regcache, regnum, cnv.u64.bytes);
op);
/* If ever GDB generates any of these, we don't have the
option of ignoring. */
- return 1;
+ return expr_eval_unhandled_opcode;
default:
ax_debug ("Agent expression op 0x%x not recognized", op);