/* Main code for remote server for GDB.
   Copyright (C) 1989-2025 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 "gdbthread.h"
#include "gdbsupport/agent.h"
#include "notif.h"
#include "tdesc.h"
#include "gdbsupport/rsp-low.h"
#include "gdbsupport/signals-state-save-restore.h"
#include <unistd.h>
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#include "gdbsupport/gdb_vecs.h"
#include "gdbsupport/gdb_wait.h"
#include "gdbsupport/btrace-common.h"
#include "gdbsupport/filestuff.h"
#include "tracepoint.h"
#include "dll.h"
#include "hostio.h"
#include <vector>
#include "gdbsupport/unordered_map.h"
#include "gdbsupport/common-inferior.h"
#include "gdbsupport/job-control.h"
#include "gdbsupport/environ.h"
#include "filenames.h"
#include "gdbsupport/pathstuff.h"
#ifdef USE_XML
#include "xml-builtin.h"
#endif

#include "gdbsupport/selftest.h"
#include "gdbsupport/scope-exit.h"
#include "gdbsupport/gdb_select.h"
#include "gdbsupport/scoped_restore.h"
#include "gdbsupport/search.h"
#include "gdbsupport/gdb_argv_vec.h"
#include "gdbsupport/remote-args.h"

#include <getopt.h>

/* PBUFSIZ must also be at least as big as IPA_CMD_BUF_SIZE, because
   the client state data is passed directly to some agent
   functions.  */
static_assert (PBUFSIZ >= IPA_CMD_BUF_SIZE);

#define require_running_or_return(BUF)		\
  if (!target_running ())			\
    {						\
      write_enn (BUF);				\
      return;					\
    }

#define require_running_or_break(BUF)		\
  if (!target_running ())			\
    {						\
      write_enn (BUF);				\
      break;					\
    }

/* The environment to pass to the inferior when creating it.  */

static gdb_environ our_environ;

bool server_waiting;

static bool extended_protocol;
static bool response_needed;
static bool exit_requested;

/* --once: Exit after the first connection has closed.  */
bool run_once;

/* Whether to report TARGET_WAITKIND_NO_RESUMED events.  */
static bool report_no_resumed;

/* The event loop checks this to decide whether to continue accepting
   events.  */
static bool keep_processing_events = true;

bool non_stop;

static struct {
  /* Set the PROGRAM_PATH.  Here we adjust the path of the provided
     binary if needed.  */
  void set (const char *path)
  {
    m_path = path;

    /* Make sure we're using the absolute path of the inferior when
       creating it.  */
    if (!contains_dir_separator (m_path.c_str ()))
      {
	int reg_file_errno;

	/* Check if the file is in our CWD.  If it is, then we prefix
	   its name with CURRENT_DIRECTORY.  Otherwise, we leave the
	   name as-is because we'll try searching for it in $PATH.  */
	if (is_regular_file (m_path.c_str (), &reg_file_errno))
	  m_path = gdb_abspath (m_path);
      }
  }

  /* Return the PROGRAM_PATH.  */
  const char *get ()
  { return m_path.empty () ? nullptr : m_path.c_str (); }

private:
  /* The program name, adjusted if needed.  */
  std::string m_path;
} program_path;

/* All program arguments are merged into a single string.  */

static std::string program_args;

static std::string wrapper_argv;

/* The PID of the originally created or attached inferior.  Used to
   send signals to the process when GDB sends us an asynchronous interrupt
   (user hitting Control-C in the client), and to wait for the child to exit
   when no longer debugging it.  */

unsigned long signal_pid;

/* Set if you want to disable optional thread related packets support
   in gdbserver, for the sake of testing GDB against stubs that don't
   support them.  */
bool disable_packet_vCont;
bool disable_packet_vCont_step;
bool disable_packet_Tthread;
bool disable_packet_qC;
bool disable_packet_qfThreadInfo;
bool disable_packet_T;

static unsigned char *mem_buf;

/* A sub-class of 'struct notif_event' for stop, holding information
   relative to a single stop reply.  We keep a queue of these to
   push to GDB in non-stop mode.  */

struct vstop_notif : public notif_event
{
  /* Thread or process that got the event.  */
  ptid_t ptid;

  /* Event info.  */
  struct target_waitstatus status;
};

/* The current btrace configuration.  This is gdbserver's mirror of GDB's
   btrace configuration.  */
static struct btrace_config current_btrace_conf;

/* The client remote protocol state. */

static client_state g_client_state;

client_state &
get_client_state ()
{
  client_state &cs = g_client_state;
  return cs;
}


/* Put a stop reply to the stop reply queue.  */

static void
queue_stop_reply (ptid_t ptid, const target_waitstatus &status)
{
  struct vstop_notif *new_notif = new struct vstop_notif;

  new_notif->ptid = ptid;
  new_notif->status = status;

  notif_event_enque (&notif_stop, new_notif);
}

static bool
remove_all_on_match_ptid (struct notif_event *event, ptid_t filter_ptid)
{
  struct vstop_notif *vstop_event = (struct vstop_notif *) event;

  return vstop_event->ptid.matches (filter_ptid);
}

/* See server.h.  */

void
discard_queued_stop_replies (ptid_t ptid)
{
  std::list<notif_event *>::iterator iter, next, end;
  end = notif_stop.queue.end ();
  for (iter = notif_stop.queue.begin (); iter != end; iter = next)
    {
      next = iter;
      ++next;

      if (iter == notif_stop.queue.begin ())
	{
	  /* The head of the list contains the notification that was
	     already sent to GDB.  So we can't remove it, otherwise
	     when GDB sends the vStopped, it would ack the _next_
	     notification, which hadn't been sent yet!  */
	  continue;
	}

      if (remove_all_on_match_ptid (*iter, ptid))
	{
	  delete *iter;
	  notif_stop.queue.erase (iter);
	}
    }
}

static void
vstop_notif_reply (struct notif_event *event, char *own_buf)
{
  struct vstop_notif *vstop = (struct vstop_notif *) event;

  prepare_resume_reply (own_buf, vstop->ptid, vstop->status);
}

/* Helper for in_queued_stop_replies.  */

static bool
in_queued_stop_replies_ptid (struct notif_event *event, ptid_t filter_ptid)
{
  struct vstop_notif *vstop_event = (struct vstop_notif *) event;

  if (vstop_event->ptid.matches (filter_ptid))
    return true;

  /* Don't resume fork children that GDB does not know about yet.  */
  if ((vstop_event->status.kind () == TARGET_WAITKIND_FORKED
       || vstop_event->status.kind () == TARGET_WAITKIND_VFORKED
       || vstop_event->status.kind () == TARGET_WAITKIND_THREAD_CLONED)
      && vstop_event->status.child_ptid ().matches (filter_ptid))
    return true;

  return false;
}

/* See server.h.  */

int
in_queued_stop_replies (ptid_t ptid)
{
  for (notif_event *event : notif_stop.queue)
    {
      if (in_queued_stop_replies_ptid (event, ptid))
	return true;
    }

  return false;
}

struct notif_server notif_stop =
{
  "vStopped", "Stop", {}, vstop_notif_reply,
};

static int
target_running (void)
{
  return get_first_thread () != NULL;
}

/* See gdbsupport/common-inferior.h.  */

const char *
get_exec_wrapper ()
{
  return !wrapper_argv.empty () ? wrapper_argv.c_str () : NULL;
}

/* See server.h.  */

gdb_environ *
get_environ ()
{
  return &our_environ;
}

static int
attach_inferior (int pid)
{
  client_state &cs = get_client_state ();
  /* myattach should return -1 if attaching is unsupported,
     0 if it succeeded, and call error() otherwise.  */

  if (find_process_pid (pid) != nullptr)
    error ("Already attached to process %d\n", pid);

  if (myattach (pid) != 0)
    return -1;

  fprintf (stderr, "Attached; pid = %d\n", pid);
  fflush (stderr);

  /* FIXME - It may be that we should get the SIGNAL_PID from the
     attach function, so that it can be the main thread instead of
     whichever we were told to attach to.  */
  signal_pid = pid;

  if (!non_stop)
    {
      cs.last_ptid = mywait (ptid_t (pid), &cs.last_status, 0, 0);

      /* GDB knows to ignore the first SIGSTOP after attaching to a running
	 process using the "attach" command, but this is different; it's
	 just using "target remote".  Pretend it's just starting up.  */
      if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED
	  && cs.last_status.sig () == GDB_SIGNAL_STOP)
	cs.last_status.set_stopped (GDB_SIGNAL_TRAP);

      current_thread->last_resume_kind = resume_stop;
      current_thread->last_status = cs.last_status;
    }

  return 0;
}

/* Decode a qXfer read request.  Return 0 if everything looks OK,
   or -1 otherwise.  */

static int
decode_xfer_read (char *buf, CORE_ADDR *ofs, unsigned int *len)
{
  /* After the read marker and annex, qXfer looks like a
     traditional 'm' packet.  */
  decode_m_packet (buf, ofs, len);

  return 0;
}

static int
decode_xfer (char *buf, char **object, char **rw, char **annex, char **offset)
{
  /* Extract and NUL-terminate the object.  */
  *object = buf;
  while (*buf && *buf != ':')
    buf++;
  if (*buf == '\0')
    return -1;
  *buf++ = 0;

  /* Extract and NUL-terminate the read/write action.  */
  *rw = buf;
  while (*buf && *buf != ':')
    buf++;
  if (*buf == '\0')
    return -1;
  *buf++ = 0;

  /* Extract and NUL-terminate the annex.  */
  *annex = buf;
  while (*buf && *buf != ':')
    buf++;
  if (*buf == '\0')
    return -1;
  *buf++ = 0;

  *offset = buf;
  return 0;
}

/* Write the response to a successful qXfer read.  Returns the
   length of the (binary) data stored in BUF, corresponding
   to as much of DATA/LEN as we could fit.  IS_MORE controls
   the first character of the response.  */
static int
write_qxfer_response (char *buf, const gdb_byte *data, int len, int is_more)
{
  int out_len;

  if (is_more)
    buf[0] = 'm';
  else
    buf[0] = 'l';

  return remote_escape_output (data, len, 1, (unsigned char *) buf + 1,
			       &out_len, PBUFSIZ - 2) + 1;
}

/* Handle btrace enabling in BTS format.  */

static void
handle_btrace_enable_bts (thread_info *thread)
{
  if (thread->btrace != NULL)
    error (_("Btrace already enabled."));

  current_btrace_conf.format = BTRACE_FORMAT_BTS;
  thread->btrace = target_enable_btrace (thread, &current_btrace_conf);
}

/* Handle btrace enabling in Intel Processor Trace format.  */

static void
handle_btrace_enable_pt (thread_info *thread)
{
  if (thread->btrace != NULL)
    error (_("Btrace already enabled."));

  current_btrace_conf.format = BTRACE_FORMAT_PT;
  thread->btrace = target_enable_btrace (thread, &current_btrace_conf);
}

/* Handle btrace disabling.  */

static void
handle_btrace_disable (thread_info *thread)
{

  if (thread->btrace == NULL)
    error (_("Branch tracing not enabled."));

  if (target_disable_btrace (thread->btrace) != 0)
    error (_("Could not disable branch tracing."));

  thread->btrace = NULL;
}

/* Handle the "Qbtrace" packet.  */

static int
handle_btrace_general_set (char *own_buf)
{
  client_state &cs = get_client_state ();
  thread_info *thread;
  char *op;

  if (!startswith (own_buf, "Qbtrace:"))
    return 0;

  op = own_buf + strlen ("Qbtrace:");

  if (cs.general_thread == null_ptid
      || cs.general_thread == minus_one_ptid)
    {
      strcpy (own_buf, "E.Must select a single thread.");
      return -1;
    }

  thread = find_thread_ptid (cs.general_thread);
  if (thread == NULL)
    {
      strcpy (own_buf, "E.No such thread.");
      return -1;
    }

  try
    {
      if (strcmp (op, "bts") == 0)
	handle_btrace_enable_bts (thread);
      else if (strcmp (op, "pt") == 0)
	handle_btrace_enable_pt (thread);
      else if (strcmp (op, "off") == 0)
	handle_btrace_disable (thread);
      else
	error (_("Bad Qbtrace operation.  Use bts, pt, or off."));

      write_ok (own_buf);
    }
  catch (const gdb_exception_error &exception)
    {
      sprintf (own_buf, "E.%s", exception.what ());
    }

  return 1;
}

/* Handle the "Qbtrace-conf" packet.  */

static int
handle_btrace_conf_general_set (char *own_buf)
{
  client_state &cs = get_client_state ();
  thread_info *thread;
  char *op;

  if (!startswith (own_buf, "Qbtrace-conf:"))
    return 0;

  op = own_buf + strlen ("Qbtrace-conf:");

  if (cs.general_thread == null_ptid
      || cs.general_thread == minus_one_ptid)
    {
      strcpy (own_buf, "E.Must select a single thread.");
      return -1;
    }

  thread = find_thread_ptid (cs.general_thread);
  if (thread == NULL)
    {
      strcpy (own_buf, "E.No such thread.");
      return -1;
    }

  if (startswith (op, "bts:size="))
    {
      unsigned long size;
      char *endp = NULL;

      errno = 0;
      size = strtoul (op + strlen ("bts:size="), &endp, 16);
      if (endp == NULL || *endp != 0 || errno != 0 || size > UINT_MAX)
	{
	  strcpy (own_buf, "E.Bad size value.");
	  return -1;
	}

      current_btrace_conf.bts.size = (unsigned int) size;
    }
  else if (strncmp (op, "pt:size=", strlen ("pt:size=")) == 0)
    {
      unsigned long size;
      char *endp = NULL;

      errno = 0;
      size = strtoul (op + strlen ("pt:size="), &endp, 16);
      if (endp == NULL || *endp != 0 || errno != 0 || size > UINT_MAX)
	{
	  strcpy (own_buf, "E.Bad size value.");
	  return -1;
	}

      current_btrace_conf.pt.size = (unsigned int) size;
    }
  else if (strncmp (op, "pt:ptwrite=", strlen ("pt:ptwrite=")) == 0)
    {
      op += strlen ("pt:ptwrite=");
      if (strncmp (op, "\"yes\"", strlen ("\"yes\"")) == 0)
	current_btrace_conf.pt.ptwrite = true;
      else if (strncmp (op, "\"no\"", strlen ("\"no\"")) == 0)
	current_btrace_conf.pt.ptwrite = false;
      else
	{
	  strcpy (own_buf, "E.Bad ptwrite value.");
	  return -1;
	}
    }
  else if (strncmp (op, "pt:event-tracing=", strlen ("pt:event-tracing=")) == 0)
    {
      op += strlen ("pt:event-tracing=");
      if (strncmp (op, "\"yes\"", strlen ("\"yes\"")) == 0)
	current_btrace_conf.pt.event_tracing = true;
      else if (strncmp (op, "\"no\"", strlen ("\"no\"")) == 0)
	current_btrace_conf.pt.event_tracing = false;
      else
	{
	  strcpy (own_buf, "E.Bad event-tracing value.");
	  return -1;
	}
    }
  else
    {
      strcpy (own_buf, "E.Bad Qbtrace configuration option.");
      return -1;
    }

  write_ok (own_buf);
  return 1;
}

/* Create the qMemTags packet reply given TAGS.

   Returns true if parsing succeeded and false otherwise.  */

static bool
create_fetch_memtags_reply (char *reply, const gdb::byte_vector &tags)
{
  /* It is an error to pass a zero-sized tag vector.  */
  gdb_assert (tags.size () != 0);

  std::string packet ("m");

  /* Write the tag data.  */
  packet += bin2hex (tags.data (), tags.size ());

  /* Check if the reply is too big for the packet to handle.  */
  if (PBUFSIZ < packet.size ())
    return false;

  strcpy (reply, packet.c_str ());
  return true;
}

/* Parse the QMemTags request into ADDR, LEN and TAGS.

   Returns true if parsing succeeded and false otherwise.  */

static bool
parse_store_memtags_request (char *request, CORE_ADDR *addr, size_t *len,
			     gdb::byte_vector &tags, int *type)
{
  gdb_assert (startswith (request, "QMemTags:"));

  const char *p = request + strlen ("QMemTags:");

  /* Read address and length.  */
  unsigned int length = 0;
  p = decode_m_packet_params (p, addr, &length, ':');
  *len = length;

  /* Read the tag type.  */
  ULONGEST tag_type = 0;
  p = unpack_varlen_hex (p, &tag_type);
  *type = (int) tag_type;

  /* Make sure there is a colon after the type.  */
  if (*p != ':')
    return false;

  /* Skip the colon.  */
  p++;

  /* Read the tag data.  */
  tags = hex2bin (p);

  return true;
}

/* Parse thread options starting at *P and return them.  On exit,
   advance *P past the options.  */

static gdb_thread_options
parse_gdb_thread_options (const char **p)
{
  ULONGEST options = 0;
  *p = unpack_varlen_hex (*p, &options);
  return (gdb_thread_option) options;
}

/* Handle all of the extended 'Q' packets.  */

