/* Remote utility routines for the remote server for GDB.
   Copyright (C) 1986-2026 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#if HAVE_TERMIOS_H
#include <termios.h>
#endif
#include "target.h"
#include "gdbthread.h"
#include "tdesc.h"
#include "debug.h"
#include "dll.h"
#include "gdbsupport/common-gdbthread.h"
#include "gdbsupport/rsp-low.h"
#include "gdbsupport/scope-exit.h"
#include "gdbsupport/netstuff.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/gdb-sigmask.h"
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "gdbsupport/gdb_sys_time.h"
#include <unistd.h>
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <sys/stat.h>

#if USE_WIN32API
#include <ws2tcpip.h>
#endif

#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif

#ifndef IN_PROCESS_AGENT

/* Extra value for readchar_callback.  */
enum {
  /* The callback is currently not scheduled.  */
  NOT_SCHEDULED = -1
};

/* Status of the readchar callback.
   Either NOT_SCHEDULED or the callback id.  */
static int readchar_callback = NOT_SCHEDULED;

static int readchar (void);
static void reset_readchar (void);
static void reschedule (void);

/* A cache entry for a successfully looked-up symbol.  */
struct sym_cache
{
  char *name;
  CORE_ADDR addr;
  struct sym_cache *next;
};

static int remote_is_stdio = 0;

static int remote_desc = -1;
static int listen_desc = -1;

#ifdef USE_WIN32API
/* gnulib wraps these as macros, undo them.  */
# undef read
# undef write

# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
#endif

int
gdb_connected (void)
{
  return remote_desc != -1;
}

/* 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)
{
#if defined(F_SETFL) && defined (FASYNC)
  int save_fcntl_flags;

  save_fcntl_flags = fcntl (fd, F_GETFL, 0);
  fcntl (fd, F_SETFL, save_fcntl_flags | FASYNC);
#if defined (F_SETOWN)
  fcntl (fd, F_SETOWN, getpid ());
#endif
#endif
}

static void
handle_accept_event (int err, gdb_client_data client_data)
{
  struct sockaddr_storage sockaddr;
  socklen_t len = sizeof (sockaddr);

  threads_debug_printf ("handling possible accept event");

  remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &len);
  if (remote_desc == -1)
    perror_with_name ("Accept failed");

  /* Enable TCP keep alive process. */
  socklen_t tmp = 1;
  setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
	      (char *) &tmp, sizeof (tmp));

  /* Tell TCP not to delay small packets.  This greatly speeds up
     interactive response. */
  tmp = 1;
  setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
	      (char *) &tmp, sizeof (tmp));

#ifndef USE_WIN32API
  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 */
#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.  */
  char orig_host[GDB_NI_MAX_ADDR], orig_port[GDB_NI_MAX_PORT];

  int r = getnameinfo ((struct sockaddr *) &sockaddr, len,
		       orig_host, sizeof (orig_host),
		       orig_port, sizeof (orig_port),
		       NI_NUMERICHOST | NI_NUMERICSERV);

  if (r != 0)
    fprintf (stderr, _("Could not obtain remote address: %s\n"),
	     gai_strerror (r));
  else
    fprintf (stderr, _("Remote debugging from host %s, port %s\n"),
	     orig_host, orig_port);

  enable_async_notification (remote_desc);

  /* Register the event loop handler.  */
  add_file_handler (remote_desc, handle_serial_event, NULL, "remote-net");

  /* We have a new GDB connection now.  If we were disconnected
     tracing, there's a window where the target could report a stop
     event to the event loop, and since we have a connection now, we'd
     try to send vStopped notifications to GDB.  But, don't do that
     until GDB as selected all-stop/non-stop, and has queried the
     threads' status ('?').  */
  target_async (0);
}

/* Prepare for a later connection to a remote debugger.
   NAME is the filename used for communication.  */

void
remote_prepare (const char *name)
{
  client_state &cs = get_client_state ();
#ifdef USE_WIN32API
  static int winsock_initialized;
#endif
  socklen_t tmp;

  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;
      cs.transport_is_reliable = 1;
      return;
    }

  struct addrinfo hint;
  struct addrinfo *ainfo;

  memset (&hint, 0, sizeof (hint));
  /* Assume no prefix will be passed, therefore we should use
     AF_UNSPEC.  */
  hint.ai_family = AF_UNSPEC;
  hint.ai_socktype = SOCK_STREAM;
  hint.ai_protocol = IPPROTO_TCP;

  parsed_connection_spec parsed
    = parse_connection_spec_without_prefix (name, &hint);

  if (parsed.port_str.empty ())
    {
      cs.transport_is_reliable = 0;
      return;
    }

#ifdef USE_WIN32API
  if (!winsock_initialized)
    {
      WSADATA wsad;

      WSAStartup (MAKEWORD (1, 0), &wsad);
      winsock_initialized = 1;
    }
#endif

  int r = getaddrinfo (parsed.host_str.c_str (), parsed.port_str.c_str (),
		       &hint, &ainfo);

  if (r != 0)
    error (_("%s: cannot resolve name: %s"), name, gai_strerror (r));

  scoped_free_addrinfo freeaddrinfo (ainfo);

  struct addrinfo *iter;

  for (iter = ainfo; iter != NULL; iter = iter->ai_next)
    {
      listen_desc = gdb_socket_cloexec (iter->ai_family, iter->ai_socktype,
					iter->ai_protocol);

      if (listen_desc >= 0)
	break;
    }

  if (iter == NULL)
    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));

  switch (iter->ai_family)
    {
    case AF_INET:
      ((struct sockaddr_in *) iter->ai_addr)->sin_addr.s_addr = INADDR_ANY;
      break;
    case AF_INET6:
      ((struct sockaddr_in6 *) iter->ai_addr)->sin6_addr = in6addr_any;
      break;
    default:
      internal_error (_("Invalid 'ai_family' %d\n"), iter->ai_family);
    }

  if (bind (listen_desc, iter->ai_addr, iter->ai_addrlen) != 0)
    perror_with_name ("Can't bind address");

  if (listen (listen_desc, 1) != 0)
    perror_with_name ("Can't listen on socket");

  cs.transport_is_reliable = 1;
}

