gdb: Support printf 'z' size modifier
[binutils-gdb.git] / gdb / gdbserver / ax.c
index 94035e490e212269943bcb5c74eae5dfbd448633..21fde5e6926843a0f0ed0499cc5c352556bdc543 100644 (file)
@@ -1,5 +1,5 @@
 /* Agent expression code for remote server.
-   Copyright (C) 2009-2013 Free Software Foundation, Inc.
+   Copyright (C) 2009-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,7 +18,9 @@
 
 #include "server.h"
 #include "ax.h"
-#include "format.h"
+#include "gdbsupport/format.h"
+#include "tracepoint.h"
+#include "gdbsupport/rsp-low.h"
 
 static void ax_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
@@ -34,7 +36,11 @@ ax_vdebug (const char *fmt, ...)
 
   va_start (ap, fmt);
   vsprintf (buf, fmt, ap);
+#ifdef IN_PROCESS_AGENT
   fprintf (stderr, PROG "/ax: %s\n", buf);
+#else
+  debug_printf (PROG "/ax: %s\n", buf);
+#endif
   va_end (ap);
 }
 
@@ -54,7 +60,7 @@ enum gdb_agent_op
   {
 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE)  \
     gdb_agent_op_ ## NAME = VALUE,
-#include "ax.def"
+#include "gdbsupport/ax.def"
 #undef DEFOP
     gdb_agent_op_last
   };
@@ -63,17 +69,19 @@ static const char *gdb_agent_op_names [gdb_agent_op_last] =
   {
     "?undef?"
 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE)  , # NAME
-#include "ax.def"
+#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
-#include "ax.def"
+#include "gdbsupport/ax.def"
 #undef DEFOP
   };
+#endif
 
 /* A wrapper for gdb_agent_op_names that does some bounds-checking.  */
 
@@ -91,23 +99,33 @@ gdb_agent_op_name (int op)
    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.  */
@@ -117,8 +135,8 @@ gdb_unparse_agent_expr (struct agent_expr *aexpr)
 {
   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;
 }
 
@@ -361,7 +379,7 @@ emit_le_goto (int *offset_p, int *size_p)
 /* 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;
@@ -418,7 +436,7 @@ compile_bytecodes (struct agent_expr *aexpr)
 
       /* 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;
@@ -798,34 +816,33 @@ compile_bytecodes (struct agent_expr *aexpr)
    in.  */
 
 static void
-ax_printf (CORE_ADDR fn, CORE_ADDR chan, char *format,
+ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format,
           int nargs, ULONGEST *args)
 {
-  char *f = format;
-  struct format_piece *fpieces;
-  int i, fp;
-  char *current_substring;
+  const char *f = format;
+  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:
          {
@@ -834,6 +851,11 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, char *format,
            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++)
@@ -882,6 +904,14 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, char *format,
            break;
          }
 
+       case size_t_arg:
+         {
+           size_t val = args[i];
+
+           printf (current_substring, val);
+           break;
+         }
+
        case literal_piece:
          /* Print a portion of the format string that has no
             directives.  Note that this will not include any
@@ -900,11 +930,11 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, char *format,
        }
 
       /* Maybe advance to the next argument.  */
-      if (fpieces[fp].argclass != literal_piece)
+      if (piece.argclass != literal_piece)
        ++i;
     }
 
-  free_format_pieces (fpieces);
+  fflush (stdout);
 }
 
 /* The agent expression evaluator, as specified by the GDB docs. It
@@ -912,8 +942,7 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, char *format,
    otherwise.  */
 
 enum eval_result_type
-gdb_eval_agent_expr (struct regcache *regcache,
-                    struct traceframe *tframe,
+gdb_eval_agent_expr (struct eval_agent_expr_context *ctx,
                     struct agent_expr *aexpr,
                     ULONGEST *rslt)
 {
@@ -1032,15 +1061,15 @@ gdb_eval_agent_expr (struct regcache *regcache,
          break;
 
        case gdb_agent_op_trace:
-         agent_mem_read (tframe,
-                         NULL, (CORE_ADDR) stack[--sp], (ULONGEST) top);
+         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 (tframe, NULL, (CORE_ADDR) top, (ULONGEST) arg);
+         agent_mem_read (ctx, NULL, (CORE_ADDR) top, (ULONGEST) arg);
          break;
 
        case gdb_agent_op_log_not:
@@ -1086,22 +1115,22 @@ gdb_eval_agent_expr (struct regcache *regcache,
          break;
 
        case gdb_agent_op_ref8:
-         agent_mem_read (tframe, cnv.u8.bytes, (CORE_ADDR) top, 1);
+         agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1);
          top = cnv.u8.val;
          break;
 
        case gdb_agent_op_ref16:
-         agent_mem_read (tframe, cnv.u16.bytes, (CORE_ADDR) top, 2);
+         agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2);
          top = cnv.u16.val;
          break;
 
        case gdb_agent_op_ref32:
-         agent_mem_read (tframe, cnv.u32.bytes, (CORE_ADDR) top, 4);
+         agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4);
          top = cnv.u32.val;
          break;
 
        case gdb_agent_op_ref64:
-         agent_mem_read (tframe, cnv.u64.bytes, (CORE_ADDR) top, 8);
+         agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8);
          top = cnv.u64.val;
          break;
 
@@ -1160,8 +1189,9 @@ gdb_eval_agent_expr (struct regcache *regcache,
          arg = (arg << 8) + aexpr->bytes[pc++];
          {
            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);
@@ -1260,11 +1290,11 @@ gdb_eval_agent_expr (struct regcache *regcache,
        case gdb_agent_op_tracev:
          arg = aexpr->bytes[pc++];
          arg = (arg << 8) + aexpr->bytes[pc++];
-         agent_tsv_read (tframe, arg);
+         agent_tsv_read (ctx, arg);
          break;
 
        case gdb_agent_op_tracenz:
-         agent_mem_read_string (tframe, NULL, (CORE_ADDR) stack[--sp],
+         agent_mem_read_string (ctx, NULL, (CORE_ADDR) stack[--sp],
                                 (ULONGEST) top);
          if (--sp >= 0)
            top = stack[sp];
@@ -1319,7 +1349,7 @@ gdb_eval_agent_expr (struct regcache *regcache,
                    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);