static void
handle_general_set (char *own_buf)
{
  client_state &cs = get_client_state ();
  if (startswith (own_buf, "QPassSignals:"))
    {
      int numsigs = (int) GDB_SIGNAL_LAST, i;
      const char *p = own_buf + strlen ("QPassSignals:");
      CORE_ADDR cursig;

      p = decode_address_to_semicolon (&cursig, p);
      for (i = 0; i < numsigs; i++)
	{
	  if (i == cursig)
	    {
	      cs.pass_signals[i] = 1;
	      if (*p == '\0')
		/* Keep looping, to clear the remaining signals.  */
		cursig = -1;
	      else
		p = decode_address_to_semicolon (&cursig, p);
	    }
	  else
	    cs.pass_signals[i] = 0;
	}
      strcpy (own_buf, "OK");
      return;
    }

  if (startswith (own_buf, "QProgramSignals:"))
    {
      int numsigs = (int) GDB_SIGNAL_LAST, i;
      const char *p = own_buf + strlen ("QProgramSignals:");
      CORE_ADDR cursig;

      cs.program_signals_p = 1;

      p = decode_address_to_semicolon (&cursig, p);
      for (i = 0; i < numsigs; i++)
	{
	  if (i == cursig)
	    {
	      cs.program_signals[i] = 1;
	      if (*p == '\0')
		/* Keep looping, to clear the remaining signals.  */
		cursig = -1;
	      else
		p = decode_address_to_semicolon (&cursig, p);
	    }
	  else
	    cs.program_signals[i] = 0;
	}
      strcpy (own_buf, "OK");
      return;
    }

  if (startswith (own_buf, "QCatchSyscalls:"))
    {
      const char *p = own_buf + sizeof ("QCatchSyscalls:") - 1;
      int enabled = -1;
      CORE_ADDR sysno;
      struct process_info *process;

      if (!target_running () || !target_supports_catch_syscall ())
	{
	  write_enn (own_buf);
	  return;
	}

      if (strcmp (p, "0") == 0)
	enabled = 0;
      else if (p[0] == '1' && (p[1] == ';' || p[1] == '\0'))
	enabled = 1;
      else
	{
	  fprintf (stderr, "Unknown catch-syscalls mode requested: %s\n",
		   own_buf);
	  write_enn (own_buf);
	  return;
	}

      process = current_process ();
      process->syscalls_to_catch.clear ();

      if (enabled)
	{
	  p += 1;
	  if (*p == ';')
	    {
	      p += 1;
	      while (*p != '\0')
		{
		  p = decode_address_to_semicolon (&sysno, p);
		  process->syscalls_to_catch.push_back (sysno);
		}
	    }
	  else
	    process->syscalls_to_catch.push_back (ANY_SYSCALL);
	}

      write_ok (own_buf);
      return;
    }

  if (strcmp (own_buf, "QEnvironmentReset") == 0)
    {
      our_environ = gdb_environ::from_host_environ ();

      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QEnvironmentHexEncoded:"))
    {
      const char *p = own_buf + sizeof ("QEnvironmentHexEncoded:") - 1;
      /* The final form of the environment variable.  FINAL_VAR will
	 hold the 'VAR=VALUE' format.  */
      std::string final_var = hex2str (p);
      std::string var_name, var_value;

      remote_debug_printf ("[QEnvironmentHexEncoded received '%s']", p);
      remote_debug_printf ("[Environment variable to be set: '%s']",
			   final_var.c_str ());

      size_t pos = final_var.find ('=');
      if (pos == std::string::npos)
	{
	  warning (_("Unexpected format for environment variable: '%s'"),
		   final_var.c_str ());
	  write_enn (own_buf);
	  return;
	}

      var_name = final_var.substr (0, pos);
      var_value = final_var.substr (pos + 1, std::string::npos);

      our_environ.set (var_name.c_str (), var_value.c_str ());

      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QEnvironmentUnset:"))
    {
      const char *p = own_buf + sizeof ("QEnvironmentUnset:") - 1;
      std::string varname = hex2str (p);

      remote_debug_printf ("[QEnvironmentUnset received '%s']", p);
      remote_debug_printf ("[Environment variable to be unset: '%s']",
			   varname.c_str ());

      our_environ.unset (varname.c_str ());

      write_ok (own_buf);
      return;
    }

  if (strcmp (own_buf, "QStartNoAckMode") == 0)
    {
      remote_debug_printf ("[noack mode enabled]");

      cs.noack_mode = 1;
      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QNonStop:"))
    {
      char *mode = own_buf + 9;
      int req = -1;
      const char *req_str;

      if (strcmp (mode, "0") == 0)
	req = 0;
      else if (strcmp (mode, "1") == 0)
	req = 1;
      else
	{
	  /* We don't know what this mode is, so complain to
	     GDB.  */
	  fprintf (stderr, "Unknown non-stop mode requested: %s\n",
		   own_buf);
	  write_enn (own_buf);
	  return;
	}

      req_str = req ? "non-stop" : "all-stop";
      if (the_target->start_non_stop (req == 1) != 0)
	{
	  fprintf (stderr, "Setting %s mode failed\n", req_str);
	  write_enn (own_buf);
	  return;
	}

      non_stop = (req != 0);

      remote_debug_printf ("[%s mode enabled]", req_str);

      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QDisableRandomization:"))
    {
      char *packet = own_buf + strlen ("QDisableRandomization:");
      ULONGEST setting;

      unpack_varlen_hex (packet, &setting);
      cs.disable_randomization = setting;

      remote_debug_printf (cs.disable_randomization
			   ? "[address space randomization disabled]"
			       : "[address space randomization enabled]");

      write_ok (own_buf);
      return;
    }

  if (target_supports_tracepoints ()
      && handle_tracepoint_general_set (own_buf))
    return;

  if (startswith (own_buf, "QAgent:"))
    {
      char *mode = own_buf + strlen ("QAgent:");
      int req = 0;

      if (strcmp (mode, "0") == 0)
	req = 0;
      else if (strcmp (mode, "1") == 0)
	req = 1;
      else
	{
	  /* We don't know what this value is, so complain to GDB.  */
	  sprintf (own_buf, "E.Unknown QAgent value");
	  return;
	}

      /* Update the flag.  */
      use_agent = req;
      remote_debug_printf ("[%s agent]", req ? "Enable" : "Disable");
      write_ok (own_buf);
      return;
    }

  if (handle_btrace_general_set (own_buf))
    return;

  if (handle_btrace_conf_general_set (own_buf))
    return;

  if (startswith (own_buf, "QThreadEvents:"))
    {
      char *mode = own_buf + strlen ("QThreadEvents:");
      enum tribool req = TRIBOOL_UNKNOWN;

      if (strcmp (mode, "0") == 0)
	req = TRIBOOL_FALSE;
      else if (strcmp (mode, "1") == 0)
	req = TRIBOOL_TRUE;
      else
	{
	  /* We don't know what this mode is, so complain to GDB.  */
	  std::string err
	    = string_printf ("E.Unknown thread-events mode requested: %s\n",
			     mode);
	  strcpy (own_buf, err.c_str ());
	  return;
	}

      cs.report_thread_events = (req == TRIBOOL_TRUE);

      remote_debug_printf ("[thread events are now %s]\n",
			   cs.report_thread_events ? "enabled" : "disabled");

      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QThreadOptions;"))
    {
      const char *p = own_buf + strlen ("QThreadOptions");

      gdb_thread_options supported_options = target_supported_thread_options ();
      if (supported_options == 0)
	{
	  /* Something went wrong -- we don't support any option, but
	     GDB sent the packet anyway.  */
	  write_enn (own_buf);
	  return;
	}

      /* We could store the options directly in thread->thread_options
	 without this map, but that would mean that a QThreadOptions
	 packet with a wildcard like "QThreadOptions;0;3:TID" would
	 result in the debug logs showing:

	   [options for TID are now 0x0]
	   [options for TID are now 0x3]

	 It's nicer if we only print the final options for each TID,
	 and if we only print about it if the options changed compared
	 to the options that were previously set on the thread.  */
      gdb::unordered_map<thread_info *, gdb_thread_options> set_options;

      while (*p != '\0')
	{
	  if (p[0] != ';')
	    {
	      write_enn (own_buf);
	      return;
	    }
	  p++;

	  /* Read the options.  */

	  gdb_thread_options options = parse_gdb_thread_options (&p);

	  if ((options & ~supported_options) != 0)
	    {
	      /* GDB asked for an unknown or unsupported option, so
		 error out.  */
	      std::string err
		= string_printf ("E.Unknown thread options requested: %s\n",
				 to_string (options).c_str ());
	      strcpy (own_buf, err.c_str ());
	      return;
	    }

	  ptid_t ptid;

	  if (p[0] == ';' || p[0] == '\0')
	    ptid = minus_one_ptid;
	  else if (p[0] == ':')
	    {
	      const char *q;

	      ptid = read_ptid (p + 1, &q);

	      if (p == q)
		{
		  write_enn (own_buf);
		  return;
		}
	      p = q;
	      if (p[0] != ';' && p[0] != '\0')
		{
		  write_enn (own_buf);
		  return;
		}
	    }
	  else
	    {
	      write_enn (own_buf);
	      return;
	    }

	  /* Convert PID.-1 => PID.0 for ptid.matches.  */
	  if (ptid.lwp () == -1)
	    ptid = ptid_t (ptid.pid ());

	  for_each_thread ([&] (thread_info *thread)
	    {
	      if (thread->id.matches (ptid))
		set_options[thread] = options;
	    });
	}

      for (const auto &[thread, options] : set_options)
	if (thread->thread_options != options)
	  {
	    threads_debug_printf ("[options for %s are now %s]\n",
				  target_pid_to_str (thread->id).c_str (),
				  to_string (options).c_str ());

	    thread->thread_options = options;
	  }

      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QStartupWithShell:"))
    {
      const char *value = own_buf + strlen ("QStartupWithShell:");

      if (strcmp (value, "1") == 0)
	startup_with_shell = true;
      else if (strcmp (value, "0") == 0)
	startup_with_shell = false;
      else
	{
	  /* Unknown value.  */
	  fprintf (stderr, "Unknown value to startup-with-shell: %s\n",
		   own_buf);
	  write_enn (own_buf);
	  return;
	}

      remote_debug_printf ("[Inferior will %s started with shell]",
			   startup_with_shell ? "be" : "not be");

      write_ok (own_buf);
      return;
    }

  if (startswith (own_buf, "QSetWorkingDir:"))
    {
      const char *p = own_buf + strlen ("QSetWorkingDir:");

      if (*p != '\0')
	{
	  std::string path = hex2str (p);

	  remote_debug_printf ("[Set the inferior's current directory to %s]",
			       path.c_str ());

	  set_inferior_cwd (std::move (path));
	}
      else
	{
	  /* An empty argument means that we should clear out any
	     previously set cwd for the inferior.  */
	  set_inferior_cwd ("");

	  remote_debug_printf ("[Unset the inferior's current directory; will "
			       "use gdbserver's cwd]");
	}
      write_ok (own_buf);

      return;
    }


  /* Handle store memory tags packets.  */
  if (startswith (own_buf, "QMemTags:")
      && target_supports_memory_tagging ())
    {
      gdb::byte_vector tags;
      CORE_ADDR addr = 0;
      size_t len = 0;
      int type = 0;

      require_running_or_return (own_buf);

      bool ret = parse_store_memtags_request (own_buf, &addr, &len, tags,
					     &type);

      if (ret)
	ret = the_target->store_memtags (addr, len, tags, type);

      if (!ret)
	write_enn (own_buf);
      else
	write_ok (own_buf);

      return;
    }

  /* Otherwise we didn't know what packet it was.  Say we didn't
     understand it.  */
  own_buf[0] = 0;
}

static const char *
get_features_xml (const char *annex)
{
  const struct target_desc *desc = current_target_desc ();

  /* `desc->xmltarget' defines what to return when looking for the
     "target.xml" file.  Its contents can either be verbatim XML code
     (prefixed with a '@') or else the name of the actual XML file to
     be used in place of "target.xml".

     This variable is set up from the auto-generated
     init_registers_... routine for the current target.  */

  if (strcmp (annex, "target.xml") == 0)
    {
      const char *ret = tdesc_get_features_xml (desc);

      if (*ret == '@')
	return ret + 1;
      else
	annex = ret;
    }

#ifdef USE_XML
  {
    int i;

    /* Look for the annex.  */
    for (i = 0; xml_builtin[i][0] != NULL; i++)
      if (strcmp (annex, xml_builtin[i][0]) == 0)
	break;

    if (xml_builtin[i][0] != NULL)
      return xml_builtin[i][1];
  }
#endif

  return NULL;
}

static void
monitor_show_help (void)
{
  monitor_output ("The following monitor commands are supported:\n");
  monitor_output ("  set debug on\n");
  monitor_output ("    Enable general debugging messages\n");
  monitor_output ("  set debug off\n");
  monitor_output ("    Disable all debugging messages\n");
  monitor_output ("  set debug COMPONENT <off|on>\n");
  monitor_output ("    Enable debugging messages for COMPONENT, which is\n");
  monitor_output ("    one of: all, threads, remote, event-loop.\n");
  monitor_output ("  set debug-hw-points <0|1>\n");
  monitor_output ("    Enable h/w breakpoint/watchpoint debugging messages\n");
  monitor_output ("  set debug-format option1[,option2,...]\n");
  monitor_output ("    Add additional information to debugging messages\n");
  monitor_output ("    Options: all, none, timestamp\n");
  monitor_output ("  exit\n");
  monitor_output ("    Quit GDBserver\n");
}

/* Read trace frame or inferior memory.  Returns the number of bytes
   actually read, zero when no further transfer is possible, and -1 on
   error.  Return of a positive value smaller than LEN does not
   indicate there's no more to be read, only the end of the transfer.
   E.g., when GDB reads memory from a traceframe, a first request may
   be served from a memory block that does not cover the whole request
   length.  A following request gets the rest served from either
   another block (of the same traceframe) or from the read-only
   regions.  */

static int
gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
  client_state &cs = get_client_state ();
  int res;

  if (cs.current_traceframe >= 0)
    {
      ULONGEST nbytes;
      ULONGEST length = len;

      if (traceframe_read_mem (cs.current_traceframe,
			       memaddr, myaddr, len, &nbytes))
	return -1;
      /* Data read from trace buffer, we're done.  */
      if (nbytes > 0)
	return nbytes;
      if (!in_readonly_region (memaddr, length))
	return -1;
      /* Otherwise we have a valid readonly case, fall through.  */
      /* (assume no half-trace half-real blocks for now) */
    }

  if (set_desired_process ())
    res = read_inferior_memory (memaddr, myaddr, len);
  else
    res = 1;

  return res == 0 ? len : -1;
}

/* Write trace frame or inferior memory.  Actually, writing to trace
   frames is forbidden.  */

static int
gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
  client_state &cs = get_client_state ();
  if (cs.current_traceframe >= 0)
    return EIO;
  else
    {
      int ret;

      if (set_desired_process ())
	ret = target_write_memory (memaddr, myaddr, len);
      else
	ret = EIO;
      return ret;
    }
}

/* Handle qSearch:memory packets.  */

static void
handle_search_memory (char *own_buf, int packet_len)
{
  CORE_ADDR start_addr;
  CORE_ADDR search_space_len;
  gdb_byte *pattern;
  unsigned int pattern_len;
  int found;
  CORE_ADDR found_addr;
  int cmd_name_len = sizeof ("qSearch:memory:") - 1;

  pattern = (gdb_byte *) malloc (packet_len);
  if (pattern == NULL)
    error ("Unable to allocate memory to perform the search");

  if (decode_search_memory_packet (own_buf + cmd_name_len,
				   packet_len - cmd_name_len,
				   &start_addr, &search_space_len,
				   pattern, &pattern_len) < 0)
    {
      free (pattern);
      error ("Error in parsing qSearch:memory packet");
    }

  auto read_memory = [] (CORE_ADDR addr, gdb_byte *result, size_t len)
    {
      return gdb_read_memory (addr, result, len) == len;
    };

  found = simple_search_memory (read_memory, start_addr, search_space_len,
				pattern, pattern_len, &found_addr);

  if (found > 0)
    sprintf (own_buf, "1,%lx", (long) found_addr);
  else if (found == 0)
    strcpy (own_buf, "0");
  else
    strcpy (own_buf, "E00");

  free (pattern);
}

/* Handle the "D" packet.  */

static void
handle_detach (char *own_buf)
{
  client_state &cs = get_client_state ();

  process_info *process;

  if (cs.multi_process)
    {
      /* skip 'D;' */
      int pid = strtol (&own_buf[2], NULL, 16);

      process = find_process_pid (pid);
    }
  else
    process = current_process ();

  if (process == NULL)
    {
      write_enn (own_buf);
      return;
    }

  if ((tracing && disconnected_tracing) || any_persistent_commands (process))
    {
      if (tracing && disconnected_tracing)
	fprintf (stderr,
		 "Disconnected tracing in effect, "
		 "leaving gdbserver attached to the process\n");

      if (any_persistent_commands (process))
	fprintf (stderr,
		 "Persistent commands are present, "
		 "leaving gdbserver attached to the process\n");

      /* Make sure we're in non-stop/async mode, so we we can both
	 wait for an async socket accept, and handle async target
	 events simultaneously.  There's also no point either in
	 having the target stop all threads, when we're going to
	 pass signals down without informing GDB.  */
      if (!non_stop)
	{
	  threads_debug_printf ("Forcing non-stop mode");

	  non_stop = true;
	  the_target->start_non_stop (true);
	}

      process->gdb_detached = 1;

      /* Detaching implicitly resumes all threads.  */
      target_continue_no_signal (minus_one_ptid);

      write_ok (own_buf);
      return;
    }

  fprintf (stderr, "Detaching from process %d\n", process->pid);
  stop_tracing ();

  /* We'll need this after PROCESS has been destroyed.  */
  int pid = process->pid;

  /* If this process has an unreported fork child, that child is not known to
     GDB, so GDB won't take care of detaching it.  We must do it here.

     Here, we specifically don't want to use "safe iteration", as detaching
     another process might delete the next thread in the iteration, which is
     the one saved by the safe iterator.  We will never delete the currently
     iterated on thread, so standard iteration should be safe.  */
  for (thread_info &thread : process->thread_list ())
    {
      /* Only threads that have a pending fork event.  */
      target_waitkind kind;
      thread_info *child = target_thread_pending_child (&thread, &kind);
      if (child == nullptr || kind == TARGET_WAITKIND_THREAD_CLONED)
	continue;

      process_info *fork_child_process = child->process ();
      int fork_child_pid = fork_child_process->pid;

      if (detach_inferior (fork_child_process) != 0)
	warning (_("Failed to detach fork child %s, child of %s"),
		 target_pid_to_str (ptid_t (fork_child_pid)).c_str (),
		 target_pid_to_str (thread.id).c_str ());
    }

  if (detach_inferior (process) != 0)
    write_enn (own_buf);
  else
    {
      discard_queued_stop_replies (ptid_t (pid));
      write_ok (own_buf);

      if (extended_protocol || target_running ())
	{
	  /* There is still at least one inferior remaining or
	     we are in extended mode, so don't terminate gdbserver,
	     and instead treat this like a normal program exit.  */
	  cs.last_status.set_exited (0);
	  cs.last_ptid = ptid_t (pid);

	  switch_to_thread (nullptr);
	}
      else
	{
	  putpkt (own_buf);
	  remote_close ();

	  /* If we are attached, then we can exit.  Otherwise, we
	     need to hang around doing nothing, until the child is
	     gone.  */
	  join_inferior (pid);
	  exit (0);
	}
    }
}

/* Parse options to --debug-format= and "monitor set debug-format".
   ARG is the text after "--debug-format=" or "monitor set debug-format".
   IS_MONITOR is non-zero if we're invoked via "monitor set debug-format".
   This triggers calls to monitor_output.
   The result is an empty string if all options were parsed ok, otherwise an
   error message which the caller must free.

   N.B. These commands affect all debug format settings, they are not
   cumulative.  If a format is not specified, it is turned off.
   However, we don't go to extra trouble with things like
   "monitor set debug-format all,none,timestamp".
   Instead we just parse them one at a time, in order.

   The syntax for "monitor set debug" we support here is not identical
   to gdb's "set debug foo on|off" because we also use this function to
   parse "--debug-format=foo,bar".  */

static std::string
parse_debug_format_options (const char *arg, int is_monitor)
{
  /* First turn all debug format options off.  */
  debug_timestamp = 0;

  /* First remove leading spaces, for "monitor set debug-format".  */
  while (c_isspace (*arg))
    ++arg;

  std::vector<gdb::unique_xmalloc_ptr<char>> options
    = delim_string_to_char_ptr_vec (arg, ',');

  for (const gdb::unique_xmalloc_ptr<char> &option : options)
    {
      if (strcmp (option.get (), "all") == 0)
	{
	  debug_timestamp = 1;
	  if (is_monitor)
	    monitor_output ("All extra debug format options enabled.\n");
	}
      else if (strcmp (option.get (), "none") == 0)
	{
	  debug_timestamp = 0;
	  if (is_monitor)
	    monitor_output ("All extra debug format options disabled.\n");
	}
      else if (strcmp (option.get (), "timestamp") == 0)
	{
	  debug_timestamp = 1;
	  if (is_monitor)
	    monitor_output ("Timestamps will be added to debug output.\n");
	}
      else if (*option == '\0')
	{
	  /* An empty option, e.g., "--debug-format=foo,,bar", is ignored.  */
	  continue;
	}
      else
	return string_printf ("Unknown debug-format argument: \"%s\"\n",
			      option.get ());
    }

  return std::string ();
}

/* A wrapper to enable, or disable a debug flag.  These are debug flags
   that control the debug output from gdbserver, that developers might
   want, this is not something most end users will need.  */

struct debug_opt
{
  /* NAME is the name of this debug option, this should be a simple string
     containing no whitespace, starting with a letter from c_isalpha(), and
     contain only c_isalnum() characters and '_' underscore and '-' hyphen.

     SETTER is a callback function used to set the debug variable.  This
     callback will be passed true to enable the debug setting, or false to
     disable the debug setting.  */
  debug_opt (const char *name, std::function<void (bool)> setter)
    : m_name (name),
      m_setter (setter)
  {
    gdb_assert (c_isalpha (*name));
  }

  /* Called to enable or disable the debug setting.  */
  void set (bool enable) const
  {
    m_setter (enable);
  }

  /* Return the name of this debug option.  */
  const char *name () const
  { return m_name; }

private:
  /* The name of this debug option.  */
  const char *m_name;

  /* The callback to update the debug setting.  */
  std::function<void (bool)> m_setter;
};

/* The set of all debug options that gdbserver supports.  These are the
   options that can be passed to the command line '--debug=...' flag, or to
   the monitor command 'monitor set debug ...'.  */

static std::vector<debug_opt> all_debug_opt {
  {"threads", [] (bool enable)
  {
    debug_threads = enable;
  }},
  {"remote", [] (bool enable)
  {
    remote_debug = enable;
  }},
  {"event-loop", [] (bool enable)
  {
    debug_event_loop = (enable ? debug_event_loop_kind::ALL
			: debug_event_loop_kind::OFF);
  }}
};

/* Parse the options to --debug=...

   OPTIONS is the string of debug components which should be enabled (or
   disabled), and must not be nullptr.  An empty OPTIONS string is valid,
   in which case a default set of debug components will be enabled.

   An unknown, or otherwise invalid debug component will result in an
   exception being thrown.

   OPTIONS can consist of multiple debug component names separated by a
   comma.  Debugging for each component will be turned on.  The special
   component 'all' can be used to enable debugging for all components.

   A component can also be prefixed with '-' to disable debugging of that
   component, so a user might use: '--debug=all,-remote', to enable all
   debugging, except for the remote (protocol) component.  Components are
   processed left to write in the OPTIONS list.  */

static void
parse_debug_options (const char *options)
{
  gdb_assert (options != nullptr);

  /* Empty options means the "default" set.  This exists mostly for
     backwards compatibility with gdbserver's legacy behavior.  */
  if (*options == '\0')
    options = "+threads";

  while (*options != '\0')
    {
      const char *end = strchrnul (options, ',');

      bool enable = *options != '-';
      if (*options == '-' || *options == '+')
	++options;

      std::string opt (options, end - options);

      if (opt.size () == 0)
	error ("invalid empty debug option");

      bool is_opt_all = opt == "all";

      bool found = false;
      for (const auto &debug_opt : all_debug_opt)
	if (is_opt_all || opt == debug_opt.name ())
	  {
	    debug_opt.set (enable);
	    found = true;
	    if (!is_opt_all)
	      break;
	  }

      if (!found)
	error ("unknown debug option '%s'", opt.c_str ());

      options = (*end == ',') ? end + 1 : end;
    }
}

/* Called from the 'monitor' command handler, to handle general 'set debug'
   monitor commands with one of the formats:

     set debug COMPONENT VALUE
     set debug VALUE

   In both of these command formats VALUE can be 'on', 'off', '1', or '0'
   with 1/0 being equivalent to on/off respectively.

   In the no-COMPONENT version of the command, if VALUE is 'on' (or '1')
   then the component 'threads' is assumed, this is for backward
   compatibility, but maybe in the future we might find a better "default"
   set of debug flags to enable.

   In the no-COMPONENT version of the command, if VALUE is 'off' (or '0')
   then all debugging is turned off.

   Otherwise, COMPONENT must be one of the known debug components, and that
   component is either enabled or disabled as appropriate.

   The string MON contains either 'COMPONENT VALUE' or just the 'VALUE' for
   the second command format, the 'set debug ' has been stripped off
   already.

   Return a string containing an error message if something goes wrong,
   this error can be returned as part of the monitor command output.  If
   everything goes correctly then the debug global will have been updated,
   and an empty string is returned.  */

static std::string
handle_general_monitor_debug (const char *mon)
{
  mon = skip_spaces (mon);

  if (*mon == '\0')
    return "No debug component name found.\n";

  /* Find the first word within MON.  This is either the component name,
     or the value if no component has been given.  */
  const char *end = skip_to_space (mon);
  std::string component (mon, end - mon);
  if (component.find (',') != component.npos || component[0] == '-'
      || component[0] == '+')
    return "Invalid character found in debug component name.\n";

  /* In ACTION_STR we create a string that will be passed to the
     parse_debug_options string.  This will be either '+COMPONENT' or
     '-COMPONENT' depending on whether we want to enable or disable
     COMPONENT.  */
  std::string action_str;

  /* If parse_debug_options succeeds, then MSG will be returned to the user
     as the output of the monitor command.  */
  std::string msg;

  /* Check for 'set debug off', this disables all debug output.  */
  if (component == "0" || component == "off")
    {
      if (*skip_spaces (end) != '\0')
	return string_printf
	  ("Junk '%s' found at end of 'set debug %s' command.\n",
	   skip_spaces (end), std::string (mon, end - mon).c_str ());

      action_str = "-all";
      msg = "All debug output disabled.\n";
    }
  /* Check for 'set debug on', this disables a general set of debug.  */
  else if (component == "1" || component == "on")
    {
      if (*skip_spaces (end) != '\0')
	return string_printf
	  ("Junk '%s' found at end of 'set debug %s' command.\n",
	   skip_spaces (end), std::string (mon, end - mon).c_str ());

      action_str = "+threads";
      msg = "General debug output enabled.\n";
    }
  /* Otherwise we should have 'set debug COMPONENT VALUE'.  Extract the two
     parts and validate.  */
  else
    {
      /* Figure out the value the user passed.  */
      const char *value_start = skip_spaces (end);
      if (*value_start == '\0')
	return string_printf ("Missing value for 'set debug %s' command.\n",
			      mon);

      const char *after_value = skip_to_space (value_start);
      if (*skip_spaces (after_value) != '\0')
	return string_printf
	  ("Junk '%s' found at end of 'set debug %s' command.\n",
	   skip_spaces (after_value),
	   std::string (mon, after_value - mon).c_str ());

      std::string value (value_start, after_value - value_start);

      /* Check VALUE to see if we are enabling, or disabling.  */
      bool enable;
      if (value == "0" || value == "off")
	enable = false;
      else if (value == "1" || value == "on")
	enable = true;
      else
	return string_printf ("Invalid value '%s' for 'set debug %s'.\n",
			      value.c_str (),
			      std::string (mon, end - mon).c_str ());

      action_str = std::string (enable ? "+" : "-") + component;
      msg = string_printf ("Debug output for '%s' %s.\n", component.c_str (),
			   enable ? "enabled" : "disabled");
    }

  gdb_assert (!msg.empty ());
  gdb_assert (!action_str.empty ());

  try
    {
      parse_debug_options (action_str.c_str ());
      monitor_output (msg.c_str ());
    }
  catch (const gdb_exception_error &exception)
    {
      return string_printf ("Error: %s\n", exception.what ());
    }

  return {};
}

/* Handle monitor commands not handled by target-specific handlers.  */

static void
handle_monitor_command (char *mon, char *own_buf)
{
  if (startswith (mon, "set debug "))
    {
      std::string error_msg
	= handle_general_monitor_debug (mon + sizeof ("set debug ") - 1);

      if (!error_msg.empty ())
	{
	  monitor_output (error_msg.c_str ());
	  monitor_show_help ();
	  write_enn (own_buf);
	}
    }
  else if (strcmp (mon, "set debug-hw-points 1") == 0)
    {
      show_debug_regs = 1;
      monitor_output ("H/W point debugging output enabled.\n");
    }
  else if (strcmp (mon, "set debug-hw-points 0") == 0)
    {
      show_debug_regs = 0;
      monitor_output ("H/W point debugging output disabled.\n");
    }
  else if (startswith (mon, "set debug-format "))
    {
      std::string error_msg
	= parse_debug_format_options (mon + sizeof ("set debug-format ") - 1,
				      1);

      if (!error_msg.empty ())
	{
	  monitor_output (error_msg.c_str ());
	  monitor_show_help ();
	  write_enn (own_buf);
	}
    }
  else if (strcmp (mon, "set debug-file") == 0)
    debug_set_output (nullptr);
  else if (startswith (mon, "set debug-file "))
    debug_set_output (mon + sizeof ("set debug-file ") - 1);
  else if (strcmp (mon, "help") == 0)
    monitor_show_help ();
  else if (strcmp (mon, "exit") == 0)
    exit_requested = true;
  else
    {
      monitor_output ("Unknown monitor command.\n\n");
      monitor_show_help ();
      write_enn (own_buf);
    }
}

/* Associates a callback with each supported qXfer'able object.  */

struct qxfer
{
  /* The object this handler handles.  */
  const char *object;

  /* Request that the target transfer up to LEN 8-bit bytes of the
     target's OBJECT.  The OFFSET, for a seekable object, specifies
     the starting point.  The ANNEX can be used to provide additional
     data-specific information to the target.

     Return the number of bytes actually transferred, zero when no
     further transfer is possible, -1 on error, -2 when the transfer
     is not supported, and -3 on a verbose error message that should
     be preserved.  Return of a positive value smaller than LEN does
     not indicate the end of the object, only the end of the transfer.

     One, and only one, of readbuf or writebuf must be non-NULL.  */
  int (*xfer) (const char *annex,
	       gdb_byte *readbuf, const gdb_byte *writebuf,
	       ULONGEST offset, LONGEST len);
};

/* Handle qXfer:auxv:read.  */

static int
handle_qxfer_auxv (const char *annex,
		   gdb_byte *readbuf, const gdb_byte *writebuf,
		   ULONGEST offset, LONGEST len)
{
  if (!the_target->supports_read_auxv () || writebuf != NULL)
    return -2;

  if (annex[0] != '\0' || current_thread == NULL)
    return -1;

  return the_target->read_auxv (current_thread->id.pid (), offset, readbuf,
				len);
}

/* Handle qXfer:exec-file:read.  */

static int
handle_qxfer_exec_file (const char *annex,
			gdb_byte *readbuf, const gdb_byte *writebuf,
			ULONGEST offset, LONGEST len)
{
  ULONGEST pid;
  int total_len;

  if (!the_target->supports_pid_to_exec_file () || writebuf != NULL)
    return -2;

  if (annex[0] == '\0')
    {
      if (current_thread == NULL)
	return -1;

      pid = current_thread->id.pid ();
    }
  else
    {
      annex = unpack_varlen_hex (annex, &pid);
      if (annex[0] != '\0')
	return -1;
    }

  if (pid <= 0)
    return -1;

  const char *file = the_target->pid_to_exec_file (pid);
  if (file == NULL)
    return -1;

  total_len = strlen (file);

  if (offset > total_len)
    return -1;

  if (offset + len > total_len)
    len = total_len - offset;

  memcpy (readbuf, file + offset, len);
  return len;
}

/* Handle qXfer:features:read.  */

static int
handle_qxfer_features (const char *annex,
		       gdb_byte *readbuf, const gdb_byte *writebuf,
		       ULONGEST offset, LONGEST len)
{
  const char *document;
  size_t total_len;

  if (writebuf != NULL)
    return -2;

  if (!target_running ())
    return -1;

  /* Grab the correct annex.  */
  document = get_features_xml (annex);
  if (document == NULL)
    return -1;

  total_len = strlen (document);

  if (offset > total_len)
    return -1;

  if (offset + len > total_len)
    len = total_len - offset;

  memcpy (readbuf, document + offset, len);
  return len;
}

/* Handle qXfer:libraries:read.  */

static int
handle_qxfer_libraries (const char *annex,
			gdb_byte *readbuf, const gdb_byte *writebuf,
			ULONGEST offset, LONGEST len)
{
  if (writebuf != NULL)
    return -2;

  if (annex[0] != '\0' || current_thread == NULL)
    return -1;

  std::string document = "<library-list version=\"1.0\">\n";

  process_info *proc = current_process ();
  for (const dll_info &dll : proc->all_dlls)
    document += string_printf
      ("  <library name=\"%s\"><segment address=\"0x%s\"/></library>\n",
       dll.name.c_str (), paddress (dll.base_addr));

  document += "</library-list>\n";

  if (offset > document.length ())
    return -1;

  if (offset + len > document.length ())
    len = document.length () - offset;

  memcpy (readbuf, &document[offset], len);

  return len;
}

/* Handle qXfer:libraries-svr4:read.  */

static int
handle_qxfer_libraries_svr4 (const char *annex,
			     gdb_byte *readbuf, const gdb_byte *writebuf,
			     ULONGEST offset, LONGEST len)
{
  if (writebuf != NULL)
    return -2;

  if (current_thread == NULL
      || !the_target->supports_qxfer_libraries_svr4 ())
    return -1;

  return the_target->qxfer_libraries_svr4 (annex, readbuf, writebuf,
					   offset, len);
}

/* Handle qXfer:osadata:read.  */

static int
handle_qxfer_osdata (const char *annex,
		     gdb_byte *readbuf, const gdb_byte *writebuf,
		     ULONGEST offset, LONGEST len)
{
  if (!the_target->supports_qxfer_osdata () || writebuf != NULL)
    return -2;

  return the_target->qxfer_osdata (annex, readbuf, NULL, offset, len);
}

/* Handle qXfer:siginfo:read and qXfer:siginfo:write.  */

static int
handle_qxfer_siginfo (const char *annex,
		      gdb_byte *readbuf, const gdb_byte *writebuf,
		      ULONGEST offset, LONGEST len)
{
  if (!the_target->supports_qxfer_siginfo ())
    return -2;

  if (annex[0] != '\0' || current_thread == NULL)
    return -1;

  return the_target->qxfer_siginfo (annex, readbuf, writebuf, offset, len);
}

/* Helper for handle_qxfer_threads_proper.
   Emit the XML to describe the thread of INF.  */

static void
handle_qxfer_threads_worker (thread_info *thread, std::string *buffer)
{
  ptid_t ptid = thread->id;
  char ptid_s[100];
  int core = target_core_of_thread (ptid);
  char core_s[21];
  const char *name = target_thread_name (ptid);
  std::string id_str = target_thread_id_str (thread);
  int handle_len;
  gdb_byte *handle;
  bool handle_status = target_thread_handle (ptid, &handle, &handle_len);

  /* If this is a (v)fork/clone child (has a (v)fork/clone parent),
     GDB does not yet know about this thread, and must not know about
     it until it gets the corresponding (v)fork/clone event.  Exclude
     this thread from the list.  */
  if (target_thread_pending_parent (thread) != nullptr)
    return;

  write_ptid (ptid_s, ptid);

  string_xml_appendf (*buffer, "<thread id=\"%s\"", ptid_s);

  if (core != -1)
    {
      sprintf (core_s, "%d", core);
      string_xml_appendf (*buffer, " core=\"%s\"", core_s);
    }

  if (name != NULL)
    string_xml_appendf (*buffer, " name=\"%s\"", name);

  if (!id_str.empty ())
    string_xml_appendf (*buffer, " id_str=\"%s\"", id_str.c_str ());

  if (handle_status)
    {
      char *handle_s = (char *) alloca (handle_len * 2 + 1);
      bin2hex (handle, handle_s, handle_len);
      string_xml_appendf (*buffer, " handle=\"%s\"", handle_s);
    }

  string_xml_appendf (*buffer, "/>\n");
}

/* Helper for handle_qxfer_threads.  Return true on success, false
   otherwise.  */

static bool
handle_qxfer_threads_proper (std::string *buffer)
{
  *buffer += "<threads>\n";

  /* The target may need to access memory and registers (e.g. via
     libthread_db) to fetch thread properties.  Even if don't need to
     stop threads to access memory, we still will need to be able to
     access registers, and other ptrace accesses like
     PTRACE_GET_THREAD_AREA that require a paused thread.  Pause all
     threads here, so that we pause each thread at most once for all
     accesses.  */
  if (non_stop)
    target_pause_all (true);

  for_each_thread ([&] (thread_info *thread)
    {
      handle_qxfer_threads_worker (thread, buffer);
    });

  if (non_stop)
    target_unpause_all (true);

  *buffer += "</threads>\n";
  return true;
}

/* Handle qXfer:threads:read.  */

static int
handle_qxfer_threads (const char *annex,
		      gdb_byte *readbuf, const gdb_byte *writebuf,
		      ULONGEST offset, LONGEST len)
{
  static std::string result;

  if (writebuf != NULL)
    return -2;

  if (annex[0] != '\0')
    return -1;

  if (offset == 0)
    {
      /* When asked for data at offset 0, generate everything and store into
	 'result'.  Successive reads will be served off 'result'.  */
      result.clear ();

      bool res = handle_qxfer_threads_proper (&result);

      if (!res)
	return -1;
    }

  if (offset >= result.length ())
    {
      /* We're out of data.  */
      result.clear ();
      return 0;
    }

  if (len > result.length () - offset)
    len = result.length () - offset;

  memcpy (readbuf, result.c_str () + offset, len);

  return len;
}

/* Handle qXfer:traceframe-info:read.  */

static int
handle_qxfer_traceframe_info (const char *annex,
			      gdb_byte *readbuf, const gdb_byte *writebuf,
			      ULONGEST offset, LONGEST len)
{
  client_state &cs = get_client_state ();
  static std::string result;

  if (writebuf != NULL)
    return -2;

  if (!target_running () || annex[0] != '\0' || cs.current_traceframe == -1)
    return -1;

  if (offset == 0)
    {
      /* When asked for data at offset 0, generate everything and
	 store into 'result'.  Successive reads will be served off
	 'result'.  */
      result.clear ();

      traceframe_read_info (cs.current_traceframe, &result);
    }

  if (offset >= result.length ())
    {
      /* We're out of data.  */
      result.clear ();
      return 0;
    }

  if (len > result.length () - offset)
    len = result.length () - offset;

  memcpy (readbuf, result.c_str () + offset, len);
  return len;
}

/* Handle qXfer:fdpic:read.  */

static int
handle_qxfer_fdpic (const char *annex, gdb_byte *readbuf,
		    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
  if (!the_target->supports_read_loadmap ())
    return -2;

  if (current_thread == NULL)
    return -1;

  return the_target->read_loadmap (annex, offset, readbuf, len);
}

/* Handle qXfer:btrace:read.  */

static int
handle_qxfer_btrace (const char *annex,
		     gdb_byte *readbuf, const gdb_byte *writebuf,
		     ULONGEST offset, LONGEST len)
{
  client_state &cs = get_client_state ();
  static std::string cache;
  thread_info *thread;
  enum btrace_read_type type;
  int result;

  if (writebuf != NULL)
    return -2;

  if (cs.general_thread == null_ptid
      || cs.general_thread == minus_one_ptid)
    {
      strcpy (cs.own_buf, "E.Must select a single thread.");
      return -3;
    }

  thread = find_thread_ptid (cs.general_thread);
  if (thread == NULL)
    {
      strcpy (cs.own_buf, "E.No such thread.");
      return -3;
    }

  if (thread->btrace == NULL)
    {
      strcpy (cs.own_buf, "E.Btrace not enabled.");
      return -3;
    }

  if (strcmp (annex, "all") == 0)
    type = BTRACE_READ_ALL;
  else if (strcmp (annex, "new") == 0)
    type = BTRACE_READ_NEW;
  else if (strcmp (annex, "delta") == 0)
    type = BTRACE_READ_DELTA;
  else
    {
      strcpy (cs.own_buf, "E.Bad annex.");
      return -3;
    }

  if (offset == 0)
    {
      cache.clear ();

      try
	{
	  result = target_read_btrace (thread->btrace, &cache, type);
	  if (result != 0)
	    memcpy (cs.own_buf, cache.c_str (), cache.length ());
	}
      catch (const gdb_exception_error &exception)
	{
	  sprintf (cs.own_buf, "E.%s", exception.what ());
	  result = -1;
	}

      if (result != 0)
	return -3;
    }
  else if (offset > cache.length ())
    {
      cache.clear ();
      return -3;
    }

  if (len > cache.length () - offset)
    len = cache.length () - offset;

  memcpy (readbuf, cache.c_str () + offset, len);

  return len;
}

/* Handle qXfer:btrace-conf:read.  */

static int
handle_qxfer_btrace_conf (const char *annex,
			  gdb_byte *readbuf, const gdb_byte *writebuf,
			  ULONGEST offset, LONGEST len)
{
  client_state &cs = get_client_state ();
  static std::string cache;
  thread_info *thread;
  int result;

  if (writebuf != NULL)
    return -2;

  if (annex[0] != '\0')
    return -1;

  if (cs.general_thread == null_ptid
      || cs.general_thread == minus_one_ptid)
    {
      strcpy (cs.own_buf, "E.Must select a single thread.");
      return -3;
    }

  thread = find_thread_ptid (cs.general_thread);
  if (thread == NULL)
    {
      strcpy (cs.own_buf, "E.No such thread.");
      return -3;
    }

  if (thread->btrace == NULL)
    {
      strcpy (cs.own_buf, "E.Btrace not enabled.");
      return -3;
    }

  if (offset == 0)
    {
      cache.clear ();

      try
	{
	  result = target_read_btrace_conf (thread->btrace, &cache);
	  if (result != 0)
	    memcpy (cs.own_buf, cache.c_str (), cache.length ());
	}
      catch (const gdb_exception_error &exception)
	{
	  sprintf (cs.own_buf, "E.%s", exception.what ());
	  result = -1;
	}

      if (result != 0)
	return -3;
    }
  else if (offset > cache.length ())
    {
      cache.clear ();
      return -3;
    }

  if (len > cache.length () - offset)
    len = cache.length () - offset;

  memcpy (readbuf, cache.c_str () + offset, len);

  return len;
}

static const struct qxfer qxfer_packets[] =
  {
    { "auxv", handle_qxfer_auxv },
    { "btrace", handle_qxfer_btrace },
    { "btrace-conf", handle_qxfer_btrace_conf },
    { "exec-file", handle_qxfer_exec_file},
    { "fdpic", handle_qxfer_fdpic},
    { "features", handle_qxfer_features },
    { "libraries", handle_qxfer_libraries },
    { "libraries-svr4", handle_qxfer_libraries_svr4 },
    { "osdata", handle_qxfer_osdata },
    { "siginfo", handle_qxfer_siginfo },
    { "threads", handle_qxfer_threads },
    { "traceframe-info", handle_qxfer_traceframe_info },
  };

static int
handle_qxfer (char *own_buf, int packet_len, int *new_packet_len_p)
{
  int i;
  char *object;
  char *rw;
  char *annex;
  char *offset;

  if (!startswith (own_buf, "qXfer:"))
    return 0;

  /* Grab the object, r/w and annex.  */
  if (decode_xfer (own_buf + 6, &object, &rw, &annex, &offset) < 0)
    {
      write_enn (own_buf);
      return 1;
    }

  for (i = 0;
       i < sizeof (qxfer_packets) / sizeof (qxfer_packets[0]);
       i++)
    {
      const struct qxfer *q = &qxfer_packets[i];

      if (strcmp (object, q->object) == 0)
	{
	  if (strcmp (rw, "read") == 0)
	    {
	      unsigned char *data;
	      int n;
	      CORE_ADDR ofs;
	      unsigned int len;

	      /* Grab the offset and length.  */
	      if (decode_xfer_read (offset, &ofs, &len) < 0)
		{
		  write_enn (own_buf);
		  return 1;
		}

	      /* Read one extra byte, as an indicator of whether there is
		 more.  */
	      if (len > PBUFSIZ - 2)
		len = PBUFSIZ - 2;
	      data = (unsigned char *) malloc (len + 1);
	      if (data == NULL)
		{
		  write_enn (own_buf);
		  return 1;
		}
	      n = (*q->xfer) (annex, data, NULL, ofs, len + 1);
	      if (n == -2)
		{
		  free (data);
		  return 0;
		}
	      else if (n == -3)
		{
		  /* Preserve error message.  */
		}
	      else if (n < 0)
		write_enn (own_buf);
	      else if (n > len)
		*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
	      else
		*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);

	      free (data);
	      return 1;
	    }
	  else if (strcmp (rw, "write") == 0)
	    {
	      int n;
	      unsigned int len;
	      CORE_ADDR ofs;
	      unsigned char *data;

	      strcpy (own_buf, "E00");
	      data = (unsigned char *) malloc (packet_len - (offset - own_buf));
	      if (data == NULL)
		{
		  write_enn (own_buf);
		  return 1;
		}
	      if (decode_xfer_write (offset, packet_len - (offset - own_buf),
				     &ofs, &len, data) < 0)
		{
		  free (data);
		  write_enn (own_buf);
		  return 1;
		}

	      n = (*q->xfer) (annex, NULL, data, ofs, len);
	      if (n == -2)
		{
		  free (data);
		  return 0;
		}
	      else if (n == -3)
		{
		  /* Preserve error message.  */
		}
	      else if (n < 0)
		write_enn (own_buf);
	      else
		sprintf (own_buf, "%x", n);

	      free (data);
	      return 1;
	    }

	  return 0;
	}
    }

  return 0;
}

/* Compute 32 bit CRC from inferior memory.

   On success, return 32 bit CRC.
   On failure, return (unsigned long long) -1.  */

static unsigned long long
crc32 (CORE_ADDR base, int len, unsigned int crc)
{
  while (len--)
    {
      unsigned char byte = 0;

      /* Return failure if memory read fails.  */
      if (read_inferior_memory (base, &byte, 1) != 0)
	return (unsigned long long) -1;

      crc = xcrc32 (&byte, 1, crc);
      base++;
    }
  return (unsigned long long) crc;
}

/* Parse the qMemTags packet request into ADDR and LEN.  */

static void
parse_fetch_memtags_request (char *request, CORE_ADDR *addr, size_t *len,
			     int *type)
{
  gdb_assert (startswith (request, "qMemTags:"));

  const char *p = request + strlen ("qMemTags:");

  /* Read address and length.  */
  unsigned int length = 0;
  p = decode_m_packet_params (p, addr, &length, ':');
  *len = length;

  /* Read the tag type.  */
  ULONGEST tag_type = 0;
  p = unpack_varlen_hex (p, &tag_type);
  *type = (int) tag_type;
}

/* Add supported btrace packets to BUF.  */

static void
supported_btrace_packets (char *buf)
{
  strcat (buf, ";Qbtrace:bts+");
  strcat (buf, ";Qbtrace-conf:bts:size+");
  strcat (buf, ";Qbtrace:pt+");
  strcat (buf, ";Qbtrace-conf:pt:size+");
  strcat (buf, ";Qbtrace-conf:pt:ptwrite+");
  strcat (buf, ";Qbtrace-conf:pt:event-tracing+");
  strcat (buf, ";Qbtrace:off+");
  strcat (buf, ";qXfer:btrace:read+");
  strcat (buf, ";qXfer:btrace-conf:read+");
}

/* Handle all of the extended 'q' packets.  */

static void
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
  client_state &cs = get_client_state ();
  static owning_intrusive_list<process_info>::iterator process_iter;
  static owning_intrusive_list<thread_info>::iterator thread_iter;

  auto init_thread_iter = [&] ()
    {
      process_iter = all_processes.begin ();
      owning_intrusive_list<thread_info> *thread_list;

      for (; process_iter != all_processes.end (); ++process_iter)
	{
	  thread_list = &process_iter->thread_list ();
	  thread_iter = thread_list->begin ();
	  if (thread_iter != thread_list->end ())
	    break;
	}
      /* Make sure that there is at least one thread to iterate.  */
      gdb_assert (process_iter != all_processes.end ());
      gdb_assert (thread_iter != thread_list->end ());
    };

  auto advance_thread_iter = [&] ()
    {
      /* The loop below is written in the natural way as-if we'd always
	 start at the beginning of the inferior list.  This fast forwards
	 the algorithm to the actual current position.  */
      owning_intrusive_list<thread_info> *thread_list
	= &process_iter->thread_list ();
      goto start;

      for (; process_iter != all_processes.end (); ++process_iter)
	{
	  thread_list = &process_iter->thread_list ();
	  thread_iter = thread_list->begin ();
	  while (thread_iter != thread_list->end ())
	    {
	      return;
	    start:
	      ++thread_iter;
	    }
	}
    };

  /* Reply the current thread id.  */
  if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
    {
      ptid_t ptid;
      require_running_or_return (own_buf);

      if (cs.general_thread != null_ptid && cs.general_thread != minus_one_ptid)
	ptid = cs.general_thread;
      else
	{
	  init_thread_iter ();
	  ptid = thread_iter->id;
	}

      sprintf (own_buf, "QC");
      own_buf += 2;
      write_ptid (own_buf, ptid);
      return;
    }

  if (strcmp ("qSymbol::", own_buf) == 0)
    {
      scoped_restore_current_thread restore_thread;

      /* For qSymbol, GDB only changes the current thread if the
	 previous current thread was of a different process.  So if
	 the previous thread is gone, we need to pick another one of
	 the same process.  This can happen e.g., if we followed an
	 exec in a non-leader thread.  */
      if (current_thread == NULL)
	{
	  thread_info *any_thread
	    = find_any_thread_of_pid (cs.general_thread.pid ());
	  switch_to_thread (any_thread);

	  /* Just in case, if we didn't find a thread, then bail out
	     instead of crashing.  */
	  if (current_thread == NULL)
	    {
	      write_enn (own_buf);
	      return;
	    }
	}

      /* GDB is suggesting new symbols have been loaded.  This may
	 mean a new shared library has been detected as loaded, so
	 take the opportunity to check if breakpoints we think are
	 inserted, still are.  Note that it isn't guaranteed that
	 we'll see this when a shared library is loaded, and nor will
	 we see this for unloads (although breakpoints in unloaded
	 libraries shouldn't trigger), as GDB may not find symbols for
	 the library at all.  We also re-validate breakpoints when we
	 see a second GDB breakpoint for the same address, and or when
	 we access breakpoint shadows.  */
      validate_breakpoints ();

      if (target_supports_tracepoints ())
	tracepoint_look_up_symbols ();

      if (current_thread != NULL)
	the_target->look_up_symbols ();

      strcpy (own_buf, "OK");
      return;
    }

  if (!disable_packet_qfThreadInfo)
    {
      if (strcmp ("qfThreadInfo", own_buf) == 0)
	{
	  require_running_or_return (own_buf);
	  init_thread_iter ();

	  *own_buf++ = 'm';
	  ptid_t ptid = thread_iter->id;
	  write_ptid (own_buf, ptid);
	  advance_thread_iter ();
	  return;
	}

      if (strcmp ("qsThreadInfo", own_buf) == 0)
	{
	  require_running_or_return (own_buf);
	  /* We're done if the process iterator hits the end of the
	     process list.  */
	  if (process_iter != all_processes.end ())
	    {
	      *own_buf++ = 'm';
	      ptid_t ptid = thread_iter->id;
	      write_ptid (own_buf, ptid);
	      advance_thread_iter ();
	      return;
	    }
	  else
	    {
	      sprintf (own_buf, "l");
	      return;
	    }
	}
    }

  if (the_target->supports_read_offsets ()
      && strcmp ("qOffsets", own_buf) == 0)
    {
      CORE_ADDR text, data;

      require_running_or_return (own_buf);
      if (the_target->read_offsets (&text, &data))
	sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
		 (long)text, (long)data, (long)data);
      else
	write_enn (own_buf);

      return;
    }

  /* Protocol features query.  */
  if (startswith (own_buf, "qSupported")
      && (own_buf[10] == ':' || own_buf[10] == '\0'))
    {
      char *p = &own_buf[10];
      int gdb_supports_qRelocInsn = 0;

      /* Process each feature being provided by GDB.  The first
	 feature will follow a ':', and latter features will follow
	 ';'.  */
      if (*p == ':')
	{
	  std::vector<std::string> qsupported;
	  std::vector<const char *> unknowns;

	  /* Two passes, to avoid nested strtok calls in
	     target_process_qsupported.  */
	  char *saveptr;
	  for (p = strtok_r (p + 1, ";", &saveptr);
	       p != NULL;
	       p = strtok_r (NULL, ";", &saveptr))
	    qsupported.emplace_back (p);

	  for (const std::string &feature : qsupported)
	    {
	      if (feature == "multiprocess+")
		{
		  /* GDB supports and wants multi-process support if
		     possible.  */
		  if (target_supports_multi_process ())
		    cs.multi_process = 1;
		}
	      else if (feature == "qRelocInsn+")
		{
		  /* GDB supports relocate instruction requests.  */
		  gdb_supports_qRelocInsn = 1;
		}
	      else if (feature == "swbreak+")
		{
		  /* GDB wants us to report whether a trap is caused
		     by a software breakpoint and for us to handle PC
		     adjustment if necessary on this target.  */
		  if (target_supports_stopped_by_sw_breakpoint ())
		    cs.swbreak_feature = 1;
		}
	      else if (feature == "hwbreak+")
		{
		  /* GDB wants us to report whether a trap is caused
		     by a hardware breakpoint.  */
		  if (target_supports_stopped_by_hw_breakpoint ())
		    cs.hwbreak_feature = 1;
		}
	      else if (feature == "fork-events+")
		{
		  /* GDB supports and wants fork events if possible.  */
		  if (target_supports_fork_events ())
		    cs.report_fork_events = 1;
		}
	      else if (feature == "vfork-events+")
		{
		  /* GDB supports and wants vfork events if possible.  */
		  if (target_supports_vfork_events ())
		    cs.report_vfork_events = 1;
		}
	      else if (feature == "exec-events+")
		{
		  /* GDB supports and wants exec events if possible.  */
		  if (target_supports_exec_events ())
		    cs.report_exec_events = 1;
		}
	      else if (feature == "vContSupported+")
		cs.vCont_supported = 1;
	      else if (feature == "QThreadEvents+")
		;
	      else if (feature == "QThreadOptions+")
		;
	      else if (feature == "no-resumed+")
		{
		  /* GDB supports and wants TARGET_WAITKIND_NO_RESUMED
		     events.  */
		  report_no_resumed = true;
		}
	      else if (feature == "memory-tagging+")
		{
		  /* GDB supports memory tagging features.  */
		  if (target_supports_memory_tagging ())
		    cs.memory_tagging_feature = true;
		}
	      else if (feature == "error-message+")
		cs.error_message_supported = true;
	      else if (feature == "single-inf-arg+")
		cs.single_inferior_argument = true;
	      else
		{
		  /* Move the unknown features all together.  */
		  unknowns.push_back (feature.c_str ());
		}
	    }

	  /* Give the target backend a chance to process the unknown
	     features.  */
	  target_process_qsupported (unknowns);
	}

      sprintf (own_buf,
	       "PacketSize=%x;QPassSignals+;QProgramSignals+;"
	       "QStartupWithShell+;QEnvironmentHexEncoded+;"
	       "QEnvironmentReset+;QEnvironmentUnset+;"
	       "QSetWorkingDir+;binary-upload+",
	       PBUFSIZ - 1);

      if (target_supports_catch_syscall ())
	strcat (own_buf, ";QCatchSyscalls+");

      if (the_target->supports_qxfer_libraries_svr4 ())
	strcat (own_buf, ";qXfer:libraries-svr4:read+"
		";augmented-libraries-svr4-read+");
      else
	{
	  /* We do not have any hook to indicate whether the non-SVR4 target
	     backend supports qXfer:libraries:read, so always report it.  */
	  strcat (own_buf, ";qXfer:libraries:read+");
	}

      if (the_target->supports_read_auxv ())
	strcat (own_buf, ";qXfer:auxv:read+");

      if (the_target->supports_qxfer_siginfo ())
	strcat (own_buf, ";qXfer:siginfo:read+;qXfer:siginfo:write+");

      if (the_target->supports_read_loadmap ())
	strcat (own_buf, ";qXfer:fdpic:read+");

      /* We always report qXfer:features:read, as targets may
	 install XML files on a subsequent call to arch_setup.
	 If we reported to GDB on startup that we don't support
	 qXfer:feature:read at all, we will never be re-queried.  */
      strcat (own_buf, ";qXfer:features:read+");

      if (cs.transport_is_reliable)
	strcat (own_buf, ";QStartNoAckMode+");

      if (the_target->supports_qxfer_osdata ())
	strcat (own_buf, ";qXfer:osdata:read+");

      if (target_supports_multi_process ())
	strcat (own_buf, ";multiprocess+");

      if (target_supports_fork_events ())
	strcat (own_buf, ";fork-events+");

      if (target_supports_vfork_events ())
	strcat (own_buf, ";vfork-events+");

      if (target_supports_exec_events ())
	strcat (own_buf, ";exec-events+");

      if (target_supports_non_stop ())
	strcat (own_buf, ";QNonStop+");

      if (target_supports_disable_randomization ())
	strcat (own_buf, ";QDisableRandomization+");

      strcat (own_buf, ";qXfer:threads:read+");

      if (target_supports_tracepoints ())
	{
	  strcat (own_buf, ";ConditionalTracepoints+");
	  strcat (own_buf, ";TraceStateVariables+");
	  strcat (own_buf, ";TracepointSource+");
	  strcat (own_buf, ";DisconnectedTracing+");
	  if (gdb_supports_qRelocInsn && target_supports_fast_tracepoints ())
	    strcat (own_buf, ";FastTracepoints+");
	  strcat (own_buf, ";InstallInTrace+");
	  strcat (own_buf, ";qXfer:traceframe-info:read+");
	  strcat (own_buf, ";EnableDisableTracepoints+");
	  strcat (own_buf, ";QTBuffer:size+");
	  strcat (own_buf, ";tracenz+");
	}

      if (target_supports_hardware_single_step ()
	  || target_supports_software_single_step () )
	{
	  strcat (own_buf, ";ConditionalBreakpoints+");
	}
      strcat (own_buf, ";BreakpointCommands+");

      if (target_supports_agent ())
	strcat (own_buf, ";QAgent+");

      if (the_target->supports_btrace ())
	supported_btrace_packets (own_buf);

      if (target_supports_stopped_by_sw_breakpoint ())
	strcat (own_buf, ";swbreak+");

      if (target_supports_stopped_by_hw_breakpoint ())
	strcat (own_buf, ";hwbreak+");

      if (the_target->supports_pid_to_exec_file ())
	strcat (own_buf, ";qXfer:exec-file:read+");

      strcat (own_buf, ";vContSupported+");

      gdb_thread_options supported_options = target_supported_thread_options ();
      if (supported_options != 0)
	{
	  char *end_buf = own_buf + strlen (own_buf);
	  sprintf (end_buf, ";QThreadOptions=%s",
		   phex_nz (supported_options));
	}

      strcat (own_buf, ";QThreadEvents+");

      strcat (own_buf, ";no-resumed+");

      if (target_supports_memory_tagging ())
	strcat (own_buf, ";memory-tagging+");

      if (cs.single_inferior_argument)
	strcat (own_buf, ";single-inf-arg+");

      /* Reinitialize components as needed for the new connection.  */
      hostio_handle_new_gdb_connection ();
      target_handle_new_gdb_connection ();

      return;
    }

  /* Thread-local storage support.  */
  if (the_target->supports_get_tls_address ()
      && startswith (own_buf, "qGetTLSAddr:"))
    {
      char *p = own_buf + 12;
      CORE_ADDR parts[2], address = 0;
      int i, err;
      ptid_t ptid = null_ptid;

      require_running_or_return (own_buf);

      for (i = 0; i < 3; i++)
	{
	  char *p2;
	  int len;

	  if (p == NULL)
	    break;

	  p2 = strchr (p, ',');
	  if (p2)
	    {
	      len = p2 - p;
	      p2++;
	    }
	  else
	    {
	      len = strlen (p);
	      p2 = NULL;
	    }

	  if (i == 0)
	    ptid = read_ptid (p, NULL);
	  else
	    decode_address (&parts[i - 1], p, len);
	  p = p2;
	}

      if (p != NULL || i < 3)
	err = 1;
      else
	{
	  thread_info *thread = find_thread_ptid (ptid);

	  if (thread == NULL)
	    err = 2;
	  else
	    err = the_target->get_tls_address (thread, parts[0], parts[1],
					       &address);
	}

      if (err == 0)
	{
	  strcpy (own_buf, paddress(address));
	  return;
	}
      else if (err > 0)
	{
	  write_enn (own_buf);
	  return;
	}

      /* Otherwise, pretend we do not understand this packet.  */
    }

  /* Windows OS Thread Information Block address support.  */
  if (the_target->supports_get_tib_address ()
      && startswith (own_buf, "qGetTIBAddr:"))
    {
      const char *annex;
      int n;
      CORE_ADDR tlb;
      ptid_t ptid = read_ptid (own_buf + 12, &annex);

      n = the_target->get_tib_address (ptid, &tlb);
      if (n == 1)
	{
	  strcpy (own_buf, paddress(tlb));
	  return;
	}
      else if (n == 0)
	{
	  write_enn (own_buf);
	  return;
	}
      return;
    }

  /* Handle "monitor" commands.  */
  if (startswith (own_buf, "qRcmd,"))
    {
      char *mon = (char *) malloc (PBUFSIZ);
      int len = strlen (own_buf + 6);

      if (mon == NULL)
	{
	  write_enn (own_buf);
	  return;
	}

      if ((len % 2) != 0
	  || hex2bin (own_buf + 6, (gdb_byte *) mon, len / 2) != len / 2)
	{
	  write_enn (own_buf);
	  free (mon);
	  return;
	}
      mon[len / 2] = '\0';

      write_ok (own_buf);

      if (the_target->handle_monitor_command (mon) == 0)
	/* Default processing.  */
	handle_monitor_command (mon, own_buf);

      free (mon);
      return;
    }

  if (startswith (own_buf, "qSearch:memory:"))
    {
      require_running_or_return (own_buf);
      handle_search_memory (own_buf, packet_len);
      return;
    }

  if (strcmp (own_buf, "qAttached") == 0
      || startswith (own_buf, "qAttached:"))
    {
      struct process_info *process;

      if (own_buf[sizeof ("qAttached") - 1])
	{
	  int pid = strtoul (own_buf + sizeof ("qAttached:") - 1, NULL, 16);
	  process = find_process_pid (pid);
	}
      else
	{
	  require_running_or_return (own_buf);
	  process = current_process ();
	}

      if (process == NULL)
	{
	  write_enn (own_buf);
	  return;
	}

      strcpy (own_buf, process->attached ? "1" : "0");
      return;
    }

  if (startswith (own_buf, "qCRC:"))
    {
      /* CRC check (compare-section).  */
      const char *comma;
      ULONGEST base;
      int len;
      unsigned long long crc;

      require_running_or_return (own_buf);
      comma = unpack_varlen_hex (own_buf + 5, &base);
      if (*comma++ != ',')
	{
	  write_enn (own_buf);
	  return;
	}
      len = strtoul (comma, NULL, 16);
      crc = crc32 (base, len, 0xffffffff);
      /* Check for memory failure.  */
      if (crc == (unsigned long long) -1)
	{
	  write_enn (own_buf);
	  return;
	}
      sprintf (own_buf, "C%lx", (unsigned long) crc);
      return;
    }

  if (handle_qxfer (own_buf, packet_len, new_packet_len_p))
    return;

  if (target_supports_tracepoints () && handle_tracepoint_query (own_buf))
    return;

  /* Handle fetch memory tags packets.  */
  if (startswith (own_buf, "qMemTags:")
      && target_supports_memory_tagging ())
    {
      gdb::byte_vector tags;
      CORE_ADDR addr = 0;
      size_t len = 0;
      int type = 0;

      require_running_or_return (own_buf);

      parse_fetch_memtags_request (own_buf, &addr, &len, &type);

      bool ret = the_target->fetch_memtags (addr, len, tags, type);

      if (ret)
	ret = create_fetch_memtags_reply (own_buf, tags);

      if (!ret)
	write_enn (own_buf);

      *new_packet_len_p = strlen (own_buf);
      return;
    }

  if (strcmp ("qExecAndArgs", own_buf) == 0)
    {
      if (program_path.get () == nullptr)
	sprintf (own_buf, "U");
      else
	{
	  std::string packet ("S;");

	  packet += bin2hex ((const gdb_byte *) program_path.get (),
			     strlen (program_path.get ()));
	  packet += ";";

	  packet += bin2hex ((const gdb_byte *) program_args.c_str (),
			     program_args.length ());
	  packet += ";";

	  if (packet.size () > PBUFSIZ)
	    {
	      sprintf (own_buf, "E.Program name and arguments too long.");
	      return;
	    }

	  strcpy (own_buf, packet.c_str ());
	  *new_packet_len_p = packet.size ();
	}
      return;
    }

  /* Otherwise we didn't know what packet it was.  Say we didn't
     understand it.  */
  own_buf[0] = 0;
}

static void gdb_wants_all_threads_stopped (void);
static void resume (struct thread_resume *actions, size_t n);

/* The callback that is passed to visit_actioned_threads.  */
typedef int (visit_actioned_threads_callback_ftype)
  (const struct thread_resume *, thread_info *);

/* Call CALLBACK for any thread to which ACTIONS applies to.  Returns
   true if CALLBACK returns true.  Returns false if no matching thread
   is found or CALLBACK results false.
   Note: This function is itself a callback for find_thread.  */

static bool
visit_actioned_threads (thread_info *thread,
			const struct thread_resume *actions,
			size_t num_actions,
			visit_actioned_threads_callback_ftype *callback)
{
  for (size_t i = 0; i < num_actions; i++)
    {
      const struct thread_resume *action = &actions[i];

      if (action->thread == minus_one_ptid
	  || action->thread == thread->id
	  || ((action->thread.pid ()
	       == thread->id.pid ())
	      && action->thread.lwp () == -1))
	{
	  if ((*callback) (action, thread))
	    return true;
	}
    }

  return false;
}

/* Callback for visit_actioned_threads.  If the thread has a pending
   status to report, report it now.  */

static int
handle_pending_status (const struct thread_resume *resumption,
		       thread_info *thread)
{
  client_state &cs = get_client_state ();
  if (thread->status_pending_p)
    {
      thread->status_pending_p = 0;

      cs.last_status = thread->last_status;
      cs.last_ptid = thread->id;
      prepare_resume_reply (cs.own_buf, cs.last_ptid, cs.last_status);
      return 1;
    }
  return 0;
}

/* Parse vCont packets.  */
static void
handle_v_cont (char *own_buf)
{
  const char *p;
  int n = 0, i = 0;
  struct thread_resume *resume_info;
  struct thread_resume default_action { null_ptid };

  /* Count the number of semicolons in the packet.  There should be one
     for every action.  */
  p = &own_buf[5];
  while (p)
    {
      n++;
      p++;
      p = strchr (p, ';');
    }

  resume_info = (struct thread_resume *) malloc (n * sizeof (resume_info[0]));
  if (resume_info == NULL)
    goto err;

  p = &own_buf[5];
  while (*p)
    {
      p++;

      memset (&resume_info[i], 0, sizeof resume_info[i]);

      if (p[0] == 's' || p[0] == 'S')
	resume_info[i].kind = resume_step;
      else if (p[0] == 'r')
	resume_info[i].kind = resume_step;
      else if (p[0] == 'c' || p[0] == 'C')
	resume_info[i].kind = resume_continue;
      else if (p[0] == 't')
	resume_info[i].kind = resume_stop;
      else
	goto err;

      if (p[0] == 'S' || p[0] == 'C')
	{
	  char *q;
	  int sig = strtol (p + 1, &q, 16);
	  if (p == q)
	    goto err;
	  p = q;

	  if (!gdb_signal_to_host_p ((enum gdb_signal) sig))
	    goto err;
	  resume_info[i].sig = gdb_signal_to_host ((enum gdb_signal) sig);
	}
      else if (p[0] == 'r')
	{
	  ULONGEST addr;

	  p = unpack_varlen_hex (p + 1, &addr);
	  resume_info[i].step_range_start = addr;

	  if (*p != ',')
	    goto err;

	  p = unpack_varlen_hex (p + 1, &addr);
	  resume_info[i].step_range_end = addr;
	}
      else
	{
	  p = p + 1;
	}

      if (p[0] == 0)
	{
	  resume_info[i].thread = minus_one_ptid;
	  default_action = resume_info[i];

	  /* Note: we don't increment i here, we'll overwrite this entry
	     the next time through.  */
	}
      else if (p[0] == ':')
	{
	  const char *q;
	  ptid_t ptid = read_ptid (p + 1, &q);

	  if (p == q)
	    goto err;
	  p = q;
	  if (p[0] != ';' && p[0] != 0)
	    goto err;

	  resume_info[i].thread = ptid;

	  i++;
	}
    }

  if (i < n)
    resume_info[i] = default_action;

  resume (resume_info, n);
  free (resume_info);
  return;

err:
  write_enn (own_buf);
  free (resume_info);
  return;
}

/* Resume target with ACTIONS, an array of NUM_ACTIONS elements.  */

static void
resume (struct thread_resume *actions, size_t num_actions)
{
  client_state &cs = get_client_state ();
  if (!non_stop)
    {
      /* Check if among the threads that GDB wants actioned, there's
	 one with a pending status to report.  If so, skip actually
	 resuming/stopping and report the pending event
	 immediately.  */

      thread_info *thread_with_status = find_thread ([&] (thread_info *thread)
	{
	  return visit_actioned_threads (thread, actions, num_actions,
					 handle_pending_status);
	});

      if (thread_with_status != NULL)
	return;

      enable_async_io ();
    }

  the_target->resume (actions, num_actions);

  if (non_stop)
    write_ok (cs.own_buf);
  else
    {
      cs.last_ptid = mywait (minus_one_ptid, &cs.last_status, 0, 1);

      if (cs.last_status.kind () == TARGET_WAITKIND_NO_RESUMED
	  && !report_no_resumed)
	{
	  /* The client does not support this stop reply.  At least
	     return error.  */
	  sprintf (cs.own_buf, "E.No unwaited-for children left.");
	  disable_async_io ();
	  return;
	}

      if (cs.last_status.kind () != TARGET_WAITKIND_EXITED
	  && cs.last_status.kind () != TARGET_WAITKIND_SIGNALLED
	  && cs.last_status.kind () != TARGET_WAITKIND_THREAD_EXITED
	  && cs.last_status.kind () != TARGET_WAITKIND_NO_RESUMED)
	current_thread->last_status = cs.last_status;

      /* From the client's perspective, all-stop mode always stops all
	 threads implicitly (and the target backend has already done
	 so by now).  Tag all threads as "want-stopped", so we don't
	 resume them implicitly without the client telling us to.  */
      gdb_wants_all_threads_stopped ();
      prepare_resume_reply (cs.own_buf, cs.last_ptid, cs.last_status);
      disable_async_io ();

      if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
	  || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED)
	target_mourn_inferior (cs.last_ptid);
    }
}

