/* Remote utility routines for the remote server for GDB.
   Copyright (C) 1986-2021 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/>.  */

#include "server.h"
#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/rsp-low.h"
#include "gdbsupport/netstuff.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/gdb-sigmask.h"
#include <ctype.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);

  if (debug_threads)
    debug_printf ("handling possible accept event\n");

  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 (__FILE__, __LINE__,
		      _("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 ();
  int pid, tid;

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

  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 the to one
   passed the last parsed char.  Returns null_ptid on error.  */
ptid_t
read_ptid (const char *buf, const char **obuf)
{
  const char *p = buf;
  const char *pp;
  ULONGEST pid = 0, tid = 0;

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

      p = pp + 1;

      tid = hex_or_minus_one (p, &pp);

      if (obuf)
	*obuf = pp;
      return ptid_t (pid, tid);
    }

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

  /* 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_t (pid, tid);
}

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

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;

  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) != p - buf2)
	{
	  perror ("putpkt(write)");
	  free (buf2);
	  return -1;
	}

      if (cs.noack_mode || is_notif)
	{
	  /* Don't expect an ack then.  */
	  if (remote_debug)
	    {
	      if (is_notif)
		debug_printf ("putpkt (\"%s\"); [notif]\n", buf2);
	      else
		debug_printf ("putpkt (\"%s\"); [noack mode]\n", buf2);
	      debug_flush ();
	    }
	  break;
	}

      if (remote_debug)
	{
	  debug_printf ("putpkt (\"%s\"); [looking for ack]\n", buf2);
	  debug_flush ();
	}

      cc = readchar ();

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

      if (remote_debug)
	{
	  debug_printf ("[received '%c' (0x%x)]\n", cc, cc);
	  debug_flush ();
	}

      /* 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 (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)
	    {
	      if (remote_debug)
		debug_printf ("readchar: Got EOF\n");
	    }
	  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;
	  if (remote_debug)
	    {
	      debug_printf ("[getpkt: discarding char '%c']\n", c);
	      debug_flush ();
	    }

	  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) != 1)
	return -1;
    }

  if (!cs.noack_mode)
    {
      if (remote_debug)
	{
	  debug_printf ("getpkt (\"%s\");  [sending ack] \n", buf);
	  debug_flush ();
	}

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

      if (remote_debug)
	{
	  debug_printf ("[sent ack]\n");
	  debug_flush ();
	}
    }
  else
    {
      if (remote_debug)
	{
	  debug_printf ("getpkt (\"%s\");  [no ack sent] \n", buf);
	  debug_flush ();
	}
    }

  /* 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,
		      struct target_waitstatus *status)
{
  client_state &cs = get_client_state ();
  if (debug_threads)
    debug_printf ("Writing resume reply for %s:%d\n",
		  target_pid_to_str (ptid).c_str (), 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:
    case TARGET_WAITKIND_SYSCALL_ENTRY:
    case TARGET_WAITKIND_SYSCALL_RETURN:
      {
	struct thread_info *saved_thread;
	const char **regp;
	struct regcache *regcache;

	if ((status->kind () == TARGET_WAITKIND_FORKED && cs.report_fork_events)
	    || (status->kind () == TARGET_WAITKIND_VFORKED
		&& cs.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->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 == 'T');
	    gdb_assert (isxdigit (*(buf + 1)));
	    gdb_assert (isxdigit (*(buf + 2)));
	    *buf = 'S';
	    *(buf + 3) = '\0';
	    break;
	  }

	buf += strlen (buf);

	saved_thread = current_thread;

	switch_to_thread (the_target, ptid);

	regp = current_target_desc ()->expedite_regs;

	regcache = get_thread_regcache (current_thread, 1);

	if (the_target->stopped_by_watchpoint ())
	  {
	    CORE_ADDR addr;
	    int i;

	    memcpy (buf, "watch:", 6);
	    buf += 6;

	    addr = the_target->stopped_data_address ();

	    /* 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 (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);
	  }

	while (*regp)
	  {
	    buf = outreg (regcache, find_regno (regcache->tdesc, *regp), buf);
	    regp ++;
	  }
	*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 sillyness 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;
	  }

	current_thread = saved_thread;
      }
      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);
}

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)
    {
      if (cs.own_buf[0] == 'm')
	{
	  CORE_ADDR mem_addr;
	  unsigned char *mem_buf;
	  unsigned int mem_len;

	  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] == 'v')
	{
	  int new_len = -1;
	  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')
    {
      CORE_ADDR mem_addr;
      unsigned char *mem_buf = NULL;
      unsigned int mem_len;

      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')
	{
	  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);
      if (putpkt (cs.own_buf) < 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