/* Open a connection to a remote debugger.
   NAME is the filename used for communication.  */

void
remote_open (const char *name)
{
  const 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, "remote-stdio");
    }
#ifndef USE_WIN32API
  else if (port_str == NULL)
    {
      struct stat statbuf;

      if (stat (name, &statbuf) == 0
	  && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)))
	remote_desc = open (name, O_RDWR);
      else
	{
	  errno = EINVAL;
	  remote_desc = -1;
	}

      if (remote_desc < 0)
	perror_with_name ("Could not open remote device");

#if HAVE_TERMIOS_H
      {
	struct termios termios;
	tcgetattr (remote_desc, &termios);

	termios.c_iflag = 0;
	termios.c_oflag = 0;
	termios.c_lflag = 0;
	termios.c_cflag &= ~(CSIZE | PARENB);
	termios.c_cflag |= CLOCAL | CS8;
	termios.c_cc[VMIN] = 1;
	termios.c_cc[VTIME] = 0;

	tcsetattr (remote_desc, TCSANOW, &termios);
      }
#endif

      fprintf (stderr, "Remote debugging using %s\n", name);

      enable_async_notification (remote_desc);

      /* Register the event loop handler.  */
      add_file_handler (remote_desc, handle_serial_event, NULL,
			"remote-device");
    }
#endif /* USE_WIN32API */
  else
    {
      char listen_port[GDB_NI_MAX_PORT];
      struct sockaddr_storage sockaddr;
      socklen_t len = sizeof (sockaddr);

      if (getsockname (listen_desc, (struct sockaddr *) &sockaddr, &len) < 0)
	perror_with_name ("Can't determine port");

      int r = getnameinfo ((struct sockaddr *) &sockaddr, len,
			   NULL, 0,
			   listen_port, sizeof (listen_port),
			   NI_NUMERICSERV);

      if (r != 0)
	fprintf (stderr, _("Can't obtain port where we are listening: %s"),
		 gai_strerror (r));
      else
	fprintf (stderr, _("Listening on port %s\n"), listen_port);

      fflush (stderr);

      /* Register the event loop handler.  */
      add_file_handler (listen_desc, handle_accept_event, NULL,
			"remote-listen");
    }
}

void
remote_close (void)
{
  delete_file_handler (remote_desc);

  disable_async_io ();

#ifdef USE_WIN32API
  closesocket (remote_desc);
#else
  if (! remote_connection_is_stdio ())
    close (remote_desc);
#endif
  remote_desc = -1;

  reset_readchar ();
}

#endif

#ifndef IN_PROCESS_AGENT

void
decode_address (CORE_ADDR *addrp, const char *start, int len)
{
  CORE_ADDR addr;
  char ch;
  int i;

  addr = 0;
  for (i = 0; i < len; i++)
    {
      ch = start[i];
      addr = addr << 4;
      addr = addr | (fromhex (ch) & 0x0f);
    }
  *addrp = addr;
}

const char *
decode_address_to_semicolon (CORE_ADDR *addrp, const char *start)
{
  const char *end;

  end = start;
  while (*end != '\0' && *end != ';')
    end++;

  decode_address (addrp, start, end - start);

  if (*end == ';')
    end++;
  return end;
}

#endif

#ifndef IN_PROCESS_AGENT

/* 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.  */

static int
try_rle (char *buf, int remaining, unsigned char *csum, char **p)
{
  int n;

  /* Always output the character.  */
  *csum += buf[0];
  *(*p)++ = buf[0];

  /* Don't go past '~'.  */
  if (remaining > 97)
    remaining = 97;

  for (n = 1; n < remaining; n++)
    if (buf[n] != buf[0])
      break;

  /* N is the index of the first character not the same as buf[0].
     buf[0] is counted twice, so by decrementing N, we get the number
     of characters the RLE sequence will replace.  */
  n--;

  if (n < 3)
    return 1;

  /* Skip the frame characters.  The manual says to skip '+' and '-'
     also, but there's no reason to.  Unfortunately these two unusable
     characters double the encoded length of a four byte zero
     value.  */
  while (n + 29 == '$' || n + 29 == '#')
    n--;

  *csum += '*';
  *(*p)++ = '*';
  *csum += n + 29;
  *(*p)++ = n + 29;

  return n + 1;
}

#endif

#ifndef IN_PROCESS_AGENT

/* Write a PTID to BUF.  Returns BUF+CHARACTERS_WRITTEN.  */

char *
write_ptid (char *buf, ptid_t ptid)
{
  client_state &cs = get_client_state ();
  ptid_t::pid_type pid;
  ptid_t::lwp_type lwp;

  if (cs.multi_process)
    {
      pid = ptid.pid ();
      if (pid < 0)
	buf += sprintf (buf, "p-%x.", -pid);
      else
	buf += sprintf (buf, "p%x.", pid);
    }
  lwp = ptid.lwp ();
  if (lwp < 0)
    buf += sprintf (buf, "-%lx", -lwp);
  else
    buf += sprintf (buf, "%lx", lwp);

  return buf;
}