/* Attach to a new program.  */
static void
handle_v_attach (char *own_buf)
{
  client_state &cs = get_client_state ();

  int pid = strtol (own_buf + 8, NULL, 16);

  try
    {
      if (attach_inferior (pid) == 0)
	{
	  /* Don't report shared library events after attaching, even if
	     some libraries are preloaded.  GDB will always poll the
	     library list.  Avoids the "stopped by shared library event"
	     notice on the GDB side.  */
	  current_process ()->dlls_changed = false;

	  if (non_stop)
	    {
	      /* In non-stop, we don't send a resume reply.  Stop events
		 will follow up using the normal notification
		 mechanism.  */
	      write_ok (own_buf);
	    }
	  else
	    prepare_resume_reply (own_buf, cs.last_ptid, cs.last_status);
	}
      else
	{
	  /* Not supported.  */
	  own_buf[0] = 0;
	}
    }
  catch (const gdb_exception_error &exception)
    {
      sprintf (own_buf, "E.%s", exception.what ());
    }
}

/* Decode an argument from the vRun packet buffer.  PTR points to the
   first hex-encoded character in the buffer, and LEN is the number of
   characters to read from the packet buffer.

   If the argument decoding is successful, return a buffer containing the
   decoded argument, including a null terminator at the end.

   If the argument decoding fails for any reason, return nullptr.  */

