Implement TARGET_WAITKIND_NO_RESUMED in the remote protocol
[deliverable/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
index d64af181add67fd138962224a362b8bcbaf3e913..77280f7c11eb84759d50c1bb544a342367a2a8a4 100644 (file)
@@ -1,7 +1,5 @@
 /* Remote utility routines for the remote server for GDB.
-   Copyright (C) 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "server.h"
 #include "terminal.h"
 #include "target.h"
-#include <stdio.h>
-#include <string.h>
+#include "gdbthread.h"
+#include "tdesc.h"
+#include "dll.h"
+#include "rsp-low.h"
+#include <ctype.h>
 #if HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
 #if HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
-#include <sys/time.h>
-#if HAVE_UNISTD_H
+#include "gdb_sys_time.h"
 #include <unistd.h>
-#endif
 #if HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
 #include <sys/stat.h>
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
 
 #if USE_WIN32API
 #include <winsock2.h>
@@ -107,8 +103,10 @@ struct sym_cache
 int remote_debug = 0;
 struct ui_file *gdb_stdlog;
 
-static int remote_desc = INVALID_DESCRIPTOR;
-static int listen_desc = INVALID_DESCRIPTOR;
+static int remote_is_stdio = 0;
+
+static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR;
+static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
 
 /* FIXME headerize? */
 extern int using_threads;
@@ -130,6 +128,14 @@ gdb_connected (void)
   return remote_desc != INVALID_DESCRIPTOR;
 }
 
+/* Return true if the remote connection is over stdio.  */
+
+int
+remote_connection_is_stdio (void)
+{
+  return remote_is_stdio;
+}
+
 static void
 enable_async_notification (int fd)
 {
@@ -151,7 +157,7 @@ handle_accept_event (int err, gdb_client_data client_data)
   socklen_t tmp;
 
   if (debug_threads)
-    fprintf (stderr, "handling possible accept event\n");
+    debug_printf ("handling possible accept event\n");
 
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -170,14 +176,21 @@ handle_accept_event (int err, gdb_client_data client_data)
              (char *) &tmp, sizeof (tmp));
 
 #ifndef USE_WIN32API
-  close (listen_desc);         /* No longer need this */
-
   signal (SIGPIPE, SIG_IGN);   /* If we don't do this, then gdbserver simply
                                   exits when the remote side dies.  */
+#endif
+
+  if (run_once)
+    {
+#ifndef USE_WIN32API
+      close (listen_desc);             /* No longer need this */
 #else
-  closesocket (listen_desc);   /* No longer need this */
+      closesocket (listen_desc);       /* No longer need this */
 #endif
+    }
 
+  /* Even if !RUN_ONCE no longer notice new connections.  Still keep the
+     descriptor open for add_file_handler to wait for a new connection.  */
   delete_file_handler (listen_desc);
 
   /* Convert IP address to string.  */
@@ -200,6 +213,73 @@ handle_accept_event (int err, gdb_client_data client_data)
   return 0;
 }
 
+/* Prepare for a later connection to a remote debugger.
+   NAME is the filename used for communication.  */
+
+void
+remote_prepare (char *name)
+{
+  char *port_str;
+#ifdef USE_WIN32API
+  static int winsock_initialized;
+#endif
+  int port;
+  struct sockaddr_in sockaddr;
+  socklen_t tmp;
+  char *port_end;
+
+  remote_is_stdio = 0;
+  if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+    {
+      /* We need to record fact that we're using stdio sooner than the
+        call to remote_open so start_inferior knows the connection is
+        via stdio.  */
+      remote_is_stdio = 1;
+      transport_is_reliable = 1;
+      return;
+    }
+
+  port_str = strchr (name, ':');
+  if (port_str == NULL)
+    {
+      transport_is_reliable = 0;
+      return;
+    }
+
+  port = strtoul (port_str + 1, &port_end, 10);
+  if (port_str[1] == '\0' || *port_end != '\0')
+    error ("Bad port argument: %s", name);
+
+#ifdef USE_WIN32API
+  if (!winsock_initialized)
+    {
+      WSADATA wsad;
+
+      WSAStartup (MAKEWORD (1, 0), &wsad);
+      winsock_initialized = 1;
+    }
+#endif
+
+  listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (listen_desc == -1)
+    perror_with_name ("Can't open socket");
+
+  /* Allow rapid reuse of this port. */
+  tmp = 1;
+  setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
+             sizeof (tmp));
+
+  sockaddr.sin_family = PF_INET;
+  sockaddr.sin_port = htons (port);
+  sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+  if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
+      || listen (listen_desc, 1))
+    perror_with_name ("Can't bind address");
+
+  transport_is_reliable = 1;
+}
+
 /* Open a connection to a remote debugger.
    NAME is the filename used for communication.  */
 
