gdb: Support printf 'z' size modifier
[binutils-gdb.git] / gdb / gdbserver / ax.c
index 87b935959156a90002ac4f35fb9a956a32b5964a..21fde5e6926843a0f0ed0499cc5c352556bdc543 100644 (file)
@@ -1,5 +1,5 @@
 /* Agent expression code for remote server.
-   Copyright (C) 2009-2017 Free Software Foundation, Inc.
+   Copyright (C) 2009-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,9 +18,9 @@
 
 #include "server.h"
 #include "ax.h"
-#include "format.h"
+#include "gdbsupport/format.h"
 #include "tracepoint.h"
-#include "rsp-low.h"
+#include "gdbsupport/rsp-low.h"
 
 static void ax_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
@@ -36,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);
 }
 
@@ -56,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
   };
@@ -65,7 +69,7 @@ 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
   };
 
@@ -74,7 +78,7 @@ 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
@@ -95,9 +99,9 @@ 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;
 
@@ -816,30 +820,29 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format,
           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:
          {
@@ -848,6 +851,11 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const 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++)
@@ -896,6 +904,14 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const 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
@@ -914,11 +930,10 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, const 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);
 }