static gdb::unique_xmalloc_ptr<char>
decode_v_run_arg (const char *ptr, size_t len)
{
  /* Two hex characters are required for each decoded byte.  */
  if (len % 2 != 0)
    return nullptr;

  /* The length in bytes needed for the decoded argument.  */
  len /= 2;

  /* Buffer to decode the argument into.  The '+ 1' is for the null
     terminator we will add.  */
  char *arg = (char *) xmalloc (len + 1);

  /* Decode the argument from the packet and add a null terminator.  We do
     this within a try block as invalid characters within the PTR buffer
     will cause hex2bin to throw an exception.  Our caller relies on us
     returning nullptr in order to clean up some memory allocations.  */
  try
    {
      hex2bin (ptr, (gdb_byte *) arg, len);
      arg[len] = '\0';
    }
  catch (const gdb_exception_error &exception)
    {
      return nullptr;
    }

  return gdb::unique_xmalloc_ptr<char> (arg);
}

/* Run a new program.  */
static void
handle_v_run (char *own_buf)
{
  client_state &cs = get_client_state ();
  char *p, *next_p;
  gdb::argv_vec new_argv;
  gdb::unique_xmalloc_ptr<char> new_program_name;
  int i;

  for (i = 0, p = own_buf + strlen ("vRun;");
       /* Exit condition is at the end of the loop.  */;
       p = next_p + 1, ++i)
    {
      next_p = strchr (p, ';');
      if (next_p == NULL)
	next_p = p + strlen (p);

      if (i == 0 && p == next_p)
	{
	  /* No program specified.  */
	  gdb_assert (new_program_name == nullptr);
	}
      else if (p == next_p)
	{
	  /* Empty argument.  */
	  new_argv.push_back (xstrdup (""));
	}
      else
	{
	  /* The length of the argument string in the packet.  */
	  size_t len = next_p - p;

	  gdb::unique_xmalloc_ptr<char> arg = decode_v_run_arg (p, len);
	  if (arg == nullptr)
	    {
	      write_enn (own_buf);
	      return;
	    }

	  if (i == 0)
	    new_program_name = std::move (arg);
	  else
	    new_argv.push_back (arg.release ());
	}
      if (*next_p == '\0')
	break;
    }

  if (new_program_name == nullptr)
    {
      /* GDB didn't specify a program to run.  Use the program from the
	 last run with the new argument list.  */
      if (program_path.get () == nullptr)
	{
	  write_enn (own_buf);
	  return;
	}
    }
  else
    program_path.set (new_program_name.get ());

  if (cs.single_inferior_argument)
    {
      if (new_argv.get ().size () > 1)
	{
	  write_enn (own_buf);
	  return;
	}
      else if (new_argv.get ().size () == 1)
	program_args = std::string (new_argv.get ()[0]);
      else
	program_args.clear ();
    }
  else
    program_args = gdb::remote_args::join (new_argv.get ());

  try
    {
      target_create_inferior (program_path.get (), program_args);
    }
  catch (const gdb_exception_error &exception)
    {
      sprintf (own_buf, "E.%s", exception.what ());
      return;
    }

  if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED)
    {
      prepare_resume_reply (own_buf, cs.last_ptid, cs.last_status);

      /* In non-stop, sending a resume reply doesn't set the general
	 thread, but GDB assumes a vRun sets it (this is so GDB can
	 query which is the main thread of the new inferior.  */
      if (non_stop)
	cs.general_thread = cs.last_ptid;
    }
  else
    write_enn (own_buf);
}