@@ -209,11 +289,27 @@ remote_open (char *name)
   char *port_str;
 
   port_str = strchr (name, ':');
+#ifdef USE_WIN32API
   if (port_str == NULL)
+    error ("Only <host>:<port> is supported on this platform.");
+#endif
+
+  if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+    {
+      fprintf (stderr, "Remote debugging using stdio\n");
+
+      /* Use stdin as the handle of the connection.
+        We only select on reads, for example.  */
+      remote_desc = fileno (stdin);
+
+      enable_async_notification (remote_desc);
+
+      /* Register the event loop handler.  */
+      add_file_handler (remote_desc, handle_serial_event, NULL);
+    }
+#ifndef USE_WIN32API
+  else if (port_str == NULL)
     {
-#ifdef USE_WIN32API
-      error ("Only <host>:<port> is supported on this platform.");
-#else
       struct stat statbuf;
 
       if (stat (name, &statbuf) == 0
@@ -274,73 +370,30 @@ remote_open (char *name)
 
       fprintf (stderr, "Remote debugging using %s\n", name);
 
-      transport_is_reliable = 0;
-
       enable_async_notification (remote_desc);
 
       /* Register the event loop handler.  */
       add_file_handler (remote_desc, handle_serial_event, NULL);
-#endif /* USE_WIN32API */
     }
+#endif /* USE_WIN32API */
   else
     {
-#ifdef USE_WIN32API
-      static int winsock_initialized;
-#endif
       int port;
+      socklen_t len;
       struct sockaddr_in sockaddr;
-      socklen_t tmp;
-      char *port_end;
-
-      port = strtoul (port_str + 1, &port_end, 10);
-      if (port_str[1] == '\0' || *port_end != '\0')
-       fatal ("Bad port argument: %s", name);
 
-#ifdef USE_WIN32API
-      if (!winsock_initialized)
-       {
-         WSADATA wsad;
-
-         WSAStartup (MAKEWORD (1, 0), &wsad);
-         winsock_initialized = 1;
-       }
-#endif
-
-      listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
-      if (listen_desc == -1)
-       perror_with_name ("Can't open socket");
-
-      /* Allow rapid reuse of this port. */
-      tmp = 1;
-      setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
-                 sizeof (tmp));
-
-      sockaddr.sin_family = PF_INET;
-      sockaddr.sin_port = htons (port);
-      sockaddr.sin_addr.s_addr = INADDR_ANY;
-
-      if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
-         || listen (listen_desc, 1))
-       perror_with_name ("Can't bind address");
-
-      /* If port is zero, a random port will be selected, and the
-        fprintf below needs to know what port was selected.  */
-      if (port == 0)
-       {
-         socklen_t len = sizeof (sockaddr);
-         if (getsockname (listen_desc, (struct sockaddr *) &sockaddr, &len) < 0
-             || len < sizeof (sockaddr))
-           perror_with_name ("Can't determine port");
-         port = ntohs (sockaddr.sin_port);
-       }
+      len = sizeof (sockaddr);
+      if (getsockname (listen_desc,
+                      (struct sockaddr *) &sockaddr, &len) < 0
+         || len < sizeof (sockaddr))
+       perror_with_name ("Can't determine port");
+      port = ntohs (sockaddr.sin_port);
 
       fprintf (stderr, "Listening on port %d\n", port);
       fflush (stderr);
 
       /* Register the event loop handler.  */
       add_file_handler (listen_desc, handle_accept_event, NULL);
-
-      transport_is_reliable = 1;
     }
 }
 
@@ -352,73 +405,18 @@ remote_close (void)
 #ifdef USE_WIN32API
   closesocket (remote_desc);
 #else
-  close (remote_desc);
+  if (! remote_connection_is_stdio ())
+    close (remote_desc);
 #endif
   remote_desc = INVALID_DESCRIPTOR;
 
   reset_readchar ();
 }
 