static ULONGEST
hex_or_minus_one (const char *buf, const char **obuf)
{
  ULONGEST ret;

  if (startswith (buf, "-1"))
    {
      ret = (ULONGEST) -1;
      buf += 2;
    }
  else
    buf = unpack_varlen_hex (buf, &ret);

  if (obuf)
    *obuf = buf;

  return ret;
}

/* Extract a PTID from BUF.  If non-null, OBUF is set to one past the last
   parsed char.  Throws on error.  */
ptid_t
read_ptid (const char *buf, const char **obuf)
{
  const char *p = buf;
  const char *pp;
  ptid_t::pid_type pid = 0;
  ptid_t::lwp_type lwp = 0;
  ULONGEST hex;

  if (*p == 'p')
    {
      /* Multi-process ptid.  */
      pp = unpack_varlen_hex (p + 1, &hex);
      if (pp == (p + 1) || *pp != '.')
	error ("invalid remote ptid: %s\n", buf);

      pid = (ptid_t::pid_type) (LONGEST) hex;
      if (hex != ((ULONGEST) pid))
	error (_("invalid remote ptid: %s"), buf);

      p = pp + 1;
      hex = hex_or_minus_one (p, &pp);
      if (pp == p)
	error ("invalid remote ptid: %s\n", buf);

      lwp = (ptid_t::lwp_type) (LONGEST) hex;
      if (hex != ((ULONGEST) lwp))
	error (_("invalid remote ptid: %s"), buf);

      if (obuf)
	*obuf = pp;

      return ptid_t (pid, lwp);
    }

  /* No multi-process.  Just a thread id.  */
  hex = hex_or_minus_one (p, &pp);

  /* Handle special thread ids.  */
  if (hex == (ULONGEST) -1)
    return minus_one_ptid;

  if (hex == 0)
    return null_ptid;

  lwp = (ptid_t::lwp_type) (LONGEST) hex;
  if (hex != ((ULONGEST) lwp))
    error (_("invalid remote ptid: %s"), buf);

  /* 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 = get_first_process ()->pid;

  if (obuf)
    *obuf = pp;

  return ptid_t (pid, lwp);
}

/* Write COUNT bytes in BUF to the client.  Returns true if all bytes
   were written, false (with errno set) if not.  */

static bool
write_prim (const char *buf, int count)
{
  while (count > 0)
    {
      int written;
      if (remote_connection_is_stdio ())
	written = write (fileno (stdout), buf, count);
      else
	written = write (remote_desc, buf, count);
      if (written < 0)
	return false;
      buf += written;
      count -= written;
    }
  return true;
}

/* 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.  */

static int
putpkt_binary_1 (char *buf, int cnt, int is_notif)
{
  client_state &cs = get_client_state ();
  int i;
  unsigned char csum = 0;
  char *buf2;
  char *p;
  int cc;

  SCOPE_EXIT { suppressed_remote_debug = false; };

  buf2 = (char *) xmalloc (strlen ("$") + cnt + strlen ("#nn") + 1);

  /* Copy the packet into buffer BUF2, encapsulating it
     and giving it a checksum.  */

  p = buf2;
  if (is_notif)
    *p++ = '%';
  else
    *p++ = '$';

  for (i = 0; i < cnt;)
    i += try_rle (buf + i, cnt - i, &csum, &p);

  *p++ = '#';
  *p++ = tohex ((csum >> 4) & 0xf);
  *p++ = tohex (csum & 0xf);

  *p = '\0';

  /* Send it over and over until we get a positive ack.  */

  do
    {
      if (!write_prim (buf2, p - buf2))
	{
	  perror ("putpkt(write)");
	  free (buf2);
	  return -1;
	}

      if (cs.noack_mode || is_notif)
	{
	  /* Don't expect an ack then.  */
	  remote_debug_printf ("putpkt (\"%s\"); [%s]",
			       (suppressed_remote_debug ? "..." : buf2),
			       (is_notif ? "notif" : "noack mode"));

	  break;
	}

      remote_debug_printf ("putpkt (\"%s\"); [looking for ack]",
			   (suppressed_remote_debug ? "..." : buf2));

      cc = readchar ();

      if (cc < 0)
	{
	  free (buf2);
	  return -1;
	}

      remote_debug_printf ("[received '%c' (0x%x)]", cc, cc);

      /* Check for an input interrupt while we're here.  */
      if (cc == '\003' && current_thread != NULL)
	the_target->request_interrupt ();
    }
  while (cc != '+');

  free (buf2);
  return 1;			/* Success! */
}

int
putpkt_binary (char *buf, int cnt)
{
  return putpkt_binary_1 (buf, cnt, 0);
}

/* Send a packet to the remote machine, with error checking.  The data
   of the packet is in BUF, and the packet should be a NUL-terminated
   string.  Returns >= 0 on success, -1 otherwise.  */

int
putpkt (char *buf)
{
  return putpkt_binary (buf, strlen (buf));
}

int
putpkt_notif (char *buf)
{
  return putpkt_binary_1 (buf, strlen (buf), 1);
}

/* Come here when we get an input interrupt from the remote side.  This
   interrupt should only be active while we are waiting for the child to do
   something.  Thus this assumes readchar:bufcnt is 0.
   About the only thing that should come through is a ^C, which
   will cause us to request child interruption.  */

static void
input_interrupt (int unused)
{
  fd_set readset;
  struct timeval immediate = { 0, 0 };

  /* Protect against spurious interrupts.  This has been observed to
     be a problem under NetBSD 1.4 and 1.5.  */

  FD_ZERO (&readset);
  FD_SET (remote_desc, &readset);
  if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
    {
      int cc;
      char c = 0;

      cc = read_prim (&c, 1);

      if (cc == 0)
	{
	  fprintf (stderr, "client connection closed\n");
	  return;
	}
      else if (cc != 1 || c != '\003')
	{
	  fprintf (stderr, "input_interrupt, count = %d c = %d ", cc, c);
	  if (c_isprint (c))
	    fprintf (stderr, "('%c')\n", c);
	  else
	    fprintf (stderr, "('\\x%02x')\n", c & 0xff);
	  return;
	}

      the_target->request_interrupt ();
    }
}

/* Check if the remote side sent us an interrupt request (^C).  */
void
check_remote_input_interrupt_request (void)
{
  /* This function may be called before establishing communications,
     therefore we need to validate the remote descriptor.  */

  if (remote_desc == -1)
    return;

  input_interrupt (0);
}

/* Asynchronous I/O support.  SIGIO must be unblocked when waiting,
   in order to accept Control-C from the client, and must be blocked
   when talking to the client.  */

static void
block_unblock_async_io (int block)
{
#ifndef USE_WIN32API
  sigset_t sigio_set;

  sigemptyset (&sigio_set);
  sigaddset (&sigio_set, SIGIO);
  gdb_sigmask (block ? SIG_BLOCK : SIG_UNBLOCK, &sigio_set, NULL);
#endif
}

/* Current state of asynchronous I/O.  */
static int async_io_enabled;

/* Enable asynchronous I/O.  */
void
enable_async_io (void)
{
  if (async_io_enabled)
    return;

  block_unblock_async_io (0);

  async_io_enabled = 1;
}

/* Disable asynchronous I/O.  */
void
disable_async_io (void)
{
  if (!async_io_enabled)
    return;

  block_unblock_async_io (1);

  async_io_enabled = 0;
}

void
initialize_async_io (void)
{
  /* Make sure that async I/O starts blocked.  */
  async_io_enabled = 1;
  disable_async_io ();

  /* Install the signal handler.  */
#ifndef USE_WIN32API
  signal (SIGIO, input_interrupt);
#endif
}

/* Internal buffer used by readchar.
   These are global to readchar because reschedule_remote needs to be
   able to tell whether the buffer is empty.  */

static unsigned char readchar_buf[BUFSIZ];
static int readchar_bufcnt = 0;
static unsigned char *readchar_bufp;

/* Returns next char from remote GDB.  -1 if error.  */

static int
readchar (void)
{
  int ch;

  if (readchar_bufcnt == 0)
    {
      readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));

      if (readchar_bufcnt <= 0)
	{
	  if (readchar_bufcnt == 0)
	    {
	      remote_debug_printf ("readchar: Got EOF");
	    }
	  else
	    perror ("readchar");

	  return -1;
	}

      readchar_bufp = readchar_buf;
    }

  readchar_bufcnt--;
  ch = *readchar_bufp++;
  reschedule ();
  return ch;
}