/* Kill process.  */
static void
handle_v_kill (char *own_buf)
{
  client_state &cs = get_client_state ();
  int pid;
  char *p = &own_buf[6];
  if (cs.multi_process)
    pid = strtol (p, NULL, 16);
  else
    pid = signal_pid;

  process_info *proc = find_process_pid (pid);

  if (proc != nullptr && kill_inferior (proc) == 0)
    {
      cs.last_status.set_signalled (GDB_SIGNAL_KILL);
      cs.last_ptid = ptid_t (pid);
      discard_queued_stop_replies (cs.last_ptid);
      write_ok (own_buf);
    }
  else
    write_enn (own_buf);
}

/* Handle all of the extended 'v' packets.  */
void
handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
{
  client_state &cs = get_client_state ();
  if (!disable_packet_vCont)
    {
      if (strcmp (own_buf, "vCtrlC") == 0)
	{
	  the_target->request_interrupt ();
	  write_ok (own_buf);
	  return;
	}

      if (startswith (own_buf, "vCont;"))
	{
	  handle_v_cont (own_buf);
	  return;
	}

      if (startswith (own_buf, "vCont?"))
	{
	  strcpy (own_buf, "vCont;c;C;t");

	  if (!disable_packet_vCont_step
	      && (target_supports_hardware_single_step ()
		  || target_supports_software_single_step ()
		  || !cs.vCont_supported))
	    {
	      /* If target supports single step either by hardware or by
		 software, add actions s and S to the list of supported
		 actions.  On the other hand, if GDB doesn't request the
		 supported vCont actions in qSupported packet, add s and
		 S to the list too.  */
	      own_buf = own_buf + strlen (own_buf);
	      strcpy (own_buf, ";s;S");
	    }

	  if (target_supports_range_stepping ())
	    {
	      own_buf = own_buf + strlen (own_buf);
	      strcpy (own_buf, ";r");
	    }
	  return;
	}
    }

  if (startswith (own_buf, "vFile:")
      && handle_vFile (own_buf, packet_len, new_packet_len))
    return;

  if (startswith (own_buf, "vAttach;"))
    {
      if ((!extended_protocol || !cs.multi_process) && target_running ())
	{
	  fprintf (stderr, "Already debugging a process\n");
	  write_enn (own_buf);
	  return;
	}
      handle_v_attach (own_buf);
      return;
    }

  if (startswith (own_buf, "vRun;"))
    {
      if ((!extended_protocol || !cs.multi_process) && target_running ())
	{
	  fprintf (stderr, "Already debugging a process\n");
	  write_enn (own_buf);
	  return;
	}
      handle_v_run (own_buf);
      return;
    }

  if (startswith (own_buf, "vKill;"))
    {
      if (!target_running ())
	{
	  fprintf (stderr, "No process to kill\n");
	  write_enn (own_buf);
	  return;
	}
      handle_v_kill (own_buf);
      return;
    }

  if (handle_notif_ack (own_buf, packet_len))
    return;

  /* Otherwise we didn't know what packet it was.  Say we didn't
     understand it.  */
  own_buf[0] = 0;
  return;
}