-/* Convert hex digit A to a number.  */
-
-static int
-fromhex (int a)
-{
-  if (a >= '0' && a <= '9')
-    return a - '0';
-  else if (a >= 'a' && a <= 'f')
-    return a - 'a' + 10;
-  else
-    error ("Reply contains invalid hex digit");
-  return 0;
-}
-
 #endif
 
-static const char hexchars[] = "0123456789abcdef";
-
-static int
-ishex (int ch, int *val)
-{
-  if ((ch >= 'a') && (ch <= 'f'))
-    {
-      *val = ch - 'a' + 10;
-      return 1;
-    }
-  if ((ch >= 'A') && (ch <= 'F'))
-    {
-      *val = ch - 'A' + 10;
-      return 1;
-    }
-  if ((ch >= '0') && (ch <= '9'))
-    {
-      *val = ch - '0';
-      return 1;
-    }
-  return 0;
-}
-
 #ifndef IN_PROCESS_AGENT
 
-int
-unhexify (char *bin, const char *hex, int count)
-{
-  int i;
-
-  for (i = 0; i < count; i++)
-    {
-      if (hex[0] == 0 || hex[1] == 0)
-       {
-         /* Hex string is short, or of uneven length.
-            Return the count that has been converted so far. */
-         return i;
-       }
-      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
-      hex += 2;
-    }
-  return i;
-}
-
 void
 decode_address (CORE_ADDR *addrp, const char *start, int len)
 {
@@ -454,118 +452,8 @@ decode_address_to_semicolon (CORE_ADDR *addrp, const char *start)
 
 #endif
 
-/* Convert number NIB to a hex digit.  */
-
-static int
-tohex (int nib)
-{
-  if (nib < 10)
-    return '0' + nib;
-  else
-    return 'a' + nib - 10;
-}
-
 #ifndef IN_PROCESS_AGENT
 
-int
-hexify (char *hex, const char *bin, int count)
-{
-  int i;
-
-  /* May use a length, or a nul-terminated string as input. */
-  if (count == 0)
-    count = strlen (bin);
-
-  for (i = 0; i < count; i++)
-    {
-      *hex++ = tohex ((*bin >> 4) & 0xf);
-      *hex++ = tohex (*bin++ & 0xf);
-    }
-  *hex = 0;
-  return i;
-}
-
-/* Convert BUFFER, binary data at least LEN bytes long, into escaped
-   binary data in OUT_BUF.  Set *OUT_LEN to the length of the data
-   encoded in OUT_BUF, and return the number of bytes in OUT_BUF
-   (which may be more than *OUT_LEN due to escape characters).  The
-   total number of bytes in the output buffer will be at most
-   OUT_MAXLEN.  */
-
-int
-remote_escape_output (const gdb_byte *buffer, int len,
-                     gdb_byte *out_buf, int *out_len,
-                     int out_maxlen)
-{
-  int input_index, output_index;
-
-  output_index = 0;
-  for (input_index = 0; input_index < len; input_index++)
-    {
-      gdb_byte b = buffer[input_index];
-
-      if (b == '$' || b == '#' || b == '}' || b == '*')
-       {
-         /* These must be escaped.  */
-         if (output_index + 2 > out_maxlen)
-           break;
-         out_buf[output_index++] = '}';
-         out_buf[output_index++] = b ^ 0x20;
-       }
-      else
-       {
-         if (output_index + 1 > out_maxlen)
-           break;
-         out_buf[output_index++] = b;
-       }
-    }
-
-  *out_len = input_index;
-  return output_index;
-}
-
-/* Convert BUFFER, escaped data LEN bytes long, into binary data
-   in OUT_BUF.  Return the number of bytes written to OUT_BUF.
-   Raise an error if the total number of bytes exceeds OUT_MAXLEN.
-
-   This function reverses remote_escape_output.  It allows more
-   escaped characters than that function does, in particular because
-   '*' must be escaped to avoid the run-length encoding processing
-   in reading packets.  */
-
-static int
-remote_unescape_input (const gdb_byte *buffer, int len,
-                      gdb_byte *out_buf, int out_maxlen)
-{
-  int input_index, output_index;
-  int escaped;
-
-  output_index = 0;
-  escaped = 0;
-  for (input_index = 0; input_index < len; input_index++)
-    {
-      gdb_byte b = buffer[input_index];
-
-      if (output_index + 1 > out_maxlen)
-       error ("Received too much data from the target.");
-
-      if (escaped)
-       {
-         out_buf[output_index++] = b ^ 0x20;
-         escaped = 0;
-       }
-      else if (b == '}')
-       escaped = 1;
-      else
-       out_buf[output_index++] = b;
-    }
-
-  if (escaped)
-    error ("Unmatched escape character in target response.");
-
-  return output_index;
-}
-
 /* Look for a sequence of characters which can be run-length encoded.
    If there are any, update *CSUM and *P.  Otherwise, output the
    single character.  Return the number of characters consumed.  */
@@ -612,23 +500,6 @@ try_rle (char *buf, int remaining, unsigned char *csum, char **p)
 
 #endif
 
-char *
-unpack_varlen_hex (char *buff, /* packet to parse */
-                  ULONGEST *result)
-{
-  int nibble;
-  ULONGEST retval = 0;
-
-  while (ishex (*buff, &nibble))
-    {
-      buff++;
-      retval = retval << 4;
-      retval |= nibble & 0x0f;
-    }
-  *result = retval;
-  return buff;
-}
-
 #ifndef IN_PROCESS_AGENT
 
 /* Write a PTID to BUF.  Returns BUF+CHARACTERS_WRITTEN.  */
@@ -660,7 +531,7 @@ hex_or_minus_one (char *buf, char **obuf)
 {
   ULONGEST ret;
 
-  if (strncmp (buf, "-1", 2) == 0)
+  if (startswith (buf, "-1"))
     {
       ret = (ULONGEST) -1;
       buf += 2;
@@ -702,15 +573,42 @@ read_ptid (char *buf, char **obuf)
   /* No multi-process.  Just a tid.  */
   tid = hex_or_minus_one (p, &pp);
 
-  /* Since the stub is not sending a process id, then default to
-     what's in the current inferior.  */
-  pid = ptid_get_pid (((struct inferior_list_entry *) current_inferior)->id);
+  /* Since GDB is not sending a process id (multi-process extensions
+     are off), then there's only one process.  Default to the first in
+     the list.  */
+  pid = pid_of (get_first_process ());
 
   if (obuf)
     *obuf = pp;
   return ptid_build (pid, tid, 0);
 }
 
+/* Write COUNT bytes in BUF to the client.
+   The result is the number of bytes written or -1 if error.
+   This may return less than COUNT.  */
+
+static int
+write_prim (const void *buf, int count)
+{
+  if (remote_connection_is_stdio ())
+    return write (fileno (stdout), buf, count);
+  else
+    return write (remote_desc, buf, count);
+}
+
+/* Read COUNT bytes from the client and store in BUF.
+   The result is the number of bytes read or -1 if error.
+   This may return less than COUNT.  */
+
+static int
+read_prim (void *buf, int count)
+{
+  if (remote_connection_is_stdio ())
+    return read (fileno (stdin), buf, count);
+  else
+    return read (remote_desc, buf, count);
+}
+
 /* Send a packet to the remote machine, with error checking.
    The data of the packet is in BUF, and the length of the
    packet is in CNT.  Returns >= 0 on success, -1 otherwise.  */
@@ -724,7 +622,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
   char *p;
   int cc;
 
-  buf2 = xmalloc (PBUFSIZ);
+  buf2 = (char *) xmalloc (strlen ("$") + cnt + strlen ("#nn") + 1);
 
   /* Copy the packet into buffer BUF2, encapsulating it
      and giving it a checksum.  */
@@ -748,7 +646,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
 
   do
     {
-      if (write (remote_desc, buf2, p - buf2) != p - buf2)
+      if (write_prim (buf2, p - buf2) != p - buf2)
        {
          perror ("putpkt(write)");
          free (buf2);
@@ -790,7 +688,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
        }
 
       /* Check for an input interrupt while we're here.  */
-      if (cc == '\003' && current_inferior != NULL)
+      if (cc == '\003' && current_thread != NULL)
        (*the_target->request_interrupt) ();
     }
   while (cc != '+');
@@ -843,12 +741,20 @@ input_interrupt (int unused)
       int cc;
       char c = 0;
 
-      cc = read (remote_desc, &c, 1);
+      cc = read_prim (&c, 1);
 
-      if (cc != 1 || c != '\003' || current_inferior == NULL)
+      if (cc == 0)
        {
-         fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
-                  cc, c, c);
+         fprintf (stderr, "client connection closed\n");
+         return;
+       }
+      else if (cc != 1 || c != '\003')
+       {
+         fprintf (stderr, "input_interrupt, count = %d c = %d ", cc, c);
+         if (isprint (c))
+           fprintf (stderr, "('%c')\n", c);
+         else
+           fprintf (stderr, "('\\x%02x')\n", c & 0xff);
          return;
        }
 
@@ -971,7 +877,7 @@ readchar (void)
 
   if (readchar_bufcnt == 0)
     {
-      readchar_bufcnt = read (remote_desc, readchar_buf, sizeof (readchar_buf));
+      readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
 
       if (readchar_bufcnt <= 0)
        {
@@ -1083,7 +989,9 @@ getpkt (char *buf)
 
       if (noack_mode)
        {
-         fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s [no-ack-mode, Bad medium?]\n",
+         fprintf (stderr,
+                  "Bad checksum, sentsum=0x%x, csum=0x%x, "
+                  "buf=%s [no-ack-mode, Bad medium?]\n",
                   (c1 << 4) + c2, csum, buf);
          /* Not much we can do, GDB wasn't expecting an ack/nac.  */
          break;
@@ -1091,7 +999,8 @@ getpkt (char *buf)
 
       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
               (c1 << 4) + c2, csum, buf);
-      write (remote_desc, "-", 1);
+      if (write_prim ("-", 1) != 1)
+       return -1;
     }
 
   if (!noack_mode)
@@ -1102,7 +1011,8 @@ getpkt (char *buf)
          fflush (stderr);
        }
 
-      write (remote_desc, "+", 1);
+      if (write_prim ("+", 1) != 1)
+       return -1;
 
       if (remote_debug)
        {
@@ -1142,36 +1052,8 @@ write_enn (char *buf)
 
 #endif
 
-void
-convert_int_to_ascii (const unsigned char *from, char *to, int n)
-{
-  int nib;
-  int ch;
-  while (n--)
-    {
-      ch = *from++;
-      nib = ((ch & 0xf0) >> 4) & 0x0f;
-      *to++ = tohex (nib);
-      nib = ch & 0x0f;
-      *to++ = tohex (nib);
-    }
-  *to++ = 0;
-}
-
 #ifndef IN_PROCESS_AGENT
 
-void
-convert_ascii_to_int (const char *from, unsigned char *to, int n)
-{
-  int nib1, nib2;
-  while (n--)
-    {
-      nib1 = fromhex (*from++);
-      nib2 = fromhex (*from++);
-      *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
-    }
-}
-
 static char *
 outreg (struct regcache *regcache, int regno, char *buf)
 {
@@ -1183,7 +1065,7 @@ outreg (struct regcache *regcache, int regno, char *buf)
   *buf++ = tohex (regno & 0xf);
   *buf++ = ':';
   collect_register_as_string (regcache, regno, buf);
-  buf += 2 * register_size (regno);
+  buf += 2 * register_size (regcache->tdesc, regno);
   *buf++ = ';';
 
   return buf;
@@ -1227,27 +1109,78 @@ prepare_resume_reply (char *buf, ptid_t ptid,
                      struct target_waitstatus *status)
 {
   if (debug_threads)
-    fprintf (stderr, "Writing resume reply for %s:%d\n\n",
-            target_pid_to_str (ptid), status->kind);
+    debug_printf ("Writing resume reply for %s:%d\n",
+                 target_pid_to_str (ptid), status->kind);
 
   switch (status->kind)
     {
     case TARGET_WAITKIND_STOPPED:
+    case TARGET_WAITKIND_FORKED:
+    case TARGET_WAITKIND_VFORKED:
+    case TARGET_WAITKIND_VFORK_DONE:
+    case TARGET_WAITKIND_EXECD:
+    case TARGET_WAITKIND_THREAD_CREATED:
       {
-       struct thread_info *saved_inferior;
+       struct thread_info *saved_thread;
        const char **regp;
        struct regcache *regcache;
 
-       sprintf (buf, "T%02x", status->value.sig);
+       if ((status->kind == TARGET_WAITKIND_FORKED && report_fork_events)
+           || (status->kind == TARGET_WAITKIND_VFORKED && report_vfork_events))
+         {
+           enum gdb_signal signal = GDB_SIGNAL_TRAP;
+           const char *event = (status->kind == TARGET_WAITKIND_FORKED
+                                ? "fork" : "vfork");
+
+           sprintf (buf, "T%02x%s:", signal, event);
+           buf += strlen (buf);
+           buf = write_ptid (buf, status->value.related_pid);
+           strcat (buf, ";");
+         }
+       else if (status->kind == TARGET_WAITKIND_VFORK_DONE && report_vfork_events)
+         {
+           enum gdb_signal signal = GDB_SIGNAL_TRAP;
+
+           sprintf (buf, "T%02xvforkdone:;", signal);
+         }
+       else if (status->kind == TARGET_WAITKIND_EXECD && report_exec_events)
+         {
+           enum gdb_signal signal = GDB_SIGNAL_TRAP;
+           const char *event = "exec";
+           char hexified_pathname[PATH_MAX * 2];
+
+           sprintf (buf, "T%02x%s:", signal, event);
+           buf += strlen (buf);
+
+           /* Encode pathname to hexified format.  */
+           bin2hex ((const gdb_byte *) status->value.execd_pathname,
+                    hexified_pathname,
+                    strlen (status->value.execd_pathname));
+
+           sprintf (buf, "%s;", hexified_pathname);
+           xfree (status->value.execd_pathname);
+           status->value.execd_pathname = NULL;
+           buf += strlen (buf);
+         }
+       else if (status->kind == TARGET_WAITKIND_THREAD_CREATED
+                && report_thread_events)
+         {
+           enum gdb_signal signal = GDB_SIGNAL_TRAP;
+
+           sprintf (buf, "T%02xcreate:;", signal);
+         }
+       else
+         sprintf (buf, "T%02x", status->value.sig);
+
        buf += strlen (buf);
 
-       regp = gdbserver_expedite_regs;
+       saved_thread = current_thread;
 
-       saved_inferior = current_inferior;
+       current_thread = find_thread_ptid (ptid);
 
-       current_inferior = find_thread_ptid (ptid);
+       regp = current_target_desc ()->expedite_regs;
 
-       regcache = get_thread_regcache (current_inferior, 1);
+       regcache = get_thread_regcache (current_thread, 1);
 
        if (the_target->stopped_by_watchpoint != NULL
            && (*the_target->stopped_by_watchpoint) ())
@@ -1268,10 +1201,20 @@ prepare_resume_reply (char *buf, ptid_t ptid,
              *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
            *buf++ = ';';
          }
+       else if (swbreak_feature && target_stopped_by_sw_breakpoint ())
+         {
+           sprintf (buf, "swbreak:;");
+           buf += strlen (buf);
+         }
+       else if (hwbreak_feature && target_stopped_by_hw_breakpoint ())
+         {
+           sprintf (buf, "hwbreak:;");
+           buf += strlen (buf);
+         }
 
        while (*regp)
          {
-           buf = outreg (regcache, find_regno (*regp), buf);
+           buf = outreg (regcache, find_regno (regcache->tdesc, *regp), buf);
            regp ++;
          }
        *buf = '\0';
@@ -1304,8 +1247,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
                strcat (buf, ";");
                buf += strlen (buf);
 
-               if (the_target->core_of_thread)
-                 core = (*the_target->core_of_thread) (ptid);
+               core = target_core_of_thread (ptid);
+
                if (core != -1)
                  {
                    sprintf (buf, "core:");
@@ -1324,7 +1267,7 @@ prepare_resume_reply (char *buf, ptid_t ptid,
            dlls_changed = 0;
          }
 
-       current_inferior = saved_inferior;
+       current_thread = saved_thread;
       }
       break;
     case TARGET_WAITKIND_EXITED:
@@ -1341,6 +1284,14 @@ prepare_resume_reply (char *buf, ptid_t ptid,
       else
        sprintf (buf, "X%02x", status->value.sig);
       break;
+    case TARGET_WAITKIND_THREAD_EXITED:
+      sprintf (buf, "w%x;", status->value.integer);
+      buf += strlen (buf);
+      buf = write_ptid (buf, ptid);
+      break;
+    case TARGET_WAITKIND_NO_RESUMED:
+      sprintf (buf, "N");
+      break;
     default:
       error ("unhandled waitkind");
       break;
@@ -1390,9 +1341,9 @@ decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
     }
 
   if (*to_p == NULL)
-    *to_p = xmalloc (*len_ptr);
+    *to_p = (unsigned char *) xmalloc (*len_ptr);
 
-  convert_ascii_to_int (&from[i++], *to_p, *len_ptr);
+  hex2bin (&from[i++], *to_p, *len_ptr);
 }
 
 int
@@ -1416,7 +1367,7 @@ decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
     }
 
   if (*to_p == NULL)
-    *to_p = xmalloc (*len_ptr);
+    *to_p = (unsigned char *) xmalloc (*len_ptr);
 
   if (remote_unescape_input ((const gdb_byte *) &from[i], packet_len - i,
                             *to_p, *len_ptr) != *len_ptr)
@@ -1426,19 +1377,13 @@ decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
 }
 
 /* Decode a qXfer write request.  */
+
 int
-decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset,
+decode_xfer_write (char *buf, int packet_len, CORE_ADDR *offset,
                   unsigned int *len, unsigned char *data)
 {
   char ch;
-
-  /* Extract and NUL-terminate the annex.  */
-  *annex = buf;
-  while (*buf && *buf != ':')
-    buf++;
-  if (*buf == '\0')
-    return -1;
-  *buf++ = 0;
+  char *b = buf;
 
   /* Extract the offset.  */
   *offset = 0;
@@ -1449,7 +1394,7 @@ decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset,
     }
 
   /* Get encoded data.  */
-  packet_len -= buf - *annex;
+  packet_len -= buf - b;
   *len = remote_unescape_input ((const gdb_byte *) buf, packet_len,
                                data, packet_len);
   return 0;
@@ -1527,7 +1472,8 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
 
   /* Send the request.  */
   strcpy (own_buf, "qSymbol:");
-  hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
+  bin2hex ((const gdb_byte *) name, own_buf + strlen ("qSymbol:"),
+         strlen (name));
   if (putpkt (own_buf) < 0)
     return -1;
 
@@ -1548,9 +1494,9 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
       unsigned int mem_len;
 
       decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
-      mem_buf = xmalloc (mem_len);
+      mem_buf = (unsigned char *) xmalloc (mem_len);
       if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-       convert_int_to_ascii (mem_buf, own_buf, mem_len);
+       bin2hex (mem_buf, own_buf, mem_len);
       else
        write_enn (own_buf);
       free (mem_buf);
@@ -1561,7 +1507,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
        return -1;
     }
 
-  if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
+  if (!startswith (own_buf, "qSymbol:"))
     {
       warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf);
       return -1;
@@ -1579,7 +1525,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
   decode_address (addrp, p, q - p);
 
   /* Save the symbol in our cache.  */
-  sym = xmalloc (sizeof (*sym));
+  sym = XNEW (struct sym_cache);
   sym->name = xstrdup (name);
   sym->addr = *addrp;
   sym->next = proc->symbol_cache;
@@ -1594,7 +1540,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
    where we want the instruction to be copied (and possibly adjusted)
    to.  On output, it points to one past the end of the resulting
    instruction(s).  The effect of executing the instruction at TO
-   shall be the same as if executing it at FROM.  For example, call
+   shall be the same as if executing it at OLDLOC.  For example, call
    instructions that implicitly push the return address on the stack
    should be adjusted to return to the instruction after OLDLOC;
    relative branches, and other PC-relative instructions need the
@@ -1632,9 +1578,9 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
       if (own_buf[0] == 'm')
        {
          decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
-         mem_buf = xmalloc (mem_len);
+         mem_buf = (unsigned char *) xmalloc (mem_len);
          if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-           convert_int_to_ascii (mem_buf, own_buf, mem_len);
+           bin2hex (mem_buf, own_buf, mem_len);
          else
            write_enn (own_buf);
        }
@@ -1670,7 +1616,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
       return -1;
     }
 
-  if (strncmp (own_buf, "qRelocInsn:", strlen ("qRelocInsn:")) != 0)
+  if (!startswith (own_buf, "qRelocInsn:"))
     {
       warning ("Malformed response to qRelocInsn, ignoring: %s\n",
               own_buf);
@@ -1686,177 +1632,14 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
 void
 monitor_output (const char *msg)
 {
-  char *buf = xmalloc (strlen (msg) * 2 + 2);
+  int len = strlen (msg);
+  char *buf = (char *) xmalloc (len * 2 + 2);
 
   buf[0] = 'O';
-  hexify (buf + 1, msg, 0);
+  bin2hex ((const gdb_byte *) msg, buf + 1, len);
 
   putpkt (buf);
   free (buf);
 }
 
-/* Return a malloc allocated string with special characters from TEXT
-   replaced by entity references.  */
-
-char *
-xml_escape_text (const char *text)
-{
-  char *result;
-  int i, special;
-
-  /* Compute the length of the result.  */
-  for (i = 0, special = 0; text[i] != '\0'; i++)
-    switch (text[i])
-      {
-      case '\'':
-      case '\"':
-       special += 5;
-       break;
-      case '&':
-       special += 4;
-       break;
-      case '<':
-      case '>':
-       special += 3;
-       break;
-      default:
-       break;
-      }
-
-  /* Expand the result.  */
-  result = xmalloc (i + special + 1);
-  for (i = 0, special = 0; text[i] != '\0'; i++)
-    switch (text[i])
-      {
-      case '\'':
-       strcpy (result + i + special, "&apos;");
-       special += 5;
-       break;
-      case '\"':
-       strcpy (result + i + special, "&quot;");
-       special += 5;
-       break;
-      case '&':
-       strcpy (result + i + special, "&amp;");
-       special += 4;
-       break;
-      case '<':
-       strcpy (result + i + special, "&lt;");
-       special += 3;
-       break;
-      case '>':
-       strcpy (result + i + special, "&gt;");
-       special += 3;
-       break;
-      default:
-       result[i + special] = text[i];
-       break;
-      }
-  result[i + special] = '\0';
-
-  return result;
-}
-
-void
-buffer_grow (struct buffer *buffer, const char *data, size_t size)
-{
-  char *new_buffer;
-  size_t new_buffer_size;
-
-  if (size == 0)
-    return;
-
-  new_buffer_size = buffer->buffer_size;
-
-  if (new_buffer_size == 0)
-    new_buffer_size = 1;
-
-  while (buffer->used_size + size > new_buffer_size)
-    new_buffer_size *= 2;
-  new_buffer = realloc (buffer->buffer, new_buffer_size);
-  if (!new_buffer)
-    abort ();
-  memcpy (new_buffer + buffer->used_size, data, size);
-  buffer->buffer = new_buffer;
-  buffer->buffer_size = new_buffer_size;
-  buffer->used_size += size;
-}
-
-void
-buffer_free (struct buffer *buffer)
-{
-  if (!buffer)
-    return;
-
-  free (buffer->buffer);
-  buffer->buffer = NULL;
-  buffer->buffer_size = 0;
-  buffer->used_size = 0;
-}
-
-void
-buffer_init (struct buffer *buffer)
-{
-  memset (buffer, 0, sizeof (*buffer));
-}
-
-char*
-buffer_finish (struct buffer *buffer)
-{
-  char *ret = buffer->buffer;
-  buffer->buffer = NULL;
-  buffer->buffer_size = 0;
-  buffer->used_size = 0;
-  return ret;
-}
-
-void
-buffer_xml_printf (struct buffer *buffer, const char *format, ...)
-{
-  va_list ap;
-  const char *f;
-  const char *prev;
-  int percent = 0;
-
-  va_start (ap, format);
-
-  prev = format;
-  for (f = format; *f; f++)
-    {
-      if (percent)
-       {
-        switch (*f)
-          {
-          case 's':
-            {
-              char *p;
-              char *a = va_arg (ap, char *);
-              buffer_grow (buffer, prev, f - prev - 1);
-              p = xml_escape_text (a);
-              buffer_grow_str (buffer, p);
-              free (p);
-              prev = f + 1;
-            }
-            break;
-          case 'd':
-            {
-              int i = va_arg (ap, int);
-              char b[sizeof ("4294967295")];
-
-              buffer_grow (buffer, prev, f - prev - 1);
-              sprintf (b, "%d", i);
-              buffer_grow_str (buffer, b);
-              prev = f + 1;
-            }
-          }
-        percent = 0;
-       }
-      else if (*f == '%')
-       percent = 1;
-    }
-
-  buffer_grow_str (buffer, prev);
-  va_end (ap);
-}
-
 #endif
This page took 0.040239 seconds and 4 git commands to generate.