/* Reset the readchar state machine.  */

static void
reset_readchar (void)
{
  readchar_bufcnt = 0;
  if (readchar_callback != NOT_SCHEDULED)
    {
      delete_timer (readchar_callback);
      readchar_callback = NOT_SCHEDULED;
    }
}

/* Process remaining data in readchar_buf.  */

static void
process_remaining (void *context)
{
  /* This is a one-shot event.  */
  readchar_callback = NOT_SCHEDULED;

  if (readchar_bufcnt > 0)
    handle_serial_event (0, NULL);
}

/* If there is still data in the buffer, queue another event to process it,
   we can't sleep in select yet.  */

static void
reschedule (void)
{
  if (readchar_bufcnt > 0 && readchar_callback == NOT_SCHEDULED)
    readchar_callback = create_timer (0, process_remaining, NULL);
}

/* Read a packet from the remote machine, with error checking,
   and store it in BUF.  Returns length of packet, or negative if error. */

int
getpkt (char *buf)
{
  client_state &cs = get_client_state ();
  char *bp;
  unsigned char csum, c1, c2;
  int c;

  while (1)
    {
      csum = 0;

      while (1)
	{
	  c = readchar ();

	  /* The '\003' may appear before or after each packet, so
	     check for an input interrupt.  */
	  if (c == '\003')
	    {
	      the_target->request_interrupt ();
	      continue;
	    }

	  if (c == '$')
	    break;

	  remote_debug_printf ("[getpkt: discarding char '%c']", c);

	  if (c < 0)
	    return -1;
	}

      bp = buf;
      while (1)
	{
	  c = readchar ();
	  if (c < 0)
	    return -1;
	  if (c == '#')
	    break;
	  *bp++ = c;
	  csum += c;
	}
      *bp = 0;

      c1 = fromhex (readchar ());
      c2 = fromhex (readchar ());

      if (csum == (c1 << 4) + c2)
	break;

      if (cs.noack_mode)
	{
	  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;
	}

      fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
	       (c1 << 4) + c2, csum, buf);
      if (!write_prim ("-", 1))
	return -1;
    }

  if (!cs.noack_mode)
    {
      remote_debug_printf ("getpkt (\"%s\");  [sending ack]", buf);

      if (!write_prim ("+", 1))
	return -1;

      remote_debug_printf ("[sent ack]");
    }
  else
    remote_debug_printf ("getpkt (\"%s\");  [no ack sent]", buf);

  /* The readchar above may have already read a '\003' out of the socket
     and moved it to the local buffer.  For example, when GDB sends
     vCont;c immediately followed by interrupt (see
     gdb.base/interrupt-noterm.exp).  As soon as we see the vCont;c, we'll
     resume the inferior and wait.  Since we've already moved the '\003'
     to the local buffer, SIGIO won't help.  In that case, if we don't
     check for interrupt after the vCont;c packet, the interrupt character
     would stay in the buffer unattended until after the next (unrelated)
     stop.  */
  while (readchar_bufcnt > 0 && *readchar_bufp == '\003')
    {
      /* Consume the interrupt character in the buffer.  */
      readchar ();
      the_target->request_interrupt ();
    }

  return bp - buf;
}