/* Resume thread and wait for another event.  In non-stop mode,
   don't really wait here, but return immediately to the event
   loop.  */
static void
myresume (char *own_buf, int step, int sig)
{
  client_state &cs = get_client_state ();
  struct thread_resume resume_info[2];
  int n = 0;
  int valid_cont_thread;

  valid_cont_thread = (cs.cont_thread != null_ptid
			 && cs.cont_thread != minus_one_ptid);

  if (step || sig || valid_cont_thread)
    {
      resume_info[0].thread = current_thread->id;
      if (step)
	resume_info[0].kind = resume_step;
      else
	resume_info[0].kind = resume_continue;
      resume_info[0].sig = sig;
      n++;
    }

  if (!valid_cont_thread)
    {
      resume_info[n].thread = minus_one_ptid;
      resume_info[n].kind = resume_continue;
      resume_info[n].sig = 0;
      n++;
    }

  resume (resume_info, n);
}

/* Callback for for_each_thread.  Make a new stop reply for each
   stopped thread.  */

static void
queue_stop_reply_callback (thread_info *thread)
{
  /* For now, assume targets that don't have this callback also don't
     manage the thread's last_status field.  */
  if (!the_target->supports_thread_stopped ())
    {
      struct vstop_notif *new_notif = new struct vstop_notif;

      new_notif->ptid = thread->id;
      new_notif->status = thread->last_status;
      /* Pass the last stop reply back to GDB, but don't notify
	 yet.  */
      notif_event_enque (&notif_stop, new_notif);
    }
  else
    {
      if (target_thread_stopped (thread))
	{
	  threads_debug_printf
	    ("Reporting thread %s as already stopped with %s",
	     target_pid_to_str (thread->id).c_str (),
	     thread->last_status.to_string ().c_str ());

	  gdb_assert (thread->last_status.kind () != TARGET_WAITKIND_IGNORE);

	  /* Pass the last stop reply back to GDB, but don't notify
	     yet.  */
	  queue_stop_reply (thread->id, thread->last_status);
	}
    }
}

/* Set this inferior threads's state as "want-stopped".  We won't
   resume this thread until the client gives us another action for
   it.  */

static void
gdb_wants_thread_stopped (thread_info *thread)
{
  thread->last_resume_kind = resume_stop;

  if (thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
    {
      /* Most threads are stopped implicitly (all-stop); tag that with
	 signal 0.  */
      thread->last_status.set_stopped (GDB_SIGNAL_0);
    }
}

/* Set all threads' states as "want-stopped".  */

static void
gdb_wants_all_threads_stopped (void)
{
  for_each_thread (gdb_wants_thread_stopped);
}

/* Callback for for_each_thread.  If the thread is stopped with an
   interesting event, mark it as having a pending event.  */

static void
set_pending_status_callback (thread_info *thread)
{
  if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED
      || (thread->last_status.sig () != GDB_SIGNAL_0
	  /* A breakpoint, watchpoint or finished step from a previous
	     GDB run isn't considered interesting for a new GDB run.
	     If we left those pending, the new GDB could consider them
	     random SIGTRAPs.  This leaves out real async traps.  We'd
	     have to peek into the (target-specific) siginfo to
	     distinguish those.  */
	  && thread->last_status.sig () != GDB_SIGNAL_TRAP))
    thread->status_pending_p = 1;
}

/* Status handler for the '?' packet.  */

static void
handle_status (char *own_buf)
{
  client_state &cs = get_client_state ();

  /* GDB is connected, don't forward events to the target anymore.  */
  for_each_process ([] (process_info *process) {
    process->gdb_detached = 0;
  });

  /* In non-stop mode, we must send a stop reply for each stopped
     thread.  In all-stop mode, just send one for the first stopped
     thread we find.  */

  if (non_stop)
    {
      for_each_thread (queue_stop_reply_callback);

      /* The first is sent immediately.  OK is sent if there is no
	 stopped thread, which is the same handling of the vStopped
	 packet (by design).  */
      notif_write_event (&notif_stop, cs.own_buf);
    }
  else
    {
      thread_info *thread = NULL;

      target_pause_all (false);
      target_stabilize_threads ();
      gdb_wants_all_threads_stopped ();

      /* We can only report one status, but we might be coming out of
	 non-stop -- if more than one thread is stopped with
	 interesting events, leave events for the threads we're not
	 reporting now pending.  They'll be reported the next time the
	 threads are resumed.  Start by marking all interesting events
	 as pending.  */
      for_each_thread (set_pending_status_callback);

      /* Prefer the last thread that reported an event to GDB (even if
	 that was a GDB_SIGNAL_TRAP).  */
      if (cs.last_status.kind () != TARGET_WAITKIND_IGNORE
	  && cs.last_status.kind () != TARGET_WAITKIND_EXITED
	  && cs.last_status.kind () != TARGET_WAITKIND_SIGNALLED)
	thread = find_thread_ptid (cs.last_ptid);

      /* If the last event thread is not found for some reason, look
	 for some other thread that might have an event to report.  */
      if (thread == NULL)
	thread = find_thread ([] (thread_info *thr_arg)
	  {
	    return thr_arg->status_pending_p;
	  });

      /* If we're still out of luck, simply pick the first thread in
	 the thread list.  */
      if (thread == NULL)
	thread = get_first_thread ();

      if (thread != NULL)
	{
	  thread_info *tp = (thread_info *) thread;

	  /* We're reporting this event, so it's no longer
	     pending.  */
	  tp->status_pending_p = 0;

	  /* GDB assumes the current thread is the thread we're
	     reporting the status for.  */
	  cs.general_thread = thread->id;
	  set_desired_thread ();

	  gdb_assert (tp->last_status.kind () != TARGET_WAITKIND_IGNORE);
	  prepare_resume_reply (own_buf, tp->id, tp->last_status);
	}
      else
	strcpy (own_buf, "W00");
    }
}

static void
gdbserver_version (void)
{
  printf ("GNU gdbserver %s%s\n"
	  "Copyright (C) 2025 Free Software Foundation, Inc.\n"
	  "gdbserver is free software, covered by the "
	  "GNU General Public License.\n"
	  "This gdbserver was configured as \"%s\"\n",
	  PKGVERSION, version, host_name);
}

static void
gdbserver_usage (FILE *stream)
{
  fprintf (stream, "Usage:\tgdbserver [OPTIONS] COMM PROG [ARGS ...]\n"
	   "\tgdbserver [OPTIONS] --attach COMM PID\n"
	   "\tgdbserver [OPTIONS] --multi COMM\n"
	   "\n"
	   "COMM may either be a tty device (for serial debugging),\n"
	   "HOST:PORT to listen for a TCP connection, or '-' or 'stdio' to use \n"
	   "stdin/stdout of gdbserver.\n"
	   "PROG is the executable program.  ARGS are arguments passed to inferior.\n"
	   "PID is the process ID to attach to, when --attach is specified.\n"
	   "\n"
	   "Operating modes:\n"
	   "\n"
	   "  --attach              Attach to running process PID.\n"
	   "  --multi               Start server without a specific program, and\n"
	   "                        only quit when explicitly commanded.\n"
	   "  --once                Exit after the first connection has closed.\n"
	   "  --help                Print this message and then exit.\n"
	   "  --version             Display version information and exit.\n"
	   "\n"
	   "Other options:\n"
	   "\n"
	   "  --wrapper WRAPPER --  Run WRAPPER to start new programs.\n"
	   "  --disable-randomization\n"
	   "                        Run PROG with address space randomization disabled.\n"
	   "  --no-disable-randomization\n"
	   "                        Don't disable address space randomization when\n"
	   "                        starting PROG.\n"
	   "  --startup-with-shell\n"
	   "                        Start PROG using a shell.  I.e., execs a shell that\n"
	   "                        then execs PROG.  (default)\n"
	   "                        To make use of globbing and variable substitution for\n"
	   "                        arguments passed directly on gdbserver invocation,\n"
	   "                        see the --no-escape-args command line option in\n"
	   "                        addition\n"
	   "  --no-startup-with-shell\n"
	   "                        Exec PROG directly instead of using a shell.\n"
	   "  --no-escape-args\n"
	   "                        If PROG is started using a shell (see the\n"
	   "                        --[no-]startup-with-shell option),\n"
	   "                        ARGS passed directly on gdbserver invocation are\n"
	   "                        escaped, so no globbing or variable substitution\n"
	   "                        happens for those. This option disables escaping, so\n"
	   "                        globbing and variable substitution in the shell\n"
	   "                        are done for ARGS on UNIX-like systems.\n"
	   "\n"
	   "Debug options:\n"
	   "\n"
	   "  --debug[=OPT1,OPT2,...]\n"
	   "                        Enable debugging output.\n"
	   "                          Options:\n"
	   "                            all, threads, event-loop, remote\n"
	   "                          With no options, 'threads' is assumed.\n"
	   "                          Prefix an option with '-' to disable\n"
	   "                          debugging of that component.\n"
	   "  --debug-format=OPT1[,OPT2,...]\n"
	   "                        Specify extra content in debugging output.\n"
	   "                          Options:\n"
	   "                            all\n"
	   "                            none\n"
	   "                            timestamp\n"
	   "  --disable-packet=OPT1[,OPT2,...]\n"
	   "                        Disable support for RSP packets or features.\n"
	   "                          Options:\n"
	   "                            vCont, vConts, T, Tthread, qC, qfThreadInfo and\n"
	   "                            threads (disable all threading packets).\n"
	   "\n"
	   "For more information, consult the GDB manual (available as on-line \n"
	   "info or a printed manual).\n");
  if (REPORT_BUGS_TO[0] && stream == stdout)
    fprintf (stream, "Report bugs to \"%s\".\n", REPORT_BUGS_TO);
}

static void
gdbserver_show_disableable (FILE *stream)
{
  fprintf (stream, "Disableable packets:\n"
	   "  vCont       \tAll vCont packets\n"
	   "  qC          \tQuerying the current thread\n"
	   "  qfThreadInfo\tThread listing\n"
	   "  Tthread     \tPassing the thread specifier in the "
	   "T stop reply packet\n"
	   "  threads     \tAll of the above\n"
	   "  T           \tAll 'T' packets\n");
}

/* Start up the event loop.  This is the entry point to the event
   loop.  */

static void
start_event_loop ()
{
  /* Loop until there is nothing to do.  This is the entry point to
     the event loop engine.  If nothing is ready at this time, wait
     for something to happen (via wait_for_event), then process it.
     Return when there are no longer event sources to wait for.  */

  keep_processing_events = true;
  while (keep_processing_events)
    {
      /* Any events already waiting in the queue?  */
      int res = gdb_do_one_event ();

      /* Was there an error?  */
      if (res == -1)
	break;
    }

  /* We are done with the event loop.  There are no more event sources
     to listen to.  So we exit gdbserver.  */
}

static void
kill_inferior_callback (process_info *process)
{
  kill_inferior (process);
  discard_queued_stop_replies (ptid_t (process->pid));
}

/* Call this when exiting gdbserver with possible inferiors that need
   to be killed or detached from.  */

static void
detach_or_kill_for_exit (void)
{
  /* First print a list of the inferiors we will be killing/detaching.
     This is to assist the user, for example, in case the inferior unexpectedly
     dies after we exit: did we screw up or did the inferior exit on its own?
     Having this info will save some head-scratching.  */

  if (have_started_inferiors_p ())
    {
      fprintf (stderr, "Killing process(es):");

      for_each_process ([] (process_info *process) {
	if (!process->attached)
	  fprintf (stderr, " %d", process->pid);
      });

      fprintf (stderr, "\n");
    }
  if (have_attached_inferiors_p ())
    {
      fprintf (stderr, "Detaching process(es):");

      for_each_process ([] (process_info *process) {
	if (process->attached)
	  fprintf (stderr, " %d", process->pid);
      });

      fprintf (stderr, "\n");
    }

  /* Now we can kill or detach the inferiors.  */
  for_each_process ([] (process_info *process) {
    int pid = process->pid;

    if (process->attached)
      detach_inferior (process);
    else
      kill_inferior (process);

    discard_queued_stop_replies (ptid_t (pid));
  });
}

/* Value that will be passed to exit(3) when gdbserver exits.  */
static int exit_code;

/* Wrapper for detach_or_kill_for_exit that catches and prints
   errors.  */

static void
detach_or_kill_for_exit_cleanup ()
{
  try
    {
      detach_or_kill_for_exit ();
    }
  catch (const gdb_exception &exception)
    {
      fflush (stdout);
      fprintf (stderr, "Detach or kill failed: %s\n",
	       exception.what ());
      exit_code = 1;
    }
}

#if GDB_SELF_TEST