void
write_ok (char *buf)
{
  buf[0] = 'O';
  buf[1] = 'K';
  buf[2] = '\0';
}

void
write_enn (char *buf)
{
  /* Some day, we should define the meanings of the error codes... */
  buf[0] = 'E';
  buf[1] = '0';
  buf[2] = '1';
  buf[3] = '\0';
}

#endif

#ifndef IN_PROCESS_AGENT

static char *
outreg (struct regcache *regcache, int regno, char *buf)
{
  if ((regno >> 12) != 0)
    *buf++ = tohex ((regno >> 12) & 0xf);
  if ((regno >> 8) != 0)
    *buf++ = tohex ((regno >> 8) & 0xf);
  *buf++ = tohex ((regno >> 4) & 0xf);
  *buf++ = tohex (regno & 0xf);
  *buf++ = ':';
  collect_register_as_string (regcache, regno, buf);
  buf += 2 * register_size (regcache->tdesc, regno);
  *buf++ = ';';

  return buf;
}

void
prepare_resume_reply (char *buf, ptid_t ptid, const target_waitstatus &status)
{
  client_state &cs = get_client_state ();
  threads_debug_printf ("Writing resume reply for %s: %s",
			target_pid_to_str (ptid).c_str (),
			status.to_string ().c_str ());

  switch (status.kind ())
    {
    case TARGET_WAITKIND_STOPPED:
    case TARGET_WAITKIND_FORKED:
    case TARGET_WAITKIND_VFORKED:
    case TARGET_WAITKIND_VFORK_DONE:
    case TARGET_WAITKIND_THREAD_CLONED:
    case TARGET_WAITKIND_EXECD:
    case TARGET_WAITKIND_THREAD_CREATED:
    case TARGET_WAITKIND_SYSCALL_ENTRY:
    case TARGET_WAITKIND_SYSCALL_RETURN:
      {
	struct regcache *regcache;
	char *buf_start = buf;

	if ((status.kind () == TARGET_WAITKIND_FORKED
	     && cs.report_fork_events)
	    || (status.kind () == TARGET_WAITKIND_VFORKED
		&& cs.report_vfork_events)
	    || status.kind () == TARGET_WAITKIND_THREAD_CLONED)
	  {
	    enum gdb_signal signal = GDB_SIGNAL_TRAP;

	    auto kind_remote_str = [] (target_waitkind kind)
	    {
	      switch (kind)
		{
		case TARGET_WAITKIND_FORKED:
		  return "fork";
		case TARGET_WAITKIND_VFORKED:
		  return "vfork";
		case TARGET_WAITKIND_THREAD_CLONED:
		  return "clone";
		default:
		  gdb_assert_not_reached ("unhandled kind");
		}
	    };

	    const char *event = kind_remote_str (status.kind ());

	    sprintf (buf, "T%02x%s:", signal, event);
	    buf += strlen (buf);
	    buf = write_ptid (buf, status.child_ptid ());
	    strcat (buf, ";");
	  }
	else if (status.kind () == TARGET_WAITKIND_VFORK_DONE
		 && cs.report_vfork_events)
	  {
	    enum gdb_signal signal = GDB_SIGNAL_TRAP;

	    sprintf (buf, "T%02xvforkdone:;", signal);
	  }
	else if (status.kind () == TARGET_WAITKIND_EXECD && cs.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.execd_pathname (),
		     hexified_pathname,
		     strlen (status.execd_pathname ()));

	    sprintf (buf, "%s;", hexified_pathname);
	    buf += strlen (buf);
	  }
	else if (status.kind () == TARGET_WAITKIND_THREAD_CREATED
		 && cs.report_thread_events)
	  {
	    enum gdb_signal signal = GDB_SIGNAL_TRAP;

	    sprintf (buf, "T%02xcreate:;", signal);
	  }
	else if (status.kind () == TARGET_WAITKIND_SYSCALL_ENTRY
		 || status.kind () == TARGET_WAITKIND_SYSCALL_RETURN)
	  {
	    enum gdb_signal signal = GDB_SIGNAL_TRAP;
	    const char *event = (status.kind () == TARGET_WAITKIND_SYSCALL_ENTRY
				 ? "syscall_entry" : "syscall_return");

	    sprintf (buf, "T%02x%s:%x;", signal, event,
		     status.syscall_number ());
	  }
	else
	  sprintf (buf, "T%02x", status.sig ());

	if (disable_packet_T)
	  {
	    /* This is a bit (OK, a lot) of a kludge, however, this isn't
	       really a user feature, but exists only so GDB can use the
	       gdbserver to test handling of the 'S' stop reply packet, so
	       we would rather this code be as simple as possible.

	       By this point we've started to build the 'T' stop packet,
	       and it should look like 'Txx....' where 'x' is a hex digit.
	       An 'S' stop packet always looks like 'Sxx', so all we do
	       here is convert the buffer from a T packet to an S packet
	       and the avoid adding any extra content by breaking out.  */
	    gdb_assert (buf_start[0] == 'T');
	    gdb_assert (c_isxdigit (buf_start[1]));
	    gdb_assert (c_isxdigit (buf_start[2]));
	    buf_start[0] = 'S';
	    buf_start[3] = '\0';
	    break;
	  }

	buf += strlen (buf);

	scoped_restore_current_thread restore_thread;

	switch_to_thread (the_target, ptid);

	regcache = get_thread_regcache (current_thread);

	if (the_target->stopped_by_watchpoint ())
	  {
	    std::vector<CORE_ADDR> addr_vec
	      = the_target->stopped_data_addresses ();

	    /* If the debugger has not said that it can handle multiple
	       watchpoint addresses then discard everything except the
	       first address.

	       Choosing the first address is pretty arbitrary, and might
	       not be the best choice.  For example, if gdbserver tracked
	       the memory contents for write watchpoints then we could
	       check them all now to see which (if any) have changed.

	       For read watchpoints there's not much we can do.  If the
	       debugger cannot accept multiple addresses, then we'd just
	       have to pick one (at random) and send that.

	       For now though, our preference is to pass all the addresses
	       to the debugger (when supported), and rely on it to make a
	       smart choice.  */
	    if (!cs.multiple_wp_addr_feature
		&& addr_vec.size () > 1)
	      addr_vec.erase (addr_vec.begin () + 1, addr_vec.end ());

	    for (const CORE_ADDR addr : addr_vec)
	      {
		memcpy (buf, "watch:", 6);
		buf += 6;

		/* Convert each byte of the address into two hexadecimal
		   chars.  Note that we take sizeof (void *) instead of
		   sizeof (addr); this is to avoid sending a 64-bit
		   address to a 32-bit GDB.  */
		for (int i = sizeof (void *) * 2; i > 0; i--)
		  *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
		*buf++ = ';';
	      }
	  }
	else if (cs.swbreak_feature && target_stopped_by_sw_breakpoint ())
	  {
	    sprintf (buf, "swbreak:;");
	    buf += strlen (buf);
	  }
	else if (cs.hwbreak_feature && target_stopped_by_hw_breakpoint ())
	  {
	    sprintf (buf, "hwbreak:;");
	    buf += strlen (buf);
	  }

	/* Handle the expedited registers.  */
	for (const std::string &expedited_reg :
	     current_target_desc ()->expedite_regs)
	  buf = outreg (regcache, find_regno (regcache->tdesc,
					      expedited_reg.c_str ()), buf);
	*buf = '\0';

	/* Formerly, if the debugger had not used any thread features
	   we would not burden it with a thread status response.  This
	   was for the benefit of GDB 4.13 and older.  However, in
	   recent GDB versions the check (``if (cont_thread != 0)'')
	   does not have the desired effect because of silliness in
	   the way that the remote protocol handles specifying a
	   thread.  Since thread support relies on qSymbol support
	   anyway, assume GDB can handle threads.  */

	if (using_threads && !disable_packet_Tthread)
	  {
	    /* This if (1) ought to be unnecessary.  But remote_wait
	       in GDB will claim this event belongs to inferior_ptid
	       if we do not specify a thread, and there's no way for
	       gdbserver to know what inferior_ptid is.  */
	    if (1 || cs.general_thread != ptid)
	      {
		int core = -1;
		/* In non-stop, don't change the general thread behind
		   GDB's back.  */
		if (!non_stop)
		  cs.general_thread = ptid;
		sprintf (buf, "thread:");
		buf += strlen (buf);
		buf = write_ptid (buf, ptid);
		strcat (buf, ";");
		buf += strlen (buf);

		core = target_core_of_thread (ptid);

		if (core != -1)
		  {
		    sprintf (buf, "core:");
		    buf += strlen (buf);
		    sprintf (buf, "%x", core);
		    strcat (buf, ";");
		    buf += strlen (buf);
		  }
	      }
	  }

	if (current_process ()->dlls_changed)
	  {
	    strcpy (buf, "library:;");
	    buf += strlen (buf);
	    current_process ()->dlls_changed = false;
	  }
      }
      break;
    case TARGET_WAITKIND_EXITED:
      if (cs.multi_process)
	sprintf (buf, "W%x;process:%x",
		 status.exit_status (), ptid.pid ());
      else
	sprintf (buf, "W%02x", status.exit_status ());
      break;
    case TARGET_WAITKIND_SIGNALLED:
      if (cs.multi_process)
	sprintf (buf, "X%x;process:%x",
		 status.sig (), ptid.pid ());
      else
	sprintf (buf, "X%02x", status.sig ());
      break;
    case TARGET_WAITKIND_THREAD_EXITED:
      sprintf (buf, "w%x;", status.exit_status ());
      buf += strlen (buf);
      buf = write_ptid (buf, ptid);
      break;
    case TARGET_WAITKIND_NO_RESUMED:
      sprintf (buf, "N");
      break;
    default:
      error ("unhandled waitkind");
      break;
    }
}

/* See remote-utils.h.  */

const char *
decode_m_packet_params (const char *from, CORE_ADDR *mem_addr_ptr,
			unsigned int *len_ptr, const char end_marker)
{
  int i = 0;
  char ch;
  *mem_addr_ptr = *len_ptr = 0;

  while ((ch = from[i++]) != ',')
    {
      *mem_addr_ptr = *mem_addr_ptr << 4;
      *mem_addr_ptr |= fromhex (ch) & 0x0f;
    }

  while ((ch = from[i++]) != end_marker)
    {
      *len_ptr = *len_ptr << 4;
      *len_ptr |= fromhex (ch) & 0x0f;
    }

  return from + i;
}

void
decode_m_packet (const char *from, CORE_ADDR *mem_addr_ptr,
		 unsigned int *len_ptr)
{
  decode_m_packet_params (from, mem_addr_ptr, len_ptr, '\0');
}

void
decode_M_packet (const char *from, CORE_ADDR *mem_addr_ptr,
		 unsigned int *len_ptr, unsigned char **to_p)
{
  from = decode_m_packet_params (from, mem_addr_ptr, len_ptr, ':');

  if (*to_p == NULL)
    *to_p = (unsigned char *) xmalloc (*len_ptr);

  hex2bin (from, *to_p, *len_ptr);
}