namespace selftests {

static void
test_memory_tagging_functions (void)
{
  /* Setup testing.  */
  gdb::char_vector packet;
  gdb::byte_vector tags, bv;
  std::string expected;
  packet.resize (32000);
  CORE_ADDR addr;
  size_t len;
  int type;

  /* Test parsing a qMemTags request.  */

  /* Valid request, addr, len and type updated.  */
  addr = 0xff;
  len = 255;
  type = 255;
  strcpy (packet.data (), "qMemTags:0,0:0");
  parse_fetch_memtags_request (packet.data (), &addr, &len, &type);
  SELF_CHECK (addr == 0 && len == 0 && type == 0);

  /* Valid request, addr, len and type updated.  */
  addr = 0;
  len = 0;
  type = 0;
  strcpy (packet.data (), "qMemTags:deadbeef,ff:5");
  parse_fetch_memtags_request (packet.data (), &addr, &len, &type);
  SELF_CHECK (addr == 0xdeadbeef && len == 255 && type == 5);

  /* Test creating a qMemTags reply.  */

  /* Non-empty tag data.  */
  bv.resize (0);

  for (int i = 0; i < 5; i++)
    bv.push_back (i);

  expected = "m0001020304";
  SELF_CHECK (create_fetch_memtags_reply (packet.data (), bv) == true);
  SELF_CHECK (strcmp (packet.data (), expected.c_str ()) == 0);

  /* Test parsing a QMemTags request.  */

  /* Valid request and empty tag data: addr, len, type and tags updated.  */
  addr = 0xff;
  len = 255;
  type = 255;
  tags.resize (5);
  strcpy (packet.data (), "QMemTags:0,0:0:");
  SELF_CHECK (parse_store_memtags_request (packet.data (),
					   &addr, &len, tags, &type) == true);
  SELF_CHECK (addr == 0 && len == 0 && type == 0 && tags.size () == 0);

  /* Valid request and non-empty tag data: addr, len, type
     and tags updated.  */
  addr = 0;
  len = 0;
  type = 0;
  tags.resize (0);
  strcpy (packet.data (),
	  "QMemTags:deadbeef,ff:5:0001020304");
  SELF_CHECK (parse_store_memtags_request (packet.data (), &addr, &len, tags,
					   &type) == true);
  SELF_CHECK (addr == 0xdeadbeef && len == 255 && type == 5
	      && tags.size () == 5);
}

/* Exercise the behavior of doing a 0-length comparison for a register in a
   register buffer, which should return true.  */

static void test_registers_raw_compare_zero_length ()
{
  /* Start off with a dummy target description.  */
  target_desc dummy_tdesc;

  /* Make it 8 bytes long.  */
  dummy_tdesc.registers_size = 8;

  /* Add a couple dummy 32-bit registers.  */
  dummy_tdesc.reg_defs.emplace_back ("r0", 0, 32);
  dummy_tdesc.reg_defs.emplace_back ("r1", 32, 32);

  /* Create our dummy register cache so we can invoke the raw_compare method
     we want to validate.  */
  regcache dummy_regcache (&dummy_tdesc);

  /* Create a dummy byte buffer we can pass to the raw_compare method.  */
  gdb_byte dummy_buffer[8];

  /* Validate the 0-length comparison (due to the comparison offset being
     equal to the length of the register) returns true.  */
  SELF_CHECK (dummy_regcache.raw_compare (0, dummy_buffer, 4));
}

} /* namespace selftests */
#endif /* GDB_SELF_TEST */

/* Main function.  This is called by the real "main" function,
   wrapped in a TRY_CATCH that handles any uncaught exceptions.  */

[[noreturn]] static void
captured_main (int argc, char *argv[])
{
  int pid;
  volatile bool multi_mode = false;
  volatile bool attach = false;
  bool selftest = false;
  bool escape_args = true;
#if GDB_SELF_TEST
  std::vector<const char *> selftest_filters;

  selftests::register_test ("remote_memory_tagging",
			    selftests::test_memory_tagging_functions);
  selftests::register_test ("test_registers_raw_compare_zero_length",
			    selftests::test_registers_raw_compare_zero_length);
#endif

  current_directory = getcwd (NULL, 0);
  client_state &cs = get_client_state ();

  if (current_directory == NULL)
    {
      error (_("Could not find current working directory: %s"),
	     safe_strerror (errno));
    }

  enum opts { OPT_VERSION = 1, OPT_HELP, OPT_ATTACH, OPT_MULTI, OPT_WRAPPER,
    OPT_DEBUG, OPT_DEBUG_FILE, OPT_DEBUG_FORMAT, OPT_DISABLE_PACKET,
    OPT_DISABLE_RANDOMIZATION, OPT_NO_DISABLE_RANDOMIZATION,
    OPT_STARTUP_WITH_SHELL, OPT_NO_STARTUP_WITH_SHELL, OPT_ONCE,
    OPT_SELFTEST, OPT_NO_ESCAPE
  };

  static struct option longopts[] =
    {
      {"version", no_argument, nullptr, OPT_VERSION},
      {"help", no_argument, nullptr, OPT_HELP},
      {"attach", no_argument, nullptr, OPT_ATTACH},
      {"multi", no_argument, nullptr, OPT_MULTI},
      {"wrapper", no_argument, nullptr, OPT_WRAPPER},
      {"debug", optional_argument, nullptr, OPT_DEBUG},
      {"debug-file", required_argument, nullptr, OPT_DEBUG_FILE},
      {"debug-format", required_argument, nullptr, OPT_DEBUG_FORMAT},
      /* --disable-packet is optional_argument only so that we can print a
	 better help list when the argument is missing.  */
      {"disable-packet", optional_argument, nullptr, OPT_DISABLE_PACKET},
      {"disable-randomization", no_argument, nullptr,
       OPT_DISABLE_RANDOMIZATION},
      {"no-disable-randomization", no_argument, nullptr,
       OPT_NO_DISABLE_RANDOMIZATION},
      {"startup-with-shell", no_argument, nullptr, OPT_STARTUP_WITH_SHELL},
      {"no-startup-with-shell", no_argument, nullptr,
       OPT_NO_STARTUP_WITH_SHELL},
      {"once", no_argument, nullptr, OPT_ONCE},
      {"selftest", optional_argument, nullptr, OPT_SELFTEST},
      {"no-escape-args", no_argument, nullptr, OPT_NO_ESCAPE},
      {nullptr, no_argument, nullptr, 0}
    };

  /* Ask getopt_long not to print error messages, we'll do that ourselves.
     Look for handling of '?' from getopt_long.  */
  opterr = 0;

  int optc, longindex;

  /* The '+' passed to getopt_long here stops ARGV being reordered.  In a
     command line like: 'gdbserver PORT program --arg1 --arg2', the
     '--arg1' and '--arg2' are arguments to 'program', not to gdbserver.
     If getopt_long is free to reorder ARGV then it will try to steal those
     arguments for itself.  */
  while ((longindex = -1,
	  optc = getopt_long (argc, argv, "+:", longopts, &longindex)) != -1)
    {
      /* As a GNU extension, getopt_long supports '--arg value' form,
	 without an '=' symbol between the 'arg' and the 'value'.  This
	 block aids in supporting this form.

	 If we found a matching entry in LONGOPTS, the entry has an
	 optional argument, and OPTARG is NULL, then this indicates that we
	 saw the '--arg value' form. Look at the next ARGV entry to see if
	 it exists, and doesn't look like a port number, or the start of
	 another argument.  If this is the case, then make the next ARGV
	 entry the argument value.  Otherwise, continue with no
	 argument.

	 If we found a matching entry in LONGOPTS, the entry has a required
	 argument, then OPTARG will not be NULL.  In this case, if the
	 start of OPTARG is the start of the previous ARGV entry, then this
	 indicates we saw the '--arg value' form.  If OPTARG looks like a
	 port number, or the start of another argument, then assume the
	 user didn't in fact pass a value, but forgot.  Pretend we are
	 missing the argument value.  */
      if (longindex != -1
	  && ((longopts[longindex].has_arg == optional_argument
	       &&optarg == nullptr)
	      || (longopts[longindex].has_arg == required_argument
		  && optarg == argv[optind - 1])))
	{
	  if (longopts[longindex].has_arg == optional_argument)
	    {
	      /* Claim the next entry from ARGV as the argument value.  */
	      optarg = argv[optind];
	      optind++;
	    }
	  else
	    gdb_assert (optarg != nullptr);

	  if (optarg == nullptr
	      || strcmp (optarg, "-") == 0
	      || strcmp (optarg, STDIO_CONNECTION_NAME) == 0
	      || startswith (optarg, "--")
	      || strchr (optarg, ':') != nullptr)
	    {
	      /* OPTARG is NULL, looks like a port number, or could be the
		 start of another argument.  Clear OPTARG as we don't have
		 an argument, and decrement OPTIND so the next call to
		 getopt will process this as an argument.  */
	      optarg = nullptr;
	      optind--;

	      /* For required arguments, if we don't have an argument, then
		 this is an error, set OPTC to reflect this.  */
	      if (longopts[longindex].has_arg == required_argument)
		optc = ':';
	    }
	}

      switch (optc)
	{
	case OPT_VERSION:
	  gdbserver_version ();
	  exit (0);

	case OPT_HELP:
	  gdbserver_usage (stdout);
	  exit (0);

	case OPT_ATTACH:
	  attach = true;
	  break;

	case OPT_MULTI:
	  multi_mode = true;
	  break;

	case OPT_WRAPPER:
	  {
	    int original_optind = optind;

	    while (argv[optind] != nullptr
		   && strcmp (argv[optind], "--") != 0)
	      {
		wrapper_argv += argv[optind];
		wrapper_argv += ' ';
		++optind;
	      }

	    if (!wrapper_argv.empty ())
	      {
		/* Erase the last whitespace.  */
		wrapper_argv.erase (wrapper_argv.end () - 1);
	      }

	    if (original_optind == optind || argv[optind] == nullptr)
	      {
		gdbserver_usage (stderr);
		exit (1);
	      }

	    /* Consume the "--".  */
	    ++optind;
	  }
	  break;

	case OPT_DEBUG:
	  {
	    const char *debug_opt = (optarg == nullptr) ? "" : optarg;
	    try
	      {
		parse_debug_options (debug_opt);
	      }
	    catch (const gdb_exception_error &exception)
	      {
		fflush (stdout);
		fprintf (stderr, "gdbserver: %s\n", exception.what ());
		exit (1);
	      }
	  }
	  break;

	case OPT_DEBUG_FILE:
	  {
	    gdb_assert (optarg != nullptr);
	    debug_set_output (optarg);
	  }
	  break;

	case OPT_DEBUG_FORMAT:
	  {
	    gdb_assert (optarg != nullptr);
	    std::string error_msg
	      = parse_debug_format_options (optarg, 0);

	    if (!error_msg.empty ())
	      {
		fprintf (stderr, "%s", error_msg.c_str ());
		exit (1);
	      }
	  }
	  break;

	case OPT_DISABLE_PACKET:
	  {
	    char *packets = optarg;
	    if (packets == nullptr)
	      {
		gdbserver_show_disableable (stdout);
		exit (1);
	      }
	    char *saveptr;
	    for (char *tok = strtok_r (packets, ",", &saveptr);
		 tok != nullptr;
		 tok = strtok_r (nullptr, ",", &saveptr))
	      {
		if (strcmp ("vCont", tok) == 0)
		  disable_packet_vCont = true;
		else if (strcmp ("vConts", tok) == 0)
		  disable_packet_vCont_step = true;
		else if (strcmp ("Tthread", tok) == 0)
		  disable_packet_Tthread = true;
		else if (strcmp ("qC", tok) == 0)
		  disable_packet_qC = true;
		else if (strcmp ("qfThreadInfo", tok) == 0)
		  disable_packet_qfThreadInfo = true;
		else if (strcmp ("T", tok) == 0)
		  disable_packet_T = true;
		else if (strcmp ("threads", tok) == 0)
		  {
		    disable_packet_vCont = true;
		    disable_packet_Tthread = true;
		    disable_packet_qC = true;
		    disable_packet_qfThreadInfo = true;
		  }
		else
		  {
		    fprintf (stderr, "Don't know how to disable \"%s\".\n\n",
			     tok);
		    gdbserver_show_disableable (stderr);
		    exit (1);
		  }
	      }
	  }
	  break;

	case OPT_DISABLE_RANDOMIZATION:
	  cs.disable_randomization = 1;
	  break;

	case OPT_NO_DISABLE_RANDOMIZATION:
	  cs.disable_randomization = 0;
	  break;

	case OPT_STARTUP_WITH_SHELL:
	  startup_with_shell = true;
	  break;

	case OPT_NO_STARTUP_WITH_SHELL:
	  startup_with_shell = false;
	  break;

	case OPT_ONCE:
	  run_once = true;
	  break;

	case OPT_SELFTEST:
	  {
	    selftest = true;
	    if (optarg != nullptr)
	      {
#if GDB_SELF_TEST
		if (*optarg == '\0')
		  {
		    fprintf (stderr, _("Error: selftest filter is empty.\n"));
		    exit (1);
		  }

		selftest_filters.push_back (optarg);
#endif
	      }
	  }
	  break;

	case OPT_NO_ESCAPE:
	  escape_args = false;
	  break;

	case ':':
	case '?':
	  /* Figuring out which element of ARGV contained the invalid
	     argument is not simple.  There are a couple of cases we need
	     to consider.

	     (1) Something like '-x'.  gdbserver doesn't support single
		 character options, so a '-' followed by a character is
		 always invalid.  In this case global OPTOPT will be set to
		 'x', and global OPTIND will point to the next ARGV entry.

	     (2) Something like '-xyz'.  gdbserver doesn't support single
		 dash arguments for its command line options.  The
		 getopt_long call treats this like '-x -y -z', in which
		 case global OPTOPT is set to 'x' and global OPTIND will
		 point to this ARGV entry.

	     (3) Something like '--unknown'.  This is just an unknown
		 double dash argument.  Global OPTOPT is set to '\0', and
		 global OPTIND points to the next ARGV entry.  */
	  std::string bad_arg;
	  if (optopt == '\0' || argv[optind] == nullptr
	      || argv[optind][0] != '-' || argv[optind][1] != optopt)
	    bad_arg = argv[optind - 1];
	  else
	    bad_arg = argv[optind];

	  if (optc == '?')
	    fprintf (stderr, _("Unknown argument: %s\n"), bad_arg.c_str ());
	  else
	    fprintf (stderr, _("Missing argument value for: %s\n"),
		     bad_arg.c_str ());
	  exit (1);
	}
    }

  const char *port = argv[optind];
  ++optind;
  if (port != nullptr && strcmp (port, "-") == 0)
    {
      port = STDIO_CONNECTION_NAME;

      /* Implying --once here prevents a hang after stdin has been closed.  */
      run_once = true;
    }

  char **next_arg = &argv[optind];
  if ((port == NULL || (!attach && !multi_mode && *next_arg == NULL))
       && !selftest)
    {
      gdbserver_usage (stderr);
      exit (1);
    }

  /* Remember stdio descriptors.  LISTEN_DESC must not be listed, it will be
     opened by remote_prepare.  */
  notice_open_fds ();

  save_original_signals_state (false);

  /* We need to know whether the remote connection is stdio before
     starting the inferior.  Inferiors created in this scenario have
     stdin,stdout redirected.  So do this here before we call
     start_inferior.  */
  if (port != NULL)
    remote_prepare (port);

  bool bad_attach = false;
  pid = 0;

  /* --attach used to come after PORT, so allow it there for
       compatibility.  */
  if (*next_arg != NULL && strcmp (*next_arg, "--attach") == 0)
    {
      attach = true;
      next_arg++;
    }

  char *arg_end;
  if (attach
      && (*next_arg == NULL
	  || (*next_arg)[0] == '\0'
	  || (pid = strtoul (*next_arg, &arg_end, 0)) == 0
	  || *arg_end != '\0'
	  || next_arg[1] != NULL))
    bad_attach = true;

  if (bad_attach)
    {
      gdbserver_usage (stderr);
      exit (1);
    }

  /* Gather information about the environment.  */
  our_environ = gdb_environ::from_host_environ ();

  initialize_async_io ();
  initialize_low ();
  have_job_control ();
  if (target_supports_tracepoints ())
    initialize_tracepoint ();

  mem_buf = (unsigned char *) xmalloc (PBUFSIZ);

  if (selftest)
    {
#if GDB_SELF_TEST
      selftests::run_tests (selftest_filters);
#else
      printf (_("Selftests have been disabled for this build.\n"));
#endif
      throw_quit ("Quit");
    }

  if (pid == 0 && *next_arg != NULL)
    {
      program_path.set (next_arg[0]);

      if (program_path.get () == nullptr)
	error (_("No program to debug"));

      int n = argc - (next_arg - argv);
      program_args
	= construct_inferior_arguments ({&next_arg[1], &next_arg[n]},
					escape_args);

      /* Wait till we are at first instruction in program.  */
      target_create_inferior (program_path.get (), program_args);

      /* We are now (hopefully) stopped at the first instruction of
	 the target process.  This assumes that the target process was
	 successfully created.  */
    }
  else if (pid != 0)
    {
      if (attach_inferior (pid) == -1)
	error ("Attaching not supported on this target");

      /* Otherwise succeeded.  */
    }
  else
    {
      cs.last_status.set_exited (0);
      cs.last_ptid = minus_one_ptid;
    }

  SCOPE_EXIT { detach_or_kill_for_exit_cleanup (); };

  /* Don't report shared library events on the initial connection,
     even if some libraries are preloaded.  Avoids the "stopped by
     shared library event" notice on gdb side.  */
  if (current_thread != nullptr)
    current_process ()->dlls_changed = false;

  bool was_running;
  if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
      || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED)
    was_running = false;
  else
    was_running = true;

  if (!was_running && !multi_mode)
    error ("No program to debug");

  while (1)
    {
      cs.noack_mode = 0;
      cs.multi_process = 0;
      cs.report_fork_events = 0;
      cs.report_vfork_events = 0;
      cs.report_exec_events = 0;
      /* Be sure we're out of tfind mode.  */
      cs.current_traceframe = -1;
      cs.cont_thread = null_ptid;
      cs.swbreak_feature = 0;
      cs.hwbreak_feature = 0;
      cs.vCont_supported = 0;
      cs.memory_tagging_feature = false;
      cs.error_message_supported = false;

      remote_open (port);

      try
	{
	  /* Wait for events.  This will return when all event sources
	     are removed from the event loop.  */
	  start_event_loop ();

	  /* If an exit was requested (using the "monitor exit"
	     command), terminate now.  */
	  if (exit_requested)
	    throw_quit ("Quit");

	  /* The only other way to get here is for getpkt to fail:

	      - If --once was specified, we're done.

	      - If not in extended-remote mode, and we're no longer
		debugging anything, simply exit: GDB has disconnected
		after processing the last process exit.

	      - Otherwise, close the connection and reopen it at the
		top of the loop.  */
	  if (run_once || (!extended_protocol && !target_running ()))
	    throw_quit ("Quit");

	  fprintf (stderr,
		   "Remote side has terminated connection.  "
		   "GDBserver will reopen the connection.\n");

	  /* Get rid of any pending statuses.  An eventual reconnection
	     (by the same GDB instance or another) will refresh all its
	     state from scratch.  */
	  discard_queued_stop_replies (minus_one_ptid);
	  for_each_thread ([] (thread_info *thread)
	    {
	      thread->status_pending_p = 0;
	    });

	  if (tracing)
	    {
	      if (disconnected_tracing)
		{
		  /* Try to enable non-stop/async mode, so we we can
		     both wait for an async socket accept, and handle
		     async target events simultaneously.  There's also
		     no point either in having the target always stop
		     all threads, when we're going to pass signals
		     down without informing GDB.  */
		  if (!non_stop)
		    {
		      if (the_target->start_non_stop (true))
			non_stop = 1;

		      /* Detaching implicitly resumes all threads;
			 simply disconnecting does not.  */
		    }
		}
	      else
		{
		  fprintf (stderr,
			   "Disconnected tracing disabled; "
			   "stopping trace run.\n");
		  stop_tracing ();
		}
	    }
	}
      catch (const gdb_exception_error &exception)
	{
	  fflush (stdout);
	  fprintf (stderr, "gdbserver: %s\n", exception.what ());

	  if (response_needed)
	    {
	      write_enn (cs.own_buf);
	      putpkt (cs.own_buf);
	    }

	  if (run_once)
	    throw_quit ("Quit");
	}
    }
}