void
decode_x_packet (const char *from, CORE_ADDR *mem_addr_ptr,
		 unsigned int *len_ptr)
{
  decode_m_packet_params (from, mem_addr_ptr, len_ptr, '\0');
}

int
decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
		 unsigned int *len_ptr, unsigned char **to_p)
{
  int i = 0;
  char ch;
  *mem_addr_ptr = *len_ptr = 0;

  while ((ch = from[i++]) != ',')
    {
      *mem_addr_ptr = *mem_addr_ptr << 4;
      *mem_addr_ptr |= fromhex (ch) & 0x0f;
    }

  while ((ch = from[i++]) != ':')
    {
      *len_ptr = *len_ptr << 4;
      *len_ptr |= fromhex (ch) & 0x0f;
    }

  if (*to_p == NULL)
    *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)
    return -1;

  return 0;
}

/* Decode a qXfer write request.  */

int
decode_xfer_write (char *buf, int packet_len, CORE_ADDR *offset,
		   unsigned int *len, unsigned char *data)
{
  char ch;
  char *b = buf;

  /* Extract the offset.  */
  *offset = 0;
  while ((ch = *buf++) != ':')
    {
      *offset = *offset << 4;
      *offset |= fromhex (ch) & 0x0f;
    }

  /* Get encoded data.  */
  packet_len -= buf - b;
  *len = remote_unescape_input ((const gdb_byte *) buf, packet_len,
				data, packet_len);
  return 0;
}

/* Decode the parameters of a qSearch:memory packet.  */

int
decode_search_memory_packet (const char *buf, int packet_len,
			     CORE_ADDR *start_addrp,
			     CORE_ADDR *search_space_lenp,
			     gdb_byte *pattern, unsigned int *pattern_lenp)
{
  const char *p = buf;

  p = decode_address_to_semicolon (start_addrp, p);
  p = decode_address_to_semicolon (search_space_lenp, p);
  packet_len -= p - buf;
  *pattern_lenp = remote_unescape_input ((const gdb_byte *) p, packet_len,
					 pattern, packet_len);
  return 0;
}

static void
free_sym_cache (struct sym_cache *sym)
{
  if (sym != NULL)
    {
      free (sym->name);
      free (sym);
    }
}

void
clear_symbol_cache (struct sym_cache **symcache_p)
{
  struct sym_cache *sym, *next;

  /* Check the cache first.  */
  for (sym = *symcache_p; sym; sym = next)
    {
      next = sym->next;
      free_sym_cache (sym);
    }

  *symcache_p = NULL;
}

/* Get the address of NAME, and return it in ADDRP if found.  if
   MAY_ASK_GDB is false, assume symbol cache misses are failures.
   Returns 1 if the symbol is found, 0 if it is not, -1 on error.  */

int
look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
{
  client_state &cs = get_client_state ();
  char *p, *q;
  int len;
  struct sym_cache *sym;
  struct process_info *proc;

  proc = current_process ();

  /* Check the cache first.  */
  for (sym = proc->symbol_cache; sym; sym = sym->next)
    if (strcmp (name, sym->name) == 0)
      {
	*addrp = sym->addr;
	return 1;
      }

  /* It might not be an appropriate time to look up a symbol,
     e.g. while we're trying to fetch registers.  */
  if (!may_ask_gdb)
    return 0;

  /* Send the request.  */
  strcpy (cs.own_buf, "qSymbol:");
  bin2hex ((const gdb_byte *) name, cs.own_buf + strlen ("qSymbol:"),
	  strlen (name));
  if (putpkt (cs.own_buf) < 0)
    return -1;

  /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
  len = getpkt (cs.own_buf);
  if (len < 0)
    return -1;

  /* We ought to handle pretty much any packet at this point while we
     wait for the qSymbol "response".  That requires re-entering the
     main loop.  For now, this is an adequate approximation; allow
     GDB to read from memory and handle 'v' packets (for vFile transfers)
     while it figures out the address of the symbol.  */
  while (1)
    {
      CORE_ADDR mem_addr;
      unsigned char *mem_buf;
      unsigned int mem_len;
      int new_len = -1;

      if (cs.own_buf[0] == 'm')
	{
	  decode_m_packet (&cs.own_buf[1], &mem_addr, &mem_len);
	  mem_buf = (unsigned char *) xmalloc (mem_len);
	  if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
	    bin2hex (mem_buf, cs.own_buf, mem_len);
	  else
	    write_enn (cs.own_buf);
	  free (mem_buf);
	  if (putpkt (cs.own_buf) < 0)
	    return -1;
	}
      else if (cs.own_buf[0] == 'x')
	{
	  decode_x_packet (&cs.own_buf[1], &mem_addr, &mem_len);
	  mem_buf = (unsigned char *) xmalloc (mem_len);
	  if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
	    {
	      gdb_byte *buffer = (gdb_byte *) cs.own_buf;
	      *buffer++ = 'b';

	      int out_len_units;
	      new_len = remote_escape_output (mem_buf, mem_len, 1,
					      buffer,
					      &out_len_units,
					      PBUFSIZ);
	      new_len++; /* For the 'b' marker.  */

	      if (out_len_units != mem_len)
		{
		  write_enn (cs.own_buf);
		  new_len = -1;
		}
	      else
		suppress_next_putpkt_log ();
	    }
	  else
	    write_enn (cs.own_buf);

	  free (mem_buf);
	  int res = ((new_len == -1)
		     ? putpkt (cs.own_buf)
		     : putpkt_binary (cs.own_buf, new_len));
	  if (res < 0)
	    return -1;
	}
      else if (cs.own_buf[0] == 'v')
	{
	  handle_v_requests (cs.own_buf, len, &new_len);
	  if (new_len != -1)
	    putpkt_binary (cs.own_buf, new_len);
	  else
	    putpkt (cs.own_buf);
	}
      else
	break;
      len = getpkt (cs.own_buf);
      if (len < 0)
	return -1;
    }

  if (!startswith (cs.own_buf, "qSymbol:"))
    {
      warning ("Malformed response to qSymbol, ignoring: %s", cs.own_buf);
      return -1;
    }

  p = cs.own_buf + strlen ("qSymbol:");
  q = p;
  while (*q && *q != ':')
    q++;

  /* Make sure we found a value for the symbol.  */
  if (p == q || *q == '\0')
    return 0;

  decode_address (addrp, p, q - p);

  /* Save the symbol in our cache.  */
  sym = XNEW (struct sym_cache);
  sym->name = xstrdup (name);
  sym->addr = *addrp;
  sym->next = proc->symbol_cache;
  proc->symbol_cache = sym;

  return 1;
}