/* Main function.  */

int
main (int argc, char *argv[])
{
  setlocale (LC_CTYPE, "");

  try
    {
      captured_main (argc, argv);
    }
  catch (const gdb_exception &exception)
    {
      if (exception.reason == RETURN_ERROR)
	{
	  fflush (stdout);
	  fprintf (stderr, "%s\n", exception.what ());
	  fprintf (stderr, "Exiting\n");
	  exit_code = 1;
	}

      exit (exit_code);
    }

  gdb_assert_not_reached ("captured_main should never return");
}

/* Process options coming from Z packets for a breakpoint.  PACKET is
   the packet buffer.  *PACKET is updated to point to the first char
   after the last processed option.  */

static void
process_point_options (struct gdb_breakpoint *bp, const char **packet)
{
  const char *dataptr = *packet;
  int persist;

  /* Check if data has the correct format.  */
  if (*dataptr != ';')
    return;

  dataptr++;

  while (*dataptr)
    {
      if (*dataptr == ';')
	++dataptr;

      if (*dataptr == 'X')
	{
	  /* Conditional expression.  */
	  threads_debug_printf ("Found breakpoint condition.");
	  if (!add_breakpoint_condition (bp, &dataptr))
	    dataptr = strchrnul (dataptr, ';');
	}
      else if (startswith (dataptr, "cmds:"))
	{
	  dataptr += strlen ("cmds:");
	  threads_debug_printf ("Found breakpoint commands %s.", dataptr);
	  persist = (*dataptr == '1');
	  dataptr += 2;
	  if (add_breakpoint_commands (bp, &dataptr, persist))
	    dataptr = strchrnul (dataptr, ';');
	}
      else
	{
	  fprintf (stderr, "Unknown token %c, ignoring.\n",
		   *dataptr);
	  /* Skip tokens until we find one that we recognize.  */
	  dataptr = strchrnul (dataptr, ';');
	}
    }
  *packet = dataptr;
}

/* Event loop callback that handles a serial event.  The first byte in
   the serial buffer gets us here.  We expect characters to arrive at
   a brisk pace, so we read the rest of the packet with a blocking
   getpkt call.  */

static int
process_serial_event (void)
{
  client_state &cs = get_client_state ();
  int signal;
  unsigned int len;
  CORE_ADDR mem_addr;
  unsigned char sig;
  int packet_len;
  int new_packet_len = -1;

  disable_async_io ();

  response_needed = false;
  packet_len = getpkt (cs.own_buf);
  if (packet_len <= 0)
    {
      remote_close ();
      /* Force an event loop break.  */
      return -1;
    }
  response_needed = true;

  char ch = cs.own_buf[0];
  switch (ch)
    {
    case 'q':
      handle_query (cs.own_buf, packet_len, &new_packet_len);
      break;
    case 'Q':
      handle_general_set (cs.own_buf);
      break;
    case 'D':
      handle_detach (cs.own_buf);
      break;
    case '!':
      extended_protocol = true;
      write_ok (cs.own_buf);
      break;
    case '?':
      handle_status (cs.own_buf);
      break;
    case 'H':
      if (cs.own_buf[1] == 'c' || cs.own_buf[1] == 'g' || cs.own_buf[1] == 's')
	{
	  require_running_or_break (cs.own_buf);

	  ptid_t thread_id = read_ptid (&cs.own_buf[2], NULL);

	  if (thread_id == null_ptid || thread_id == minus_one_ptid)
	    thread_id = null_ptid;
	  else if (thread_id.is_pid ())
	    {
	      /* The ptid represents a pid.  */
	      thread_info *thread = find_any_thread_of_pid (thread_id.pid ());

	      if (thread == NULL)
		{
		  write_enn (cs.own_buf);
		  break;
		}

	      thread_id = thread->id;
	    }
	  else
	    {
	      /* The ptid represents a lwp/tid.  */
	      if (find_thread_ptid (thread_id) == NULL)
		{
		  write_enn (cs.own_buf);
		  break;
		}
	    }

	  if (cs.own_buf[1] == 'g')
	    {
	      if (thread_id == null_ptid)
		{
		  /* GDB is telling us to choose any thread.  Check if
		     the currently selected thread is still valid. If
		     it is not, select the first available.  */
		  thread_info *thread = find_thread_ptid (cs.general_thread);
		  if (thread == NULL)
		    thread = get_first_thread ();
		  thread_id = thread->id;
		}

	      cs.general_thread = thread_id;
	      set_desired_thread ();
	      gdb_assert (current_thread != NULL);
	    }
	  else if (cs.own_buf[1] == 'c')
	    cs.cont_thread = thread_id;

	  write_ok (cs.own_buf);
	}
      else
	{
	  /* Silently ignore it so that gdb can extend the protocol
	     without compatibility headaches.  */
	  cs.own_buf[0] = '\0';
	}
      break;
    case 'g':
      require_running_or_break (cs.own_buf);
      if (cs.current_traceframe >= 0)
	{
	  regcache a_regcache (current_target_desc ());

	  if (fetch_traceframe_registers (cs.current_traceframe,
					  &a_regcache, -1) == 0)
	    registers_to_string (&a_regcache, cs.own_buf);
	  else
	    write_enn (cs.own_buf);
	}
      else
	{
	  struct regcache *regcache;

	  if (!set_desired_thread ())
	    write_enn (cs.own_buf);
	  else
	    {
	      regcache = get_thread_regcache (current_thread);
	      registers_to_string (regcache, cs.own_buf);
	    }
	}
      break;
    case 'G':
      require_running_or_break (cs.own_buf);
      if (cs.current_traceframe >= 0)
	write_enn (cs.own_buf);
      else
	{
	  struct regcache *regcache;

	  if (!set_desired_thread ())
	    write_enn (cs.own_buf);
	  else
	    {
	      regcache = get_thread_regcache (current_thread);
	      registers_from_string (regcache, &cs.own_buf[1]);
	      write_ok (cs.own_buf);
	    }
	}
      break;
    case 'm':
      {
	require_running_or_break (cs.own_buf);
	decode_m_packet (&cs.own_buf[1], &mem_addr, &len);
	int res = gdb_read_memory (mem_addr, mem_buf, len);
	if (res < 0)
	  write_enn (cs.own_buf);
	else
	  bin2hex (mem_buf, cs.own_buf, res);
      }
      break;
    case 'M':
      require_running_or_break (cs.own_buf);
      decode_M_packet (&cs.own_buf[1], &mem_addr, &len, &mem_buf);
      if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
	write_ok (cs.own_buf);
      else
	write_enn (cs.own_buf);
      break;
    case 'x':
      {
	require_running_or_break (cs.own_buf);
	decode_x_packet (&cs.own_buf[1], &mem_addr, &len);
	int res = gdb_read_memory (mem_addr, mem_buf, len);
	if (res < 0)
	  write_enn (cs.own_buf);
	else
	  {
	    gdb_byte *buffer = (gdb_byte *) cs.own_buf;
	    *buffer++ = 'b';

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

	    if (out_len_units != res)
	      {
		write_enn (cs.own_buf);
		new_packet_len = -1;
	      }
	    else
	      suppress_next_putpkt_log ();
	  }
      }
      break;
    case 'X':
      require_running_or_break (cs.own_buf);
      if (decode_X_packet (&cs.own_buf[1], packet_len - 1,
			   &mem_addr, &len, &mem_buf) < 0
	  || gdb_write_memory (mem_addr, mem_buf, len) != 0)
	write_enn (cs.own_buf);
      else
	write_ok (cs.own_buf);
      break;
    case 'C':
      require_running_or_break (cs.own_buf);
      hex2bin (cs.own_buf + 1, &sig, 1);
      if (gdb_signal_to_host_p ((enum gdb_signal) sig))
	signal = gdb_signal_to_host ((enum gdb_signal) sig);
      else
	signal = 0;
      myresume (cs.own_buf, 0, signal);
      break;
    case 'S':
      require_running_or_break (cs.own_buf);
      hex2bin (cs.own_buf + 1, &sig, 1);
      if (gdb_signal_to_host_p ((enum gdb_signal) sig))
	signal = gdb_signal_to_host ((enum gdb_signal) sig);
      else
	signal = 0;
      myresume (cs.own_buf, 1, signal);
      break;
    case 'c':
      require_running_or_break (cs.own_buf);
      signal = 0;
      myresume (cs.own_buf, 0, signal);
      break;
    case 's':
      require_running_or_break (cs.own_buf);
      signal = 0;
      myresume (cs.own_buf, 1, signal);
      break;
    case 'Z':  /* insert_ ... */
      /* Fallthrough.  */
    case 'z':  /* remove_ ... */
      {
	char *dataptr;
	ULONGEST addr;
	int kind;
	char type = cs.own_buf[1];
	int res;
	const int insert = ch == 'Z';
	const char *p = &cs.own_buf[3];

	p = unpack_varlen_hex (p, &addr);
	kind = strtol (p + 1, &dataptr, 16);

	if (insert)
	  {
	    struct gdb_breakpoint *bp;

	    bp = set_gdb_breakpoint (type, addr, kind, &res);
	    if (bp != NULL)
	      {
		res = 0;

		/* GDB may have sent us a list of *point parameters to
		   be evaluated on the target's side.  Read such list
		   here.  If we already have a list of parameters, GDB
		   is telling us to drop that list and use this one
		   instead.  */
		clear_breakpoint_conditions_and_commands (bp);
		const char *options = dataptr;
		process_point_options (bp, &options);
	      }
	  }
	else
	  res = delete_gdb_breakpoint (type, addr, kind);

	if (res == 0)
	  write_ok (cs.own_buf);
	else if (res == 1)
	  /* Unsupported.  */
	  cs.own_buf[0] = '\0';
	else
	  write_enn (cs.own_buf);
	break;
      }
    case 'k':
      response_needed = false;
      if (!target_running ())
	/* The packet we received doesn't make sense - but we can't
	   reply to it, either.  */
	return 0;

      fprintf (stderr, "Killing all inferiors\n");

      for_each_process (kill_inferior_callback);

      /* When using the extended protocol, we wait with no program
	 running.  The traditional protocol will exit instead.  */
      if (extended_protocol)
	{
	  cs.last_status.set_exited (GDB_SIGNAL_KILL);
	  return 0;
	}
      else
	exit (0);

    case 'T':
      {
	require_running_or_break (cs.own_buf);

	ptid_t thread_id = read_ptid (&cs.own_buf[1], NULL);
	if (find_thread_ptid (thread_id) == NULL)
	  {
	    write_enn (cs.own_buf);
	    break;
	  }

	if (mythread_alive (thread_id))
	  write_ok (cs.own_buf);
	else
	  write_enn (cs.own_buf);
      }
      break;
    case 'R':
      response_needed = false;

      /* Restarting the inferior is only supported in the extended
	 protocol.  */
      if (extended_protocol)
	{
	  if (target_running ())
	    for_each_process (kill_inferior_callback);

	  fprintf (stderr, "GDBserver restarting\n");

	  /* Wait till we are at 1st instruction in prog.  */
	  if (program_path.get () != NULL)
	    {
	      target_create_inferior (program_path.get (), program_args);

	      if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED)
		{
		  /* Stopped at the first instruction of the target
		     process.  */
		  cs.general_thread = cs.last_ptid;
		}
	      else
		{
		  /* Something went wrong.  */
		  cs.general_thread = null_ptid;
		}
	    }
	  else
	    {
	      cs.last_status.set_exited (GDB_SIGNAL_KILL);
	    }
	  return 0;
	}
      else
	{
	  /* It is a request we don't understand.  Respond with an
	     empty packet so that gdb knows that we don't support this
	     request.  */
	  cs.own_buf[0] = '\0';
	  break;
	}
    case 'v':
      /* Extended (long) request.  */
      handle_v_requests (cs.own_buf, packet_len, &new_packet_len);
      break;

    default:
      /* It is a request we don't understand.  Respond with an empty
	 packet so that gdb knows that we don't support this
	 request.  */
      cs.own_buf[0] = '\0';
      break;
    }

  if (new_packet_len != -1)
    putpkt_binary (cs.own_buf, new_packet_len);
  else
    putpkt (cs.own_buf);

  response_needed = false;

  if (exit_requested)
    return -1;

  return 0;
}

/* Event-loop callback for serial events.  */

void
handle_serial_event (int err, gdb_client_data client_data)
{
  threads_debug_printf ("handling possible serial event");

  /* Really handle it.  */
  if (process_serial_event () < 0)
    {
      keep_processing_events = false;
      return;
    }

  /* Be sure to not change the selected thread behind GDB's back.
     Important in the non-stop mode asynchronous protocol.  */
  set_desired_thread ();
}

/* Push a stop notification on the notification queue.  */

static void
push_stop_notification (ptid_t ptid, const target_waitstatus &status)
{
  struct vstop_notif *vstop_notif = new struct vstop_notif;

  vstop_notif->status = status;
  vstop_notif->ptid = ptid;
  /* Push Stop notification.  */
  notif_push (&notif_stop, vstop_notif);
}

/* Event-loop callback for target events.  */

void
handle_target_event (int err, gdb_client_data client_data)
{
  client_state &cs = get_client_state ();
  threads_debug_printf ("handling possible target event");

  cs.last_ptid = mywait (minus_one_ptid, &cs.last_status,
		      TARGET_WNOHANG, 1);

  if (cs.last_status.kind () == TARGET_WAITKIND_NO_RESUMED)
    {
      if (gdb_connected () && report_no_resumed)
	push_stop_notification (null_ptid, cs.last_status);
    }
  else if (cs.last_status.kind () != TARGET_WAITKIND_IGNORE)
    {
      int pid = cs.last_ptid.pid ();
      struct process_info *process = find_process_pid (pid);
      int forward_event = !gdb_connected () || process->gdb_detached;

      if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
	  || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED)
	{
	  mark_breakpoints_out (process);
	  target_mourn_inferior (cs.last_ptid);
	}
      else if (cs.last_status.kind () == TARGET_WAITKIND_THREAD_EXITED)
	;
      else
	{
	  /* We're reporting this thread as stopped.  Update its
	     "want-stopped" state to what the client wants, until it
	     gets a new resume action.  */
	  current_thread->last_resume_kind = resume_stop;
	  current_thread->last_status = cs.last_status;
	}

      if (forward_event)
	{
	  if (!target_running ())
	    {
	      /* The last process exited.  We're done.  */
	      exit (0);
	    }

	  if (cs.last_status.kind () == TARGET_WAITKIND_EXITED
	      || cs.last_status.kind () == TARGET_WAITKIND_SIGNALLED
	      || cs.last_status.kind () == TARGET_WAITKIND_THREAD_EXITED)
	    ;
	  else
	    {
	      /* A thread stopped with a signal, but gdb isn't
		 connected to handle it.  Pass it down to the
		 inferior, as if it wasn't being traced.  */
	      enum gdb_signal signal;

	      threads_debug_printf ("GDB not connected; forwarding event %d for"
				    " [%s]",
				    (int) cs.last_status.kind (),
				    target_pid_to_str (cs.last_ptid).c_str ());

	      if (cs.last_status.kind () == TARGET_WAITKIND_STOPPED)
		signal = cs.last_status.sig ();
	      else
		signal = GDB_SIGNAL_0;
	      target_continue (cs.last_ptid, signal);
	    }
	}
      else
	{
	  push_stop_notification (cs.last_ptid, cs.last_status);

	  if (cs.last_status.kind () == TARGET_WAITKIND_THREAD_EXITED
	      && !target_any_resumed ())
	    {
	      target_waitstatus ws;
	      ws.set_no_resumed ();
	      push_stop_notification (null_ptid, ws);
	    }
	}
    }

  /* Be sure to not change the selected thread behind GDB's back.
     Important in the non-stop mode asynchronous protocol.  */
  set_desired_thread ();
}

/* See gdbsupport/event-loop.h.  */

int
invoke_async_signal_handlers ()
{
  return 0;
}

/* See gdbsupport/event-loop.h.  */

int
check_async_event_handlers ()
{
  return 0;
}

/* See gdbsupport/errors.h  */

void
flush_streams ()
{
  fflush (stdout);
  fflush (stderr);
}

/* See gdbsupport/gdb_select.h.  */

int
gdb_select (int n, fd_set *readfds, fd_set *writefds,
	    fd_set *exceptfds, struct timeval *timeout)
{
  return select (n, readfds, writefds, exceptfds, timeout);
}

#if GDB_SELF_TEST
namespace selftests
{

void
reset ()
{}

} /* namespace selftests */
#endif /* GDB_SELF_TEST */