/* Relocate an instruction to execute at a different address.  OLDLOC
   is the address in the inferior memory where the instruction to
   relocate is currently at.  On input, TO points to the destination
   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 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
   offset adjusted; etc.  Returns 0 on success, -1 on failure.  */

int
relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
{
  client_state &cs = get_client_state ();
  int len;
  ULONGEST written = 0;

  /* Send the request.  */
  sprintf (cs.own_buf, "qRelocInsn:%s;%s", paddress (oldloc),
	   paddress (*to));
  if (putpkt (cs.own_buf) < 0)
    return -1;

  /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
  len = getpkt (cs.own_buf);
  if (len < 0)
    return -1;

  /* We ought to handle pretty much any packet at this point while we
     wait for the qRelocInsn "response".  That requires re-entering
     the main loop.  For now, this is an adequate approximation; allow
     GDB to access memory.  */
  while (cs.own_buf[0] == 'm' || cs.own_buf[0] == 'M'
	 || cs.own_buf[0] == 'X' || cs.own_buf[0] == 'x')
    {
      CORE_ADDR mem_addr;
      unsigned char *mem_buf = NULL;
      unsigned int mem_len;
      int new_len = -1;

      if (cs.own_buf[0] == 'm')
	{
	  decode_m_packet (&cs.own_buf[1], &mem_addr, &mem_len);
	  mem_buf = (unsigned char *) xmalloc (mem_len);
	  if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
	    bin2hex (mem_buf, cs.own_buf, mem_len);
	  else
	    write_enn (cs.own_buf);
	}
      else if (cs.own_buf[0] == 'x')
	{
	  decode_x_packet (&cs.own_buf[1], &mem_addr, &mem_len);
	  mem_buf = (unsigned char *) xmalloc (mem_len);
	  if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
	    {
	      gdb_byte *buffer = (gdb_byte *) cs.own_buf;
	      *buffer++ = 'b';

	      int out_len_units;
	      new_len = remote_escape_output (mem_buf, mem_len, 1,
					      buffer,
					      &out_len_units,
					      PBUFSIZ);
	      new_len++; /* For the 'b' marker.  */

	      if (out_len_units != mem_len)
		{
		  write_enn (cs.own_buf);
		  new_len = -1;
		}
	      else
		suppress_next_putpkt_log ();
	    }
	  else
	    write_enn (cs.own_buf);
	}
      else if (cs.own_buf[0] == 'X')
	{
	  if (decode_X_packet (&cs.own_buf[1], len - 1, &mem_addr,
			       &mem_len, &mem_buf) < 0
	      || target_write_memory (mem_addr, mem_buf, mem_len) != 0)
	    write_enn (cs.own_buf);
	  else
	    write_ok (cs.own_buf);
	}
      else
	{
	  decode_M_packet (&cs.own_buf[1], &mem_addr, &mem_len, &mem_buf);
	  if (target_write_memory (mem_addr, mem_buf, mem_len) == 0)
	    write_ok (cs.own_buf);
	  else
	    write_enn (cs.own_buf);
	}
      free (mem_buf);

      int res = ((new_len == -1)
		 ? putpkt (cs.own_buf)
		 : putpkt_binary (cs.own_buf, new_len));
      if (res < 0)
	return -1;
      len = getpkt (cs.own_buf);
      if (len < 0)
	return -1;
    }

  if (cs.own_buf[0] == 'E')
    {
      warning ("An error occurred while relocating an instruction: %s",
	       cs.own_buf);
      return -1;
    }

  if (!startswith (cs.own_buf, "qRelocInsn:"))
    {
      warning ("Malformed response to qRelocInsn, ignoring: %s",
	       cs.own_buf);
      return -1;
    }

  unpack_varlen_hex (cs.own_buf + strlen ("qRelocInsn:"), &written);

  *to += written;
  return 0;
}

void
monitor_output (const char *msg)
{
  int len = strlen (msg);
  char *buf = (char *) xmalloc (len * 2 + 2);

  buf[0] = 'O';
  bin2hex ((const gdb_byte *) msg, buf + 1, len);

  putpkt (buf);
  free (buf);
}

#endif
