]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/remote.c
gdb: remove target_section_table typedef
[thirdparty/binutils-gdb.git] / gdb / remote.c
index f78417b5de779659e1e3117a01cfd119916f42ce..b58dbd4cb66e064be3d2e82f5c9d596b0d2a740c 100644 (file)
@@ -1,6 +1,6 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
 
-   Copyright (C) 1988-2021 Free Software Foundation, Inc.
+   Copyright (C) 1988-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -30,7 +30,6 @@
 #include "process-stratum-target.h"
 #include "gdbcmd.h"
 #include "objfiles.h"
-#include "gdb-stabs.h"
 #include "gdbthread.h"
 #include "remote.h"
 #include "remote-notif.h"
@@ -59,7 +58,7 @@
 #include "gdbcore.h"
 
 #include "remote-fileio.h"
-#include "gdb/fileio.h"
+#include "gdbsupport/fileio.h"
 #include <sys/stat.h>
 #include "xml-support.h"
 
 #include "gdbsupport/agent.h"
 #include "btrace.h"
 #include "record-btrace.h"
-#include <algorithm>
 #include "gdbsupport/scoped_restore.h"
 #include "gdbsupport/environ.h"
 #include "gdbsupport/byte-vector.h"
 #include "gdbsupport/search.h"
 #include <algorithm>
+#include <iterator>
 #include <unordered_map>
 #include "async-event.h"
 #include "gdbsupport/selftest.h"
@@ -117,6 +116,36 @@ enum packet_support
     PACKET_DISABLE
   };
 
+/* Convert the packet support auto_boolean to a name used for gdb printing.  */
+
+static const char *
+get_packet_support_name (auto_boolean support)
+{
+  switch (support)
+    {
+      case AUTO_BOOLEAN_TRUE:
+       return "on";
+      case AUTO_BOOLEAN_FALSE:
+       return "off";
+      case AUTO_BOOLEAN_AUTO:
+       return "auto";
+      default:
+       gdb_assert_not_reached ("invalid var_auto_boolean");
+    }
+}
+
+/* Convert the target type (future remote target or currently connected target)
+   to a name used for gdb printing.  */
+
+static const char *
+get_target_type_name (bool target_connected)
+{
+  if (target_connected)
+    return _("on the current remote target");
+  else
+    return _("on future remote targets");
+}
+
 /* Analyze a packet's return value and update the packet config
    accordingly.  */
 
@@ -127,6 +156,155 @@ enum packet_result
   PACKET_UNKNOWN
 };
 
+/* Enumeration of packets for a remote target.  */
+
+enum {
+  PACKET_vCont = 0,
+  PACKET_X,
+  PACKET_qSymbol,
+  PACKET_P,
+  PACKET_p,
+  PACKET_Z0,
+  PACKET_Z1,
+  PACKET_Z2,
+  PACKET_Z3,
+  PACKET_Z4,
+  PACKET_vFile_setfs,
+  PACKET_vFile_open,
+  PACKET_vFile_pread,
+  PACKET_vFile_pwrite,
+  PACKET_vFile_close,
+  PACKET_vFile_unlink,
+  PACKET_vFile_readlink,
+  PACKET_vFile_fstat,
+  PACKET_qXfer_auxv,
+  PACKET_qXfer_features,
+  PACKET_qXfer_exec_file,
+  PACKET_qXfer_libraries,
+  PACKET_qXfer_libraries_svr4,
+  PACKET_qXfer_memory_map,
+  PACKET_qXfer_osdata,
+  PACKET_qXfer_threads,
+  PACKET_qXfer_statictrace_read,
+  PACKET_qXfer_traceframe_info,
+  PACKET_qXfer_uib,
+  PACKET_qGetTIBAddr,
+  PACKET_qGetTLSAddr,
+  PACKET_qSupported,
+  PACKET_qTStatus,
+  PACKET_QPassSignals,
+  PACKET_QCatchSyscalls,
+  PACKET_QProgramSignals,
+  PACKET_QSetWorkingDir,
+  PACKET_QStartupWithShell,
+  PACKET_QEnvironmentHexEncoded,
+  PACKET_QEnvironmentReset,
+  PACKET_QEnvironmentUnset,
+  PACKET_qCRC,
+  PACKET_qSearch_memory,
+  PACKET_vAttach,
+  PACKET_vRun,
+  PACKET_QStartNoAckMode,
+  PACKET_vKill,
+  PACKET_qXfer_siginfo_read,
+  PACKET_qXfer_siginfo_write,
+  PACKET_qAttached,
+
+  /* Support for conditional tracepoints.  */
+  PACKET_ConditionalTracepoints,
+
+  /* Support for target-side breakpoint conditions.  */
+  PACKET_ConditionalBreakpoints,
+
+  /* Support for target-side breakpoint commands.  */
+  PACKET_BreakpointCommands,
+
+  /* Support for fast tracepoints.  */
+  PACKET_FastTracepoints,
+
+  /* Support for static tracepoints.  */
+  PACKET_StaticTracepoints,
+
+  /* Support for installing tracepoints while a trace experiment is
+     running.  */
+  PACKET_InstallInTrace,
+
+  PACKET_bc,
+  PACKET_bs,
+  PACKET_TracepointSource,
+  PACKET_QAllow,
+  PACKET_qXfer_fdpic,
+  PACKET_QDisableRandomization,
+  PACKET_QAgent,
+  PACKET_QTBuffer_size,
+  PACKET_Qbtrace_off,
+  PACKET_Qbtrace_bts,
+  PACKET_Qbtrace_pt,
+  PACKET_qXfer_btrace,
+
+  /* Support for the QNonStop packet.  */
+  PACKET_QNonStop,
+
+  /* Support for the QThreadEvents packet.  */
+  PACKET_QThreadEvents,
+
+  /* Support for multi-process extensions.  */
+  PACKET_multiprocess_feature,
+
+  /* Support for enabling and disabling tracepoints while a trace
+     experiment is running.  */
+  PACKET_EnableDisableTracepoints_feature,
+
+  /* Support for collecting strings using the tracenz bytecode.  */
+  PACKET_tracenz_feature,
+
+  /* Support for continuing to run a trace experiment while GDB is
+     disconnected.  */
+  PACKET_DisconnectedTracing_feature,
+
+  /* Support for qXfer:libraries-svr4:read with a non-empty annex.  */
+  PACKET_augmented_libraries_svr4_read_feature,
+
+  /* Support for the qXfer:btrace-conf:read packet.  */
+  PACKET_qXfer_btrace_conf,
+
+  /* Support for the Qbtrace-conf:bts:size packet.  */
+  PACKET_Qbtrace_conf_bts_size,
+
+  /* Support for swbreak+ feature.  */
+  PACKET_swbreak_feature,
+
+  /* Support for hwbreak+ feature.  */
+  PACKET_hwbreak_feature,
+
+  /* Support for fork events.  */
+  PACKET_fork_event_feature,
+
+  /* Support for vfork events.  */
+  PACKET_vfork_event_feature,
+
+  /* Support for the Qbtrace-conf:pt:size packet.  */
+  PACKET_Qbtrace_conf_pt_size,
+
+  /* Support for exec events.  */
+  PACKET_exec_event_feature,
+
+  /* Support for query supported vCont actions.  */
+  PACKET_vContSupported,
+
+  /* Support remote CTRL-C.  */
+  PACKET_vCtrlC,
+
+  /* Support TARGET_WAITKIND_NO_RESUMED.  */
+  PACKET_no_resumed,
+
+  /* Support for memory tagging, allocation tag fetch/store
+     packets and the tag violation stop replies.  */
+  PACKET_memory_tagging_feature,
+
+  PACKET_MAX
+};
+
 struct threads_listing_context;
 
 /* Stub vCont actions support.
@@ -176,10 +354,7 @@ struct readahead_cache
   ULONGEST offset = 0;
 
   /* The buffer holding the cache contents.  */
-  gdb_byte *buf = nullptr;
-  /* The buffer's size.  We try to read as much as fits into a packet
-     at a time.  */
-  size_t bufsize = 0;
+  gdb::byte_vector buf;
 
   /* Cache hit and miss counters.  */
   ULONGEST hit_count = 0;
@@ -194,9 +369,9 @@ struct packet_reg
   long regnum; /* GDB's internal register number.  */
   LONGEST pnum; /* Remote protocol register number.  */
   int in_g_packet; /* Always part of G packet.  */
-  /* long size in bytes;  == register_size (target_gdbarch (), regnum);
+  /* long size in bytes;  == register_size (arch, regnum);
      at present.  */
-  /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
+  /* char *name; == gdbarch_register_name (arch, regnum);
      at present.  */
 };
 
@@ -238,6 +413,49 @@ public:
   /* Get the remote arch state for GDBARCH.  */
   struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch);
 
+  void create_async_event_handler ()
+  {
+    gdb_assert (m_async_event_handler_token == nullptr);
+    m_async_event_handler_token
+      = ::create_async_event_handler ([] (gdb_client_data data)
+                                     {
+                                       inferior_event_handler (INF_REG_EVENT);
+                                     },
+                                     nullptr, "remote");
+  }
+
+  void mark_async_event_handler ()
+  {
+    gdb_assert (this->is_async_p ());
+    ::mark_async_event_handler (m_async_event_handler_token);
+  }
+
+  void clear_async_event_handler ()
+  { ::clear_async_event_handler (m_async_event_handler_token); }
+
+  bool async_event_handler_marked () const
+  { return ::async_event_handler_marked (m_async_event_handler_token); }
+
+  void delete_async_event_handler ()
+  {
+    if (m_async_event_handler_token != nullptr)
+      ::delete_async_event_handler (&m_async_event_handler_token);
+  }
+
+  bool is_async_p () const
+  {
+    /* We're async whenever the serial device is.  */
+    gdb_assert (this->remote_desc != nullptr);
+    return serial_is_async_p (this->remote_desc);
+  }
+
+  bool can_async_p () const
+  {
+    /* We can async whenever the serial device can.  */
+    gdb_assert (this->remote_desc != nullptr);
+    return serial_can_async_p (this->remote_desc);
+  }
+
 public: /* data */
 
   /* A buffer to use for incoming packets, and its current size.  The
@@ -258,15 +476,6 @@ public: /* data */
      Otherwise zero, meaning to use the guessed size.  */
   long explicit_packet_size = 0;
 
-  /* remote_wait is normally called when the target is running and
-     waits for a stop reply packet.  But sometimes we need to call it
-     when the target is already stopped.  We can send a "?" packet
-     and have remote_wait read the response.  Or, if we already have
-     the response, we can stash it in BUF and tell remote_wait to
-     skip calling getpkt.  This flag is set when BUF contains a
-     stop reply packet and the target is not waiting.  */
-  int cached_wait_status = 0;
-
   /* True, if in no ack mode.  That is, neither GDB nor the stub will
      expect acks from each other.  The connection is assumed to be
      reliable.  */
@@ -285,9 +494,6 @@ public: /* data */
 
   /* The status of the stub support for the various vCont actions.  */
   vCont_action_support supports_vCont;
-  /* Whether vCont support was probed already.  This is a workaround
-     until packet_support is per-connection.  */
-  bool supports_vCont_probed;
 
   /* True if the user has pressed Ctrl-C, but the target hasn't
      responded to that.  */
@@ -377,10 +583,6 @@ public: /* data */
      immediately, so queue is not needed for them.  */
   std::vector<stop_reply_up> stop_reply_queue;
 
-  /* Asynchronous signal handle registered as event loop source for
-     when we have pending events ready to be passed to the core.  */
-  struct async_event_handler *remote_async_inferior_event_token = nullptr;
-
   /* FIXME: cagney/1999-09-23: Even though getpkt was called with
      ``forever'' still use the normal timeout mechanism.  This is
      currently used by the ASYNC code to guarentee that target reads
@@ -388,9 +590,13 @@ public: /* data */
      modified to return a timeout indication and, in turn
      remote_wait()/wait_for_inferior() have gained a timeout parameter
      this can go away.  */
-  int wait_forever_enabled_p = 1;
+  bool wait_forever_enabled_p = true;
 
 private:
+  /* Asynchronous signal handle registered as event loop source for
+     when we have pending events ready to be passed to the core.  */
+  async_event_handler *m_async_event_handler_token = nullptr;
+
   /* Mapping of remote protocol data for each gdbarch.  Usually there
      is only one entry here, though we may see more with stubs that
      support multi-process.  */
@@ -400,10 +606,134 @@ private:
 
 static const target_info remote_target_info = {
   "remote",
-  N_("Remote serial target in gdb-specific protocol"),
+  N_("Remote target using gdb-specific protocol"),
   remote_doc
 };
 
+/* Description of a remote packet.  */
+
+struct packet_description
+{
+  /* Name of the packet used for gdb output.  */
+  const char *name;
+
+  /* Title of the packet, used by the set/show remote name-packet
+     commands to identify the individual packages and gdb output.  */
+  const char *title;
+};
+
+/* Configuration of a remote packet.  */
+
+struct packet_config
+{
+  /* If auto, GDB auto-detects support for this packet or feature,
+     either through qSupported, or by trying the packet and looking
+     at the response.  If true, GDB assumes the target supports this
+     packet.  If false, the packet is disabled.  Configs that don't
+     have an associated command always have this set to auto.  */
+  enum auto_boolean detect;
+
+  /* Does the target support this packet?  */
+  enum packet_support support;
+};
+
+/* User configurable variables for the number of characters in a
+   memory read/write packet.  MIN (rsa->remote_packet_size,
+   rsa->sizeof_g_packet) is the default.  Some targets need smaller
+   values (fifo overruns, et.al.) and some users need larger values
+   (speed up transfers).  The variables ``preferred_*'' (the user
+   request), ``current_*'' (what was actually set) and ``forced_*''
+   (Positive - a soft limit, negative - a hard limit).  */
+
+struct memory_packet_config
+{
+  const char *name;
+  long size;
+  int fixed_p;
+};
+
+/* These global variables contain the default configuration for every new
+   remote_feature object.  */
+static memory_packet_config memory_read_packet_config =
+{
+  "memory-read-packet-size",
+};
+static memory_packet_config memory_write_packet_config =
+{
+  "memory-write-packet-size",
+};
+
+/* This global array contains packet descriptions (name and title).  */
+static packet_description packets_descriptions[PACKET_MAX];
+/* This global array contains the default configuration for every new
+   per-remote target array.  */
+static packet_config remote_protocol_packets[PACKET_MAX];
+
+/* Description of a remote target's features.  It stores the configuration
+   and provides functions to determine supported features of the target.  */
+
+struct remote_features
+{
+  remote_features ()
+  {
+    m_memory_read_packet_config = memory_read_packet_config;
+    m_memory_write_packet_config = memory_write_packet_config;
+
+    std::copy (std::begin (remote_protocol_packets),
+              std::end (remote_protocol_packets),
+              std::begin (m_protocol_packets));
+  }
+  ~remote_features () = default;
+
+  DISABLE_COPY_AND_ASSIGN (remote_features);
+
+  /* Returns whether a given packet defined by its enum value is supported.  */
+  enum packet_support packet_support (int) const;
+
+  /* Returns the packet's corresponding "set remote foo-packet" command
+     state.  See struct packet_config for more details.  */
+  enum auto_boolean packet_set_cmd_state (int packet) const
+  { return m_protocol_packets[packet].detect; }
+
+  /* Returns true if the multi-process extensions are in effect.  */
+  int remote_multi_process_p () const
+  { return packet_support (PACKET_multiprocess_feature) == PACKET_ENABLE; }
+
+  /* Returns true if fork events are supported.  */
+  int remote_fork_event_p () const
+  { return packet_support (PACKET_fork_event_feature) == PACKET_ENABLE; }
+
+  /* Returns true if vfork events are supported.  */
+  int remote_vfork_event_p () const
+  { return packet_support (PACKET_vfork_event_feature) == PACKET_ENABLE; }
+
+  /* Returns true if exec events are supported.  */
+  int remote_exec_event_p () const
+  { return packet_support (PACKET_exec_event_feature) == PACKET_ENABLE; }
+
+  /* Returns true if memory tagging is supported, false otherwise.  */
+  bool remote_memory_tagging_p () const
+  { return packet_support (PACKET_memory_tagging_feature) == PACKET_ENABLE; }
+
+  /* Reset all packets back to "unknown support".  Called when opening a
+     new connection to a remote target.  */
+  void reset_all_packet_configs_support ();
+
+/* Check result value in BUF for packet WHICH_PACKET and update the packet's
+   support configuration accordingly.  */
+  packet_result packet_ok (const char *buf, const int which_packet);
+  packet_result packet_ok (const gdb::char_vector &buf, const int which_packet);
+
+  /* Configuration of a remote target's memory read packet.  */
+  memory_packet_config m_memory_read_packet_config;
+  /* Configuration of a remote target's memory write packet.  */
+  memory_packet_config m_memory_write_packet_config;
+
+  /* The per-remote target array which stores a remote's packet
+     configurations.  */
+  packet_config m_protocol_packets[PACKET_MAX];
+};
+
 class remote_target : public process_stratum_target
 {
 public:
@@ -435,8 +765,6 @@ public:
   void store_registers (struct regcache *, int) override;
   void prepare_to_store (struct regcache *) override;
 
-  void files_info () override;
-
   int insert_breakpoint (struct gdbarch *, struct bp_target_info *) override;
 
   int remove_breakpoint (struct gdbarch *, struct bp_target_info *,
@@ -499,8 +827,8 @@ public:
                                             int handle_len,
                                             inferior *inf) override;
 
-  gdb::byte_vector thread_info_to_thread_handle (struct thread_info *tp)
-                                                override;
+  gdb::array_view<const gdb_byte> thread_info_to_thread_handle (struct thread_info *tp)
+    override;
 
   void stop (ptid_t) override;
 
@@ -519,7 +847,7 @@ public:
 
   void rcmd (const char *command, struct ui_file *output) override;
 
-  char *pid_to_exec_file (int pid) override;
+  const char *pid_to_exec_file (int pid) override;
 
   void log_command (const char *cmd) override
   {
@@ -548,7 +876,7 @@ public:
 
   bool is_async_p () override;
 
-  void async (int) override;
+  void async (bool) override;
 
   int async_wait_fd () override;
 
@@ -571,33 +899,41 @@ public:
 
   int fileio_open (struct inferior *inf, const char *filename,
                   int flags, int mode, int warn_if_slow,
-                  int *target_errno) override;
+                  fileio_error *target_errno) override;
 
   int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                    ULONGEST offset, int *target_errno) override;
+                    ULONGEST offset, fileio_error *target_errno) override;
 
   int fileio_pread (int fd, gdb_byte *read_buf, int len,
-                   ULONGEST offset, int *target_errno) override;
+                   ULONGEST offset, fileio_error *target_errno) override;
 
-  int fileio_fstat (int fd, struct stat *sb, int *target_errno) override;
+  int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override;
 
-  int fileio_close (int fd, int *target_errno) override;
+  int fileio_close (int fd, fileio_error *target_errno) override;
 
   int fileio_unlink (struct inferior *inf,
                     const char *filename,
-                    int *target_errno) override;
+                    fileio_error *target_errno) override;
 
   gdb::optional<std::string>
     fileio_readlink (struct inferior *inf,
                     const char *filename,
-                    int *target_errno) override;
+                    fileio_error *target_errno) override;
 
   bool supports_enable_disable_tracepoint () override;
 
   bool supports_string_tracing () override;
 
+  int remote_supports_cond_tracepoints ();
+
   bool supports_evaluation_of_breakpoint_conditions () override;
 
+  int remote_supports_fast_tracepoints ();
+
+  int remote_supports_static_tracepoints ();
+
+  int remote_supports_install_in_trace ();
+
   bool can_run_breakpoint_commands () override;
 
   void trace_init () override;
@@ -618,7 +954,7 @@ public:
 
   int get_trace_status (struct trace_status *ts) override;
 
-  void get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
+  void get_tracepoint_status (tracepoint *tp, struct uploaded_tp *utp)
     override;
 
   void trace_stop () override;
@@ -669,8 +1005,8 @@ public:
   bool use_agent (bool use) override;
   bool can_use_agent () override;
 
-  struct btrace_target_info *enable_btrace (ptid_t ptid,
-                                           const struct btrace_config *conf) override;
+  struct btrace_target_info *
+    enable_btrace (thread_info *tp, const struct btrace_config *conf) override;
 
   void disable_btrace (struct btrace_target_info *tinfo) override;
 
@@ -712,25 +1048,25 @@ public: /* Remote specific methods.  */
   void remote_file_delete (const char *remote_file, int from_tty);
 
   int remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
-                          ULONGEST offset, int *remote_errno);
+                          ULONGEST offset, fileio_error *remote_errno);
   int remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                           ULONGEST offset, int *remote_errno);
+                           ULONGEST offset, fileio_error *remote_errno);
   int remote_hostio_pread_vFile (int fd, gdb_byte *read_buf, int len,
-                                ULONGEST offset, int *remote_errno);
+                                ULONGEST offset, fileio_error *remote_errno);
 
   int remote_hostio_send_command (int command_bytes, int which_packet,
-                                 int *remote_errno, const char **attachment,
+                                 fileio_error *remote_errno, const char **attachment,
                                  int *attachment_len);
   int remote_hostio_set_filesystem (struct inferior *inf,
-                                   int *remote_errno);
+                                   fileio_error *remote_errno);
   /* We should get rid of this and use fileio_open directly.  */
   int remote_hostio_open (struct inferior *inf, const char *filename,
                          int flags, int mode, int warn_if_slow,
-                         int *remote_errno);
-  int remote_hostio_close (int fd, int *remote_errno);
+                         fileio_error *remote_errno);
+  int remote_hostio_close (int fd, fileio_error *remote_errno);
 
   int remote_hostio_unlink (inferior *inf, const char *filename,
-                           int *remote_errno);
+                           fileio_error *remote_errno);
 
   struct remote_state *get_remote_state ();
 
@@ -748,7 +1084,7 @@ public: /* Remote specific methods.  */
 
   char *append_resumption (char *p, char *endp,
                           ptid_t ptid, int step, gdb_signal siggnal);
-  int remote_resume_with_vcont (ptid_t ptid, int step,
+  int remote_resume_with_vcont (ptid_t scope_ptid, int step,
                                gdb_signal siggnal);
 
   thread_info *add_current_inferior_and_thread (const char *wait_status);
@@ -769,14 +1105,15 @@ public: /* Remote specific methods.  */
   void print_one_stopped_thread (thread_info *thread);
   void process_initial_stop_replies (int from_tty);
 
-  thread_info *remote_add_thread (ptid_t ptid, bool running, bool executing);
+  thread_info *remote_add_thread (ptid_t ptid, bool running, bool executing,
+                                 bool silent_p);
 
   void btrace_sync_conf (const btrace_config *conf);
 
   void remote_btrace_maybe_reopen ();
 
   void remove_new_fork_children (threads_listing_context *context);
-  void kill_new_fork_children (int pid);
+  void kill_new_fork_children (inferior *inf);
   void discard_pending_stop_replies (struct inferior *inf);
   int stop_reply_queue_length ();
 
@@ -855,7 +1192,7 @@ public: /* Remote specific methods.  */
   void send_interrupt_sequence ();
   void interrupt_query ();
 
-  void remote_notif_get_pending_events (notif_client *nc);
+  void remote_notif_get_pending_events (const notif_client *nc);
 
   int fetch_register_using_p (struct regcache *regcache,
                              packet_reg *reg);
@@ -919,12 +1256,8 @@ public: /* Remote specific methods.  */
 
   void skip_frame ();
   long read_frame (gdb::char_vector *buf_p);
-  void getpkt (gdb::char_vector *buf, int forever);
-  int getpkt_or_notif_sane_1 (gdb::char_vector *buf, int forever,
-                             int expecting_notif, int *is_notif);
-  int getpkt_sane (gdb::char_vector *buf, int forever);
-  int getpkt_or_notif_sane (gdb::char_vector *buf, int forever,
-                           int *is_notif);
+  int getpkt (gdb::char_vector *buf, bool forever = false,
+             bool *is_notif = nullptr);
   int remote_vkill (int pid);
   void remote_kill_k ();
 
@@ -943,19 +1276,21 @@ public: /* Remote specific methods.  */
                                         const gdb_byte *writebuf,
                                         ULONGEST offset, LONGEST len,
                                         ULONGEST *xfered_len,
-                                        struct packet_config *packet);
+                                        const unsigned int which_packet);
 
   target_xfer_status remote_read_qxfer (const char *object_name,
                                        const char *annex,
                                        gdb_byte *readbuf, ULONGEST offset,
                                        LONGEST len,
                                        ULONGEST *xfered_len,
-                                       struct packet_config *packet);
+                                       const unsigned int which_packet);
 
   void push_stop_reply (struct stop_reply *new_event);
 
   bool vcont_r_supported ();
 
+  remote_features m_features;
+
 private:
 
   bool start_remote_1 (int from_tty, int extended_p);
@@ -967,7 +1302,7 @@ private:
 
 static const target_info extended_remote_target_info = {
   "extended-remote",
-  N_("Extended remote serial target in gdb-specific protocol"),
+  N_("Extended remote target using gdb-specific protocol"),
   remote_doc
 };
 
@@ -1026,22 +1361,29 @@ struct stop_reply : public notif_event
   int core;
 };
 
+/* Return TARGET as a remote_target if it is one, else nullptr.  */
+
+static remote_target *
+as_remote_target (process_stratum_target *target)
+{
+  return dynamic_cast<remote_target *> (target);
+}
+
 /* See remote.h.  */
 
 bool
 is_remote_target (process_stratum_target *target)
 {
-  remote_target *rt = dynamic_cast<remote_target *> (target);
-  return rt != nullptr;
+  return as_remote_target (target) != nullptr;
 }
 
 /* Per-program-space data key.  */
-static const struct program_space_key<char, gdb::xfree_deleter<char>>
+static const registry<program_space>::key<char, gdb::xfree_deleter<char>>
   remote_pspace_data;
 
 /* The variable registered as the control variable used by the
    remote exec-file commands.  While the remote exec-file setting is
-   per-program-space, the set/show machinery uses this as the 
+   per-program-space, the set/show machinery uses this as the
    location of the remote exec-file value.  */
 static std::string remote_exec_file_var;
 
@@ -1071,9 +1413,12 @@ static CORE_ADDR remote_address_masked (CORE_ADDR);
 
 static int stub_unpack_int (const char *buff, int fieldlength);
 
-struct packet_config;
+static void set_remote_protocol_packet_cmd (const char *args, int from_tty,
+                                           cmd_list_element *c);
 
-static void show_packet_config_cmd (struct packet_config *config);
+static void show_packet_config_cmd (ui_file *file,
+                                   const unsigned int which_packet,
+                                   remote_target *remote);
 
 static void show_remote_protocol_packet_cmd (struct ui_file *file,
                                             int from_tty,
@@ -1082,8 +1427,6 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file,
 
 static ptid_t read_ptid (const char *buf, const char **obuf);
 
-static void remote_async_inferior_event_handler (gdb_client_data);
-
 static bool remote_read_description_p (struct target_ops *target);
 
 static void remote_console_output (const char *msg);
@@ -1256,7 +1599,7 @@ remote_target::remote_get_noisy_reply ()
       char *buf;
 
       QUIT;                    /* Allow user to bail out with ^C.  */
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       buf = rs->buf.data ();
       if (buf[0] == 'E')
        trace_error (buf);
@@ -1282,7 +1625,8 @@ remote_target::remote_get_noisy_reply ()
 
          try
            {
-             gdbarch_relocate_instruction (target_gdbarch (), &to, from);
+             gdbarch_relocate_instruction (current_inferior ()->arch (),
+                                           &to, from);
              relocated = 1;
            }
          catch (const gdb_exception &ex)
@@ -1355,7 +1699,7 @@ remote_target::get_remote_state ()
      function which calls getpkt also needs to be mindful of changes
      to rs->buf, but this call limits the number of places which run
      into trouble.  */
-  m_remote_state.get_remote_arch_state (target_gdbarch ());
+  m_remote_state.get_remote_arch_state (current_inferior ()->arch ());
 
   return &m_remote_state;
 }
@@ -1402,7 +1746,7 @@ static void
 show_remote_exec_file (struct ui_file *file, int from_tty,
                       struct cmd_list_element *cmd, const char *value)
 {
-  fprintf_filtered (file, "%s\n", get_remote_exec_file ());
+  gdb_printf (file, "%s\n", get_remote_exec_file ());
 }
 
 static int
@@ -1521,7 +1865,8 @@ long
 remote_target::get_remote_packet_size ()
 {
   struct remote_state *rs = get_remote_state ();
-  remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
+  remote_arch_state *rsa
+    = rs->get_remote_arch_state (current_inferior ()->arch ());
 
   if (rs->explicit_packet_size)
     return rs->explicit_packet_size;
@@ -1584,22 +1929,21 @@ show_interrupt_sequence (struct ui_file *file, int from_tty,
                         const char *value)
 {
   if (interrupt_sequence_mode == interrupt_sequence_control_c)
-    fprintf_filtered (file,
-                     _("Send the ASCII ETX character (Ctrl-c) "
-                       "to the remote target to interrupt the "
-                       "execution of the program.\n"));
+    gdb_printf (file,
+               _("Send the ASCII ETX character (Ctrl-c) "
+                 "to the remote target to interrupt the "
+                 "execution of the program.\n"));
   else if (interrupt_sequence_mode == interrupt_sequence_break)
-    fprintf_filtered (file,
-                     _("send a break signal to the remote target "
-                       "to interrupt the execution of the program.\n"));
+    gdb_printf (file,
+               _("send a break signal to the remote target "
+                 "to interrupt the execution of the program.\n"));
   else if (interrupt_sequence_mode == interrupt_sequence_break_g)
-    fprintf_filtered (file,
-                     _("Send a break signal and 'g' a.k.a. Magic SysRq g to "
-                       "the remote target to interrupt the execution "
-                       "of Linux kernel.\n"));
+    gdb_printf (file,
+               _("Send a break signal and 'g' a.k.a. Magic SysRq g to "
+                 "the remote target to interrupt the execution "
+                 "of Linux kernel.\n"));
   else
-    internal_error (__FILE__, __LINE__,
-                   _("Invalid value for interrupt_sequence_mode: %s."),
+    internal_error (_("Invalid value for interrupt_sequence_mode: %s."),
                    interrupt_sequence_mode);
 }
 
@@ -1644,21 +1988,6 @@ show_remotebreak (struct ui_file *file, int from_tty,
 static unsigned int remote_address_size;
 
 \f
-/* User configurable variables for the number of characters in a
-   memory read/write packet.  MIN (rsa->remote_packet_size,
-   rsa->sizeof_g_packet) is the default.  Some targets need smaller
-   values (fifo overruns, et.al.) and some users need larger values
-   (speed up transfers).  The variables ``preferred_*'' (the user
-   request), ``current_*'' (what was actually set) and ``forced_*''
-   (Positive - a soft limit, negative - a hard limit).  */
-
-struct memory_packet_config
-{
-  const char *name;
-  long size;
-  int fixed_p;
-};
-
 /* The default max memory-write-packet-size, when the setting is
    "fixed".  The 16k is historical.  (It came from older GDB's using
    alloca for buffers and the knowledge (folklore?) that some hosts
@@ -1689,7 +2018,8 @@ long
 remote_target::get_memory_packet_size (struct memory_packet_config *config)
 {
   struct remote_state *rs = get_remote_state ();
-  remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
+  remote_arch_state *rsa
+    = rs->get_remote_arch_state (current_inferior ()->arch ());
 
   long what_they_get;
   if (config->fixed_p)
@@ -1724,13 +2054,14 @@ remote_target::get_memory_packet_size (struct memory_packet_config *config)
    something really big then do a sanity check.  */
 
 static void
-set_memory_packet_size (const char *args, struct memory_packet_config *config)
+set_memory_packet_size (const char *args, struct memory_packet_config *config,
+                       bool target_connected)
 {
   int fixed_p = config->fixed_p;
   long size = config->size;
 
   if (args == NULL)
-    error (_("Argument required (integer, `fixed' or `limited')."));
+    error (_("Argument required (integer, \"fixed\" or \"limit\")."));
   else if (strcmp (args, "hard") == 0
       || strcmp (args, "fixed") == 0)
     fixed_p = 1;
@@ -1758,55 +2089,90 @@ set_memory_packet_size (const char *args, struct memory_packet_config *config)
                         ? DEFAULT_MAX_MEMORY_PACKET_SIZE_FIXED
                         : size);
 
-      if (! query (_("The target may not be able to correctly handle a %s\n"
-                  "of %ld bytes. Change the packet size? "),
-                  config->name, query_size))
+      if (target_connected
+         && !query (_("The target may not be able to correctly handle a %s\n"
+                      "of %ld bytes.  Change the packet size? "),
+                    config->name, query_size))
+       error (_("Packet size not changed."));
+      else if (!target_connected
+              && !query (_("Future remote targets may not be able to "
+                           "correctly handle a %s\nof %ld bytes.  Change the "
+                           "packet size for future remote targets? "),
+                         config->name, query_size))
        error (_("Packet size not changed."));
     }
   /* Update the config.  */
   config->fixed_p = fixed_p;
   config->size = size;
+
+  const char *target_type = get_target_type_name (target_connected);
+  gdb_printf (_("The %s %s is set to \"%s\".\n"), config->name, target_type,
+             args);
+
 }
 
+/* Show the memory-read or write-packet size configuration CONFIG of the
+   target REMOTE.  If REMOTE is nullptr, the default configuration for future
+   remote targets should be passed in CONFIG.  */
+
 static void
-show_memory_packet_size (struct memory_packet_config *config)
+show_memory_packet_size (memory_packet_config *config, remote_target *remote)
 {
+  const char *target_type = get_target_type_name (remote != nullptr);
+
   if (config->size == 0)
-    printf_filtered (_("The %s is 0 (default). "), config->name);
+    gdb_printf (_("The %s %s is 0 (default). "), config->name, target_type);
   else
-    printf_filtered (_("The %s is %ld. "), config->name, config->size);
+    gdb_printf (_("The %s %s is %ld. "), config->name, target_type,
+               config->size);
+
   if (config->fixed_p)
-    printf_filtered (_("Packets are fixed at %ld bytes.\n"),
-                    get_fixed_memory_packet_size (config));
+    gdb_printf (_("Packets are fixed at %ld bytes.\n"),
+               get_fixed_memory_packet_size (config));
   else
     {
-      remote_target *remote = get_current_remote_target ();
-
-      if (remote != NULL)
-       printf_filtered (_("Packets are limited to %ld bytes.\n"),
-                        remote->get_memory_packet_size (config));
+      if (remote != nullptr)
+       gdb_printf (_("Packets are limited to %ld bytes.\n"),
+                   remote->get_memory_packet_size (config));
       else
-       puts_filtered ("The actual limit will be further reduced "
-                      "dependent on the target.\n");
+       gdb_puts ("The actual limit will be further reduced "
+                 "dependent on the target.\n");
     }
 }
 
-/* FIXME: needs to be per-remote-target.  */
-static struct memory_packet_config memory_write_packet_config =
-{
-  "memory-write-packet-size",
-};
+/* Configure the memory-write-packet size of the currently selected target.  If
+   no target is available, the default configuration for future remote targets
+   is configured.  */
 
 static void
 set_memory_write_packet_size (const char *args, int from_tty)
 {
-  set_memory_packet_size (args, &memory_write_packet_config);
+  remote_target *remote = get_current_remote_target ();
+  if (remote != nullptr)
+    {
+      set_memory_packet_size
+       (args, &remote->m_features.m_memory_write_packet_config, true);
+    }
+  else
+    {
+      memory_packet_config* config = &memory_write_packet_config;
+      set_memory_packet_size (args, config, false);
+    }
 }
 
+/* Display the memory-write-packet size of the currently selected target.  If
+   no target is available, the default configuration for future remote targets
+   is shown.  */
+
 static void
 show_memory_write_packet_size (const char *args, int from_tty)
 {
-  show_memory_packet_size (&memory_write_packet_config);
+  remote_target *remote = get_current_remote_target ();
+  if (remote != nullptr)
+    show_memory_packet_size (&remote->m_features.m_memory_write_packet_config,
+                            remote);
+  else
+    show_memory_packet_size (&memory_write_packet_config, nullptr);
 }
 
 /* Show the number of hardware watchpoints that can be used.  */
@@ -1816,8 +2182,8 @@ show_hardware_watchpoint_limit (struct ui_file *file, int from_tty,
                                struct cmd_list_element *c,
                                const char *value)
 {
-  fprintf_filtered (file, _("The maximum number of target hardware "
-                           "watchpoints is %s.\n"), value);
+  gdb_printf (file, _("The maximum number of target hardware "
+                     "watchpoints is %s.\n"), value);
 }
 
 /* Show the length limit (in bytes) for hardware watchpoints.  */
@@ -1827,8 +2193,8 @@ show_hardware_watchpoint_length_limit (struct ui_file *file, int from_tty,
                                       struct cmd_list_element *c,
                                       const char *value)
 {
-  fprintf_filtered (file, _("The maximum length (in bytes) of a target "
-                           "hardware watchpoint is %s.\n"), value);
+  gdb_printf (file, _("The maximum length (in bytes) of a target "
+                     "hardware watchpoint is %s.\n"), value);
 }
 
 /* Show the number of hardware breakpoints that can be used.  */
@@ -1838,8 +2204,8 @@ show_hardware_breakpoint_limit (struct ui_file *file, int from_tty,
                                struct cmd_list_element *c,
                                const char *value)
 {
-  fprintf_filtered (file, _("The maximum number of target hardware "
-                           "breakpoints is %s.\n"), value);
+  gdb_printf (file, _("The maximum number of target hardware "
+                     "breakpoints is %s.\n"), value);
 }
 
 /* Controls the maximum number of characters to display in the debug output
@@ -1855,38 +2221,54 @@ show_remote_packet_max_chars (struct ui_file *file, int from_tty,
                              struct cmd_list_element *c,
                              const char *value)
 {
-  fprintf_filtered (file, _("Number of remote packet characters to "
-                           "display is %s.\n"), value);
+  gdb_printf (file, _("Number of remote packet characters to "
+                     "display is %s.\n"), value);
 }
 
 long
 remote_target::get_memory_write_packet_size ()
 {
-  return get_memory_packet_size (&memory_write_packet_config);
+  return get_memory_packet_size (&m_features.m_memory_write_packet_config);
 }
 
-/* FIXME: needs to be per-remote-target.  */
-static struct memory_packet_config memory_read_packet_config =
-{
-  "memory-read-packet-size",
-};
+/* Configure the memory-read-packet size of the currently selected target.  If
+   no target is available, the default configuration for future remote targets
+   is adapted.  */
 
 static void
 set_memory_read_packet_size (const char *args, int from_tty)
 {
-  set_memory_packet_size (args, &memory_read_packet_config);
+  remote_target *remote = get_current_remote_target ();
+  if (remote != nullptr)
+    set_memory_packet_size
+      (args, &remote->m_features.m_memory_read_packet_config, true);
+  else
+    {
+      memory_packet_config* config = &memory_read_packet_config;
+      set_memory_packet_size (args, config, false);
+    }
+
 }
 
+/* Display the memory-read-packet size of the currently selected target.  If
+   no target is available, the default configuration for future remote targets
+   is shown.  */
+
 static void
 show_memory_read_packet_size (const char *args, int from_tty)
 {
-  show_memory_packet_size (&memory_read_packet_config);
+  remote_target *remote = get_current_remote_target ();
+  if (remote != nullptr)
+    show_memory_packet_size (&remote->m_features.m_memory_read_packet_config,
+                            remote);
+  else
+    show_memory_packet_size (&memory_read_packet_config, nullptr);
 }
 
 long
 remote_target::get_memory_read_packet_size ()
 {
-  long size = get_memory_packet_size (&memory_read_packet_config);
+  long size = get_memory_packet_size (&m_features.m_memory_read_packet_config);
 
   /* FIXME: cagney/1999-11-07: Functions like getpkt() need to get an
      extra buffer size argument before the memory read size can be
@@ -1896,34 +2278,52 @@ remote_target::get_memory_read_packet_size ()
   return size;
 }
 
-\f
+static enum packet_support packet_config_support (const packet_config *config);
 
-struct packet_config
-  {
-    const char *name;
-    const char *title;
 
-    /* If auto, GDB auto-detects support for this packet or feature,
-       either through qSupported, or by trying the packet and looking
-       at the response.  If true, GDB assumes the target supports this
-       packet.  If false, the packet is disabled.  Configs that don't
-       have an associated command always have this set to auto.  */
-    enum auto_boolean detect;
+static void
+set_remote_protocol_packet_cmd (const char *args, int from_tty,
+                               cmd_list_element *c)
+{
+  remote_target *remote = get_current_remote_target ();
+  gdb_assert (c->var.has_value ());
 
-    /* The "show remote foo-packet" command created for this packet.  */
-    cmd_list_element *show_cmd;
+  auto *default_config = static_cast<packet_config *> (c->context ());
+  const int packet_idx = std::distance (remote_protocol_packets,
+                                       default_config);
 
-    /* Does the target support this packet?  */
-    enum packet_support support;
-  };
+  if (packet_idx >= 0 && packet_idx < PACKET_MAX)
+    {
+      const char *name = packets_descriptions[packet_idx].name;
+      const auto_boolean value = c->var->get<auto_boolean> ();
+      const char *support = get_packet_support_name (value);
+      const char *target_type = get_target_type_name (remote != nullptr);
+
+      if (remote != nullptr)
+       remote->m_features.m_protocol_packets[packet_idx].detect = value;
+      else
+       remote_protocol_packets[packet_idx].detect = value;
 
-static enum packet_support packet_config_support (struct packet_config *config);
-static enum packet_support packet_support (int packet);
+      gdb_printf (_("Support for the '%s' packet %s is set to \"%s\".\n"), name,
+                 target_type, support);
+      return;
+    }
+
+  internal_error (_("Could not find config for %s"), c->name);
+}
 
 static void
-show_packet_config_cmd (struct packet_config *config)
+show_packet_config_cmd (ui_file *file, const unsigned int which_packet,
+                       remote_target *remote)
 {
   const char *support = "internal-error";
+  const char *target_type = get_target_type_name (remote != nullptr);
+
+  packet_config *config;
+  if (remote != nullptr)
+    config = &remote->m_features.m_protocol_packets[which_packet];
+  else
+    config = &remote_protocol_packets[which_packet];
 
   switch (packet_config_support (config))
     {
@@ -1940,24 +2340,31 @@ show_packet_config_cmd (struct packet_config *config)
   switch (config->detect)
     {
     case AUTO_BOOLEAN_AUTO:
-      printf_filtered (_("Support for the `%s' packet "
-                        "is auto-detected, currently %s.\n"),
-                      config->name, support);
+      gdb_printf (file,
+                 _("Support for the '%s' packet %s is \"auto\", "
+                   "currently %s.\n"),
+                 packets_descriptions[which_packet].name, target_type,
+                 support);
       break;
     case AUTO_BOOLEAN_TRUE:
     case AUTO_BOOLEAN_FALSE:
-      printf_filtered (_("Support for the `%s' packet is currently %s.\n"),
-                      config->name, support);
+      gdb_printf (file,
+                 _("Support for the '%s' packet %s is \"%s\".\n"),
+                 packets_descriptions[which_packet].name, target_type,
+                 get_packet_support_name (config->detect));
       break;
     }
 }
 
 static void
-add_packet_config_cmd (struct packet_config *config, const char *name,
+add_packet_config_cmd (const unsigned int which_packet, const char *name,
                       const char *title, int legacy)
 {
-  config->name = name;
-  config->title = title;
+  packets_descriptions[which_packet].name = name;
+  packets_descriptions[which_packet].title = title;
+
+  packet_config *config = &remote_protocol_packets[which_packet];
+
   gdb::unique_xmalloc_ptr<char> set_doc
     = xstrprintf ("Set use of remote protocol `%s' (%s) packet.",
                  name, title);
@@ -1970,23 +2377,26 @@ add_packet_config_cmd (struct packet_config *config, const char *name,
     = add_setshow_auto_boolean_cmd (cmd_name.release (), class_obscure,
                                    &config->detect, set_doc.get (),
                                    show_doc.get (), NULL, /* help_doc */
-                                   NULL,
+                                   set_remote_protocol_packet_cmd,
                                    show_remote_protocol_packet_cmd,
                                    &remote_set_cmdlist, &remote_show_cmdlist);
-  config->show_cmd = cmds.show;
+  cmds.show->set_context (config);
+  cmds.set->set_context (config);
 
   /* set/show remote NAME-packet {auto,on,off} -- legacy.  */
   if (legacy)
     {
-      /* It's not clear who should take ownership of this string, so, for
-        now, make it static, and give copies to each of the add_alias_cmd
-        calls below.  */
-      static gdb::unique_xmalloc_ptr<char> legacy_name
+      /* It's not clear who should take ownership of the LEGACY_NAME string
+        created below, so, for now, place the string into a static vector
+        which ensures the strings is released when GDB exits.  */
+      static std::vector<gdb::unique_xmalloc_ptr<char>> legacy_names;
+      gdb::unique_xmalloc_ptr<char> legacy_name
        = xstrprintf ("%s-packet", name);
       add_alias_cmd (legacy_name.get (), cmds.set, class_obscure, 0,
                     &remote_set_cmdlist);
       add_alias_cmd (legacy_name.get (), cmds.show, class_obscure, 0,
                     &remote_show_cmdlist);
+      legacy_names.emplace_back (std::move (legacy_name));
     }
 }
 
@@ -2012,230 +2422,71 @@ packet_check_result (const char *buf)
       return PACKET_OK;
     }
   else
-    /* The stub does not support the packet.  */
-    return PACKET_UNKNOWN;
-}
-
-static enum packet_result
-packet_check_result (const gdb::char_vector &buf)
-{
-  return packet_check_result (buf.data ());
-}
-
-static enum packet_result
-packet_ok (const char *buf, struct packet_config *config)
-{
-  enum packet_result result;
-
-  if (config->detect != AUTO_BOOLEAN_TRUE
-      && config->support == PACKET_DISABLE)
-    internal_error (__FILE__, __LINE__,
-                   _("packet_ok: attempt to use a disabled packet"));
-
-  result = packet_check_result (buf);
-  switch (result)
-    {
-    case PACKET_OK:
-    case PACKET_ERROR:
-      /* The stub recognized the packet request.  */
-      if (config->support == PACKET_SUPPORT_UNKNOWN)
-       {
-         remote_debug_printf ("Packet %s (%s) is supported",
-                              config->name, config->title);
-         config->support = PACKET_ENABLE;
-       }
-      break;
-    case PACKET_UNKNOWN:
-      /* The stub does not support the packet.  */
-      if (config->detect == AUTO_BOOLEAN_AUTO
-         && config->support == PACKET_ENABLE)
-       {
-         /* If the stub previously indicated that the packet was
-            supported then there is a protocol error.  */
-         error (_("Protocol error: %s (%s) conflicting enabled responses."),
-                config->name, config->title);
-       }
-      else if (config->detect == AUTO_BOOLEAN_TRUE)
-       {
-         /* The user set it wrong.  */
-         error (_("Enabled packet %s (%s) not recognized by stub"),
-                config->name, config->title);
-       }
-
-      remote_debug_printf ("Packet %s (%s) is NOT supported",
-                          config->name, config->title);
-      config->support = PACKET_DISABLE;
-      break;
-    }
-
-  return result;
-}
-
-static enum packet_result
-packet_ok (const gdb::char_vector &buf, struct packet_config *config)
-{
-  return packet_ok (buf.data (), config);
-}
-
-enum {
-  PACKET_vCont = 0,
-  PACKET_X,
-  PACKET_qSymbol,
-  PACKET_P,
-  PACKET_p,
-  PACKET_Z0,
-  PACKET_Z1,
-  PACKET_Z2,
-  PACKET_Z3,
-  PACKET_Z4,
-  PACKET_vFile_setfs,
-  PACKET_vFile_open,
-  PACKET_vFile_pread,
-  PACKET_vFile_pwrite,
-  PACKET_vFile_close,
-  PACKET_vFile_unlink,
-  PACKET_vFile_readlink,
-  PACKET_vFile_fstat,
-  PACKET_qXfer_auxv,
-  PACKET_qXfer_features,
-  PACKET_qXfer_exec_file,
-  PACKET_qXfer_libraries,
-  PACKET_qXfer_libraries_svr4,
-  PACKET_qXfer_memory_map,
-  PACKET_qXfer_osdata,
-  PACKET_qXfer_threads,
-  PACKET_qXfer_statictrace_read,
-  PACKET_qXfer_traceframe_info,
-  PACKET_qXfer_uib,
-  PACKET_qGetTIBAddr,
-  PACKET_qGetTLSAddr,
-  PACKET_qSupported,
-  PACKET_qTStatus,
-  PACKET_QPassSignals,
-  PACKET_QCatchSyscalls,
-  PACKET_QProgramSignals,
-  PACKET_QSetWorkingDir,
-  PACKET_QStartupWithShell,
-  PACKET_QEnvironmentHexEncoded,
-  PACKET_QEnvironmentReset,
-  PACKET_QEnvironmentUnset,
-  PACKET_qCRC,
-  PACKET_qSearch_memory,
-  PACKET_vAttach,
-  PACKET_vRun,
-  PACKET_QStartNoAckMode,
-  PACKET_vKill,
-  PACKET_qXfer_siginfo_read,
-  PACKET_qXfer_siginfo_write,
-  PACKET_qAttached,
-
-  /* Support for conditional tracepoints.  */
-  PACKET_ConditionalTracepoints,
-
-  /* Support for target-side breakpoint conditions.  */
-  PACKET_ConditionalBreakpoints,
-
-  /* Support for target-side breakpoint commands.  */
-  PACKET_BreakpointCommands,
-
-  /* Support for fast tracepoints.  */
-  PACKET_FastTracepoints,
-
-  /* Support for static tracepoints.  */
-  PACKET_StaticTracepoints,
-
-  /* Support for installing tracepoints while a trace experiment is
-     running.  */
-  PACKET_InstallInTrace,
-
-  PACKET_bc,
-  PACKET_bs,
-  PACKET_TracepointSource,
-  PACKET_QAllow,
-  PACKET_qXfer_fdpic,
-  PACKET_QDisableRandomization,
-  PACKET_QAgent,
-  PACKET_QTBuffer_size,
-  PACKET_Qbtrace_off,
-  PACKET_Qbtrace_bts,
-  PACKET_Qbtrace_pt,
-  PACKET_qXfer_btrace,
-
-  /* Support for the QNonStop packet.  */
-  PACKET_QNonStop,
-
-  /* Support for the QThreadEvents packet.  */
-  PACKET_QThreadEvents,
-
-  /* Support for multi-process extensions.  */
-  PACKET_multiprocess_feature,
-
-  /* Support for enabling and disabling tracepoints while a trace
-     experiment is running.  */
-  PACKET_EnableDisableTracepoints_feature,
-
-  /* Support for collecting strings using the tracenz bytecode.  */
-  PACKET_tracenz_feature,
-
-  /* Support for continuing to run a trace experiment while GDB is
-     disconnected.  */
-  PACKET_DisconnectedTracing_feature,
-
-  /* Support for qXfer:libraries-svr4:read with a non-empty annex.  */
-  PACKET_augmented_libraries_svr4_read_feature,
-
-  /* Support for the qXfer:btrace-conf:read packet.  */
-  PACKET_qXfer_btrace_conf,
-
-  /* Support for the Qbtrace-conf:bts:size packet.  */
-  PACKET_Qbtrace_conf_bts_size,
-
-  /* Support for swbreak+ feature.  */
-  PACKET_swbreak_feature,
-
-  /* Support for hwbreak+ feature.  */
-  PACKET_hwbreak_feature,
-
-  /* Support for fork events.  */
-  PACKET_fork_event_feature,
-
-  /* Support for vfork events.  */
-  PACKET_vfork_event_feature,
-
-  /* Support for the Qbtrace-conf:pt:size packet.  */
-  PACKET_Qbtrace_conf_pt_size,
-
-  /* Support for exec events.  */
-  PACKET_exec_event_feature,
+    /* The stub does not support the packet.  */
+    return PACKET_UNKNOWN;
+}
 
-  /* Support for query supported vCont actions.  */
-  PACKET_vContSupported,
+static enum packet_result
+packet_check_result (const gdb::char_vector &buf)
+{
+  return packet_check_result (buf.data ());
+}
 
-  /* Support remote CTRL-C.  */
-  PACKET_vCtrlC,
+packet_result
+remote_features::packet_ok (const char *buf, const int which_packet)
+{
+  packet_config *config = &m_protocol_packets[which_packet];
+  packet_description *descr = &packets_descriptions[which_packet];
 
-  /* Support TARGET_WAITKIND_NO_RESUMED.  */
-  PACKET_no_resumed,
+  enum packet_result result;
 
-  /* Support for memory tagging, allocation tag fetch/store
-     packets and the tag violation stop replies.  */
-  PACKET_memory_tagging_feature,
+  if (config->detect != AUTO_BOOLEAN_TRUE
+      && config->support == PACKET_DISABLE)
+    internal_error (_("packet_ok: attempt to use a disabled packet"));
 
-  PACKET_MAX
-};
+  result = packet_check_result (buf);
+  switch (result)
+    {
+    case PACKET_OK:
+    case PACKET_ERROR:
+      /* The stub recognized the packet request.  */
+      if (config->support == PACKET_SUPPORT_UNKNOWN)
+       {
+         remote_debug_printf ("Packet %s (%s) is supported",
+                              descr->name, descr->title);
+         config->support = PACKET_ENABLE;
+       }
+      break;
+    case PACKET_UNKNOWN:
+      /* The stub does not support the packet.  */
+      if (config->detect == AUTO_BOOLEAN_AUTO
+         && config->support == PACKET_ENABLE)
+       {
+         /* If the stub previously indicated that the packet was
+            supported then there is a protocol error.  */
+         error (_("Protocol error: %s (%s) conflicting enabled responses."),
+                descr->name, descr->title);
+       }
+      else if (config->detect == AUTO_BOOLEAN_TRUE)
+       {
+         /* The user set it wrong.  */
+         error (_("Enabled packet %s (%s) not recognized by stub"),
+                descr->name, descr->title);
+       }
 
-/* FIXME: needs to be per-remote-target.  Ignoring this for now,
-   assuming all remote targets are the same server (thus all support
-   the same packets).  */
-static struct packet_config remote_protocol_packets[PACKET_MAX];
+      remote_debug_printf ("Packet %s (%s) is NOT supported", descr->name,
+                          descr->title);
+      config->support = PACKET_DISABLE;
+      break;
+    }
 
-/* Returns the packet's corresponding "set remote foo-packet" command
-   state.  See struct packet_config for more details.  */
+  return result;
+}
 
-static enum auto_boolean
-packet_set_cmd_state (int packet)
+packet_result
+remote_features::packet_ok (const gdb::char_vector &buf, const int which_packet)
 {
-  return remote_protocol_packets[packet].detect;
+  return packet_ok (buf.data (), which_packet);
 }
 
 /* Returns whether a given packet or feature is supported.  This takes
@@ -2243,7 +2494,7 @@ packet_set_cmd_state (int packet)
    command, which may be used to bypass auto-detection.  */
 
 static enum packet_support
-packet_config_support (struct packet_config *config)
+packet_config_support (const packet_config *config)
 {
   switch (config->detect)
     {
@@ -2258,14 +2509,10 @@ packet_config_support (struct packet_config *config)
     }
 }
 
-/* Same as packet_config_support, but takes the packet's enum value as
-   argument.  */
-
-static enum packet_support
-packet_support (int packet)
+packet_support
+remote_features::packet_support (int packet) const
 {
-  struct packet_config *config = &remote_protocol_packets[packet];
-
+  const packet_config *config = &m_protocol_packets[packet];
   return packet_config_support (config);
 }
 
@@ -2274,21 +2521,19 @@ show_remote_protocol_packet_cmd (struct ui_file *file, int from_tty,
                                 struct cmd_list_element *c,
                                 const char *value)
 {
-  struct packet_config *packet;
+  remote_target *remote = get_current_remote_target ();
   gdb_assert (c->var.has_value ());
 
-  for (packet = remote_protocol_packets;
-       packet < &remote_protocol_packets[PACKET_MAX];
-       packet++)
+  auto *default_config = static_cast<packet_config *> (c->context ());
+  const int packet_idx = std::distance (remote_protocol_packets,
+                                       default_config);
+
+  if (packet_idx >= 0 && packet_idx < PACKET_MAX)
     {
-      if (c == packet->show_cmd)
-       {
-         show_packet_config_cmd (packet);
-         return;
-       }
+       show_packet_config_cmd (file, packet_idx, remote);
+       return;
     }
-  internal_error (__FILE__, __LINE__, _("Could not find config for %s"),
-                 c->name);
+  internal_error (_("Could not find config for %s"), c->name);
 }
 
 /* Should we try one of the 'Z' requests?  */
@@ -2312,10 +2557,23 @@ static void
 set_remote_protocol_Z_packet_cmd (const char *args, int from_tty,
                                  struct cmd_list_element *c)
 {
+  remote_target *remote = get_current_remote_target ();
   int i;
 
   for (i = 0; i < NR_Z_PACKET_TYPES; i++)
-    remote_protocol_packets[PACKET_Z0 + i].detect = remote_Z_packet_detect;
+    {
+      if (remote != nullptr)
+       remote->m_features.m_protocol_packets[PACKET_Z0 + i].detect
+         = remote_Z_packet_detect;
+      else
+       remote_protocol_packets[PACKET_Z0 + i].detect = remote_Z_packet_detect;
+    }
+
+  const char *support = get_packet_support_name (remote_Z_packet_detect);
+  const char *target_type = get_target_type_name (remote != nullptr);
+  gdb_printf (_("Use of Z packets %s is set to \"%s\".\n"), target_type,
+             support);
+
 }
 
 static void
@@ -2323,52 +2581,11 @@ show_remote_protocol_Z_packet_cmd (struct ui_file *file, int from_tty,
                                   struct cmd_list_element *c,
                                   const char *value)
 {
+  remote_target *remote = get_current_remote_target ();
   int i;
 
   for (i = 0; i < NR_Z_PACKET_TYPES; i++)
-    {
-      show_packet_config_cmd (&remote_protocol_packets[PACKET_Z0 + i]);
-    }
-}
-
-/* Returns true if the multi-process extensions are in effect.  */
-
-static int
-remote_multi_process_p (struct remote_state *rs)
-{
-  return packet_support (PACKET_multiprocess_feature) == PACKET_ENABLE;
-}
-
-/* Returns true if fork events are supported.  */
-
-static int
-remote_fork_event_p (struct remote_state *rs)
-{
-  return packet_support (PACKET_fork_event_feature) == PACKET_ENABLE;
-}
-
-/* Returns true if vfork events are supported.  */
-
-static int
-remote_vfork_event_p (struct remote_state *rs)
-{
-  return packet_support (PACKET_vfork_event_feature) == PACKET_ENABLE;
-}
-
-/* Returns true if exec events are supported.  */
-
-static int
-remote_exec_event_p (struct remote_state *rs)
-{
-  return packet_support (PACKET_exec_event_feature) == PACKET_ENABLE;
-}
-
-/* Returns true if memory tagging is supported, false otherwise.  */
-
-static bool
-remote_memory_tagging_p ()
-{
-  return packet_support (PACKET_memory_tagging_feature) == PACKET_ENABLE;
+    show_packet_config_cmd (file, PACKET_Z0 + i, remote);
 }
 
 /* Insert fork catchpoint target routine.  If fork events are enabled
@@ -2377,9 +2594,7 @@ remote_memory_tagging_p ()
 int
 remote_target::insert_fork_catchpoint (int pid)
 {
-  struct remote_state *rs = get_remote_state ();
-
-  return !remote_fork_event_p (rs);
+  return !m_features.remote_fork_event_p ();
 }
 
 /* Remove fork catchpoint target routine.  Nothing to do, just
@@ -2397,9 +2612,7 @@ remote_target::remove_fork_catchpoint (int pid)
 int
 remote_target::insert_vfork_catchpoint (int pid)
 {
-  struct remote_state *rs = get_remote_state ();
-
-  return !remote_vfork_event_p (rs);
+  return !m_features.remote_vfork_event_p ();
 }
 
 /* Remove vfork catchpoint target routine.  Nothing to do, just
@@ -2417,9 +2630,7 @@ remote_target::remove_vfork_catchpoint (int pid)
 int
 remote_target::insert_exec_catchpoint (int pid)
 {
-  struct remote_state *rs = get_remote_state ();
-
-  return !remote_exec_event_p (rs);
+  return !m_features.remote_exec_event_p ();
 }
 
 /* Remove exec catchpoint target routine.  Nothing to do, just
@@ -2448,19 +2659,18 @@ remote_target::remote_query_attached (int pid)
   struct remote_state *rs = get_remote_state ();
   size_t size = get_remote_packet_size ();
 
-  if (packet_support (PACKET_qAttached) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qAttached) == PACKET_DISABLE)
     return 0;
 
-  if (remote_multi_process_p (rs))
+  if (m_features.remote_multi_process_p ())
     xsnprintf (rs->buf.data (), size, "qAttached:%x", pid);
   else
     xsnprintf (rs->buf.data (), size, "qAttached");
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf,
-                    &remote_protocol_packets[PACKET_qAttached]))
+  switch (m_features.packet_ok (rs->buf, PACKET_qAttached))
     {
     case PACKET_OK:
       if (strcmp (rs->buf.data (), "1") == 0)
@@ -2499,7 +2709,7 @@ remote_target::remote_add_inferior (bool fake_pid_p, int pid, int attached,
   if (attached == -1)
     attached = remote_query_attached (pid);
 
-  if (gdbarch_has_global_solist (target_gdbarch ()))
+  if (gdbarch_has_global_solist (current_inferior ()->arch ()))
     {
       /* If the target shares code across all inferiors, then every
         attach adds a new inferior.  */
@@ -2560,10 +2770,13 @@ static remote_thread_info *get_remote_thread_info (remote_target *target,
                                                   ptid_t ptid);
 
 /* Add thread PTID to GDB's thread list.  Tag it as executing/running
-   according to RUNNING.  */
+   according to EXECUTING and RUNNING respectively.  If SILENT_P (or the
+   remote_state::starting_up flag) is true then the new thread is added
+   silently, otherwise the new thread will be announced to the user.  */
 
 thread_info *
-remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing)
+remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing,
+                                 bool silent_p)
 {
   struct remote_state *rs = get_remote_state ();
   struct thread_info *thread;
@@ -2574,7 +2787,7 @@ remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing)
      consider that a single-threaded target, mentioning a new thread
      might be confusing to the user.  Be silent then, preserving the
      age old behavior.  */
-  if (rs->starting_up)
+  if (rs->starting_up || silent_p)
     thread = add_thread_silent (this, ptid);
   else
     thread = add_thread (this, ptid);
@@ -2607,12 +2820,12 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, bool executing)
   /* If this is a new thread, add it to GDB's thread list.
      If we leave it up to WFI to do this, bad things will happen.  */
 
-  thread_info *tp = find_thread_ptid (this, currthread);
+  thread_info *tp = this->find_thread (currthread);
   if (tp != NULL && tp->state == THREAD_EXITED)
     {
       /* We're seeing an event on a thread id we knew had exited.
         This has to be a new thread reusing the old id.  Add it.  */
-      remote_add_thread (currthread, running, executing);
+      remote_add_thread (currthread, running, executing, false);
       return;
     }
 
@@ -2634,7 +2847,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, bool executing)
          else
            {
              thread_info *thr
-               = remote_add_thread (currthread, running, executing);
+               = remote_add_thread (currthread, running, executing, false);
              switch_to_thread (thr);
            }
          return;
@@ -2657,8 +2870,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, bool executing)
         thread, so notifications are emitted in a sensible order.  */
       if (find_inferior_pid (this, currthread.pid ()) == NULL)
        {
-         struct remote_state *rs = get_remote_state ();
-         bool fake_pid_p = !remote_multi_process_p (rs);
+         bool fake_pid_p = !m_features.remote_multi_process_p ();
 
          inf = remote_add_inferior (fake_pid_p,
                                     currthread.pid (), -1, 1);
@@ -2666,7 +2878,7 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, bool executing)
 
       /* This is really a new thread.  Add it.  */
       thread_info *new_thr
-       = remote_add_thread (currthread, running, executing);
+       = remote_add_thread (currthread, running, executing, false);
 
       /* If we found a new inferior, let the common code do whatever
         it needs to with it (e.g., read shared libraries, insert
@@ -2692,7 +2904,7 @@ get_remote_thread_info (thread_info *thread)
   if (thread->priv == NULL)
     thread->priv.reset (new remote_thread_info);
 
-  return static_cast<remote_thread_info *> (thread->priv.get ());
+  return gdb::checked_static_cast<remote_thread_info *> (thread->priv.get ());
 }
 
 /* Return PTID's private thread data, creating it if necessary.  */
@@ -2700,7 +2912,7 @@ get_remote_thread_info (thread_info *thread)
 static remote_thread_info *
 get_remote_thread_info (remote_target *target, ptid_t ptid)
 {
-  thread_info *thr = find_thread_ptid (target, ptid);
+  thread_info *thr = target->find_thread (ptid);
   return get_remote_thread_info (thr);
 }
 
@@ -2721,7 +2933,7 @@ record_currthread (struct remote_state *rs, ptid_t currthread)
 void
 remote_target::pass_signals (gdb::array_view<const unsigned char> pass_signals)
 {
-  if (packet_support (PACKET_QPassSignals) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QPassSignals) != PACKET_DISABLE)
     {
       char *pass_packet, *p;
       int count = 0;
@@ -2754,8 +2966,8 @@ remote_target::pass_signals (gdb::array_view<const unsigned char> pass_signals)
       if (!rs->last_pass_packet || strcmp (rs->last_pass_packet, pass_packet))
        {
          putpkt (pass_packet);
-         getpkt (&rs->buf, 0);
-         packet_ok (rs->buf, &remote_protocol_packets[PACKET_QPassSignals]);
+         getpkt (&rs->buf);
+         m_features.packet_ok (rs->buf, PACKET_QPassSignals);
          xfree (rs->last_pass_packet);
          rs->last_pass_packet = pass_packet;
        }
@@ -2775,7 +2987,7 @@ remote_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
   enum packet_result result;
   int n_sysno = 0;
 
-  if (packet_support (PACKET_QCatchSyscalls) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QCatchSyscalls) == PACKET_DISABLE)
     {
       /* Not supported.  */
       return 1;
@@ -2827,8 +3039,8 @@ remote_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
   struct remote_state *rs = get_remote_state ();
 
   putpkt (catch_packet);
-  getpkt (&rs->buf, 0);
-  result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QCatchSyscalls]);
+  getpkt (&rs->buf);
+  result = m_features.packet_ok (rs->buf, PACKET_QCatchSyscalls);
   if (result == PACKET_OK)
     return 0;
   else
@@ -2841,7 +3053,7 @@ remote_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
 void
 remote_target::program_signals (gdb::array_view<const unsigned char> signals)
 {
-  if (packet_support (PACKET_QProgramSignals) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QProgramSignals) != PACKET_DISABLE)
     {
       char *packet, *p;
       int count = 0;
@@ -2875,8 +3087,8 @@ remote_target::program_signals (gdb::array_view<const unsigned char> signals)
          || strcmp (rs->last_program_signals_packet, packet) != 0)
        {
          putpkt (packet);
-         getpkt (&rs->buf, 0);
-         packet_ok (rs->buf, &remote_protocol_packets[PACKET_QProgramSignals]);
+         getpkt (&rs->buf);
+         m_features.packet_ok (rs->buf, PACKET_QProgramSignals);
          xfree (rs->last_program_signals_packet);
          rs->last_program_signals_packet = packet;
        }
@@ -2911,7 +3123,7 @@ remote_target::set_thread (ptid_t ptid, int gen)
   else
     write_ptid (buf, endbuf, ptid);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (gen)
     rs->general_thread = ptid;
   else
@@ -2942,12 +3154,12 @@ remote_target::set_continue_thread (ptid_t ptid)
 void
 remote_target::set_general_process ()
 {
-  struct remote_state *rs = get_remote_state ();
-
   /* If the remote can't handle multiple processes, don't bother.  */
-  if (!remote_multi_process_p (rs))
+  if (!m_features.remote_multi_process_p ())
     return;
 
+  remote_state *rs = get_remote_state ();
+
   /* We only need to change the remote current thread if it's pointing
      at some other process.  */
   if (rs->general_thread.pid () != inferior_ptid.pid ())
@@ -2995,7 +3207,7 @@ remote_target::thread_alive (ptid_t ptid)
   write_ptid (p, endp, ptid);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   return (rs->buf[0] == 'O' && rs->buf[1] == 'K');
 }
 
@@ -3022,7 +3234,7 @@ remote_target::thread_name (struct thread_info *info)
 
 /* WARNING: This threadref data structure comes from the remote O.S.,
    libstub protocol encoding, and remote.c.  It is not particularly
-   changable.  */
+   changeable.  */
 
 /* Right now, the internal structure is int. We want it to be bigger.
    Plan to fix this.  */
@@ -3097,9 +3309,8 @@ char *
 remote_target::write_ptid (char *buf, const char *endbuf, ptid_t ptid)
 {
   int pid, tid;
-  struct remote_state *rs = get_remote_state ();
 
-  if (remote_multi_process_p (rs))
+  if (m_features.remote_multi_process_p ())
     {
       pid = ptid.pid ();
       if (pid < 0)
@@ -3152,14 +3363,15 @@ read_ptid (const char *buf, const char **obuf)
       return null_ptid;
     }
 
-  /* Since the stub is not sending a process id, then default to
-     what's in inferior_ptid, unless it's null at this point.  If so,
+  /* Since the stub is not sending a process id, default to what's
+     current_inferior, unless it doesn't have a PID yet.  If so,
      then since there's no way to know the pid of the reported
      threads, use the magic number.  */
-  if (inferior_ptid == null_ptid)
+  inferior *inf = current_inferior ();
+  if (inf->pid == 0)
     pid = magic_null_ptid.pid ();
   else
-    pid = inferior_ptid.pid ();
+    pid = inf->pid;
 
   if (obuf)
     *obuf = pp;
@@ -3495,7 +3707,7 @@ remote_target::remote_get_threadinfo (threadref *threadid,
 
   pack_threadinfo_request (rs->buf.data (), fieldset, threadid);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   if (rs->buf[0] == '\0')
     return 0;
@@ -3569,7 +3781,7 @@ remote_target::remote_get_threadlist (int startflag, threadref *nextthread,
   pack_threadlist_request (rs->buf.data (), startflag, result_limit,
                           nextthread);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (rs->buf[0] == '\0')
     {
       /* Packet not supported.  */
@@ -3756,7 +3968,7 @@ remote_target::remote_current_thread (ptid_t oldpid)
   struct remote_state *rs = get_remote_state ();
 
   putpkt ("qC");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (rs->buf[0] == 'Q' && rs->buf[1] == 'C')
     {
       const char *obuf;
@@ -3860,7 +4072,7 @@ int
 remote_target::remote_get_threads_with_qxfer (threads_listing_context *context)
 {
 #if defined(HAVE_LIBEXPAT)
-  if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
     {
       gdb::optional<gdb::char_vector> xml
        = target_read_stralloc (this, TARGET_OBJECT_THREADS, NULL);
@@ -3890,7 +4102,7 @@ remote_target::remote_get_threads_with_qthreadinfo (threads_listing_context *con
       const char *bufp;
 
       putpkt ("qfThreadInfo");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       bufp = rs->buf.data ();
       if (bufp[0] != '\0')             /* q packet recognized */
        {
@@ -3903,7 +4115,7 @@ remote_target::remote_get_threads_with_qthreadinfo (threads_listing_context *con
                }
              while (*bufp++ == ',');   /* comma-separated list */
              putpkt ("qsThreadInfo");
-             getpkt (&rs->buf, 0);
+             getpkt (&rs->buf);
              bufp = rs->buf.data ();
            }
          return 1;
@@ -4000,7 +4212,7 @@ remote_target::update_thread_list ()
 
              remote_notice_new_inferior (item.ptid, executing);
 
-             thread_info *tp = find_thread_ptid (this, item.ptid);
+             thread_info *tp = this->find_thread (item.ptid);
              remote_thread_info *info = get_remote_thread_info (tp);
              info->core = item.core;
              info->extra = std::move (item.extra);
@@ -4038,8 +4250,7 @@ remote_target::extra_thread_info (thread_info *tp)
   struct gdb_ext_thread_info threadinfo;
 
   if (rs->remote_desc == 0)            /* paranoia */
-    internal_error (__FILE__, __LINE__,
-                   _("remote_threads_extra_info"));
+    internal_error (_("remote_threads_extra_info"));
 
   if (tp->ptid == magic_null_ptid
       || (tp->ptid.pid () != 0 && tp->ptid.lwp () == 0))
@@ -4053,7 +4264,7 @@ remote_target::extra_thread_info (thread_info *tp)
   if (!extra.empty ())
     return extra.c_str ();
 
-  if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
     {
       /* If we're using qXfer:threads:read, then the extra info is
         included in the XML.  So if we didn't have anything cached,
@@ -4071,7 +4282,7 @@ remote_target::extra_thread_info (thread_info *tp)
       write_ptid (b, endb, tp->ptid);
 
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       if (rs->buf[0] != 0)
        {
          extra.resize (strlen (rs->buf.data ()) / 2);
@@ -4119,7 +4330,7 @@ remote_target::static_tracepoint_marker_at (CORE_ADDR addr,
   p += strlen (p);
   p += hexnumstr (p, addr);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   p = rs->buf.data ();
 
   if (*p == 'E')
@@ -4145,7 +4356,7 @@ remote_target::static_tracepoint_markers_by_strid (const char *strid)
   /* Ask for a first packet of static tracepoint marker
      definition.  */
   putpkt ("qTfSTM");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   p = rs->buf.data ();
   if (*p == 'E')
     error (_("Remote failure reply: %s"), p);
@@ -4162,7 +4373,7 @@ remote_target::static_tracepoint_markers_by_strid (const char *strid)
       while (*p++ == ',');     /* comma-separated list */
       /* Ask for another packet of static tracepoint definition.  */
       putpkt ("qTsSTM");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       p = rs->buf.data ();
     }
 
@@ -4222,8 +4433,7 @@ remote_target::~remote_target ()
      everything of this target.  */
   discard_pending_stop_replies_in_queue ();
 
-  if (rs->remote_async_inferior_event_token)
-    delete_async_event_handler (&rs->remote_async_inferior_event_token);
+  rs->delete_async_event_handler ();
 
   delete rs->notif_state;
 }
@@ -4243,7 +4453,7 @@ remote_target::get_offsets ()
     return;
 
   putpkt ("qOffsets");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   buf = rs->buf.data ();
 
   if (buf[0] == '\000')
@@ -4318,7 +4528,7 @@ remote_target::get_offsets ()
   objfile *objf = current_program_space->symfile_object_file;
   section_offsets offs = objf->section_offsets;
 
-  symfile_segment_data_up data = get_symfile_segment_data (objf->obfd);
+  symfile_segment_data_up data = get_symfile_segment_data (objf->obfd.get ());
   do_segments = (data != NULL);
   do_sections = num_segments == 0;
 
@@ -4353,7 +4563,7 @@ remote_target::get_offsets ()
 
   if (do_segments)
     {
-      int ret = symfile_map_offsets_to_segments (objf->obfd,
+      int ret = symfile_map_offsets_to_segments (objf->obfd.get (),
                                                 data.get (), offs,
                                                 num_segments, segments);
 
@@ -4398,8 +4608,7 @@ remote_target::send_interrupt_sequence ()
       remote_serial_write ("g", 1);
     }
   else
-    internal_error (__FILE__, __LINE__,
-                   _("Invalid value for interrupt_sequence_mode: %s."),
+    internal_error (_("Invalid value for interrupt_sequence_mode: %s."),
                    interrupt_sequence_mode);
 }
 
@@ -4479,7 +4688,6 @@ remote_target::get_current_thread (const char *wait_status)
 thread_info *
 remote_target::add_current_inferior_and_thread (const char *wait_status)
 {
-  struct remote_state *rs = get_remote_state ();
   bool fake_pid_p = false;
 
   switch_to_no_thread ();
@@ -4490,7 +4698,7 @@ remote_target::add_current_inferior_and_thread (const char *wait_status)
 
   if (curr_ptid != null_ptid)
     {
-      if (!remote_multi_process_p (rs))
+      if (!m_features.remote_multi_process_p ())
        fake_pid_p = true;
     }
   else
@@ -4548,9 +4756,10 @@ remote_target::print_one_stopped_thread (thread_info *thread)
       enum gdb_signal sig = ws.sig ();
 
       if (signal_print_state (sig))
-       gdb::observers::signal_received.notify (sig);
+       notify_signal_received (sig);
     }
-  gdb::observers::normal_stop.notify (NULL, 1);
+
+  notify_normal_stop (nullptr, 1);
 }
 
 /* Process all initial stop replies the remote side sent in response
@@ -4599,7 +4808,7 @@ remote_target::process_initial_stop_replies (int from_tty)
       if (ignore_event)
        continue;
 
-      thread_info *evthread = find_thread_ptid (this, event_ptid);
+      thread_info *evthread = this->find_thread (event_ptid);
 
       if (ws.kind () == TARGET_WAITKIND_STOPPED)
        {
@@ -4626,7 +4835,7 @@ remote_target::process_initial_stop_replies (int from_tty)
      registers/memory.  */
   for (inferior *inf : all_non_exited_inferiors (this))
     {
-      inf->needs_setup = 1;
+      inf->needs_setup = true;
 
       if (non_stop)
        {
@@ -4646,9 +4855,9 @@ remote_target::process_initial_stop_replies (int from_tty)
           the poll in stop_all_threads to consider events from it, so enable
           it temporarily.  */
        gdb_assert (!this->is_async_p ());
-       SCOPE_EXIT { target_async (0); };
-       target_async (1);
-       stop_all_threads ();
+       SCOPE_EXIT { target_async (false); };
+       target_async (true);
+       stop_all_threads ("remote connect in all-stop");
       }
 
       /* If all threads of an inferior were already stopped, we
@@ -4703,7 +4912,7 @@ remote_target::process_initial_stop_replies (int from_tty)
     }
 }
 
-/* Mark a remote_target as marking (by setting the starting_up flag within
+/* Mark a remote_target as starting (by setting the starting_up flag within
    its remote_state) for the lifetime of this object.  The reference count
    on the remote target is temporarily incremented, to prevent the target
    being deleted under our feet.  */
@@ -4713,26 +4922,32 @@ struct scoped_mark_target_starting
   /* Constructor, TARGET is the target to be marked as starting, its
      reference count will be incremented.  */
   scoped_mark_target_starting (remote_target *target)
-    : m_remote_target (target)
-  {
-    m_remote_target->incref ();
-    remote_state *rs = m_remote_target->get_remote_state ();
-    rs->starting_up = true;
-  }
+    : m_remote_target (remote_target_ref::new_reference (target)),
+      m_restore_starting_up (set_starting_up_flag (target))
+  { /* Nothing.  */ }
+
+private:
 
-  /* Destructor, mark the target being worked on as no longer starting, and
-     decrement the reference count.  */
-  ~scoped_mark_target_starting ()
+  /* Helper function, set the starting_up flag on TARGET and return an
+     object which, when it goes out of scope, will restore the previous
+     value of the starting_up flag.  */
+  static scoped_restore_tmpl<bool>
+  set_starting_up_flag (remote_target *target)
   {
-    remote_state *rs = m_remote_target->get_remote_state ();
-    rs->starting_up = false;
-    decref_target (m_remote_target);
+    remote_state *rs = target->get_remote_state ();
+    gdb_assert (!rs->starting_up);
+    return make_scoped_restore (&rs->starting_up, true);
   }
 
-private:
+  /* A gdb::ref_ptr pointer to a remote_target.  */
+  using remote_target_ref = gdb::ref_ptr<remote_target, target_ops_ref_policy>;
 
-  /* The target on which we are operating.  */
-  remote_target *m_remote_target;
+  /* A reference to the target on which we are operating.  */
+  remote_target_ref m_remote_target;
+
+  /* An object which restores the previous value of the starting_up flag
+     when it goes out of scope.  */
+  scoped_restore_tmpl<bool> m_restore_starting_up;
 };
 
 /* Helper for remote_target::start_remote, start the remote connection and
@@ -4746,7 +4961,6 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
   REMOTE_SCOPED_DEBUG_ENTER_EXIT;
 
   struct remote_state *rs = get_remote_state ();
-  struct packet_config *noack_config;
 
   /* Signal other parts that we're going through the initial setup,
      and so things may not be stable yet.  E.g., we don't try to
@@ -4769,8 +4983,12 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
      which later probes to skip.  */
   remote_query_supported ();
 
+  /* Check vCont support and set the remote state's vCont_action_support
+     attribute.  */
+  remote_vcont_probe ();
+
   /* If the stub wants to get a QAllow, compose one and send it.  */
-  if (packet_support (PACKET_QAllow) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QAllow) != PACKET_DISABLE)
     set_permissions ();
 
   /* gdbserver < 7.7 (before its fix from 2013-12-11) did reply to any
@@ -4784,9 +5002,12 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
     const char v_mustreplyempty[] = "vMustReplyEmpty";
 
     putpkt (v_mustreplyempty);
-    getpkt (&rs->buf, 0);
+    getpkt (&rs->buf);
     if (strcmp (rs->buf.data (), "OK") == 0)
-      remote_protocol_packets[PACKET_vFile_setfs].support = PACKET_DISABLE;
+      {
+       m_features.m_protocol_packets[PACKET_vFile_setfs].support
+         = PACKET_DISABLE;
+      }
     else if (strcmp (rs->buf.data (), "") != 0)
       error (_("Remote replied unexpectedly to '%s': %s"), v_mustreplyempty,
             rs->buf.data ());
@@ -4805,12 +5026,11 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
      If FALSE, then don't activate noack mode, regardless of what the
      stub claimed should be the default with qSupported.  */
 
-  noack_config = &remote_protocol_packets[PACKET_QStartNoAckMode];
-  if (packet_config_support (noack_config) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QStartNoAckMode) != PACKET_DISABLE)
     {
       putpkt ("QStartNoAckMode");
-      getpkt (&rs->buf, 0);
-      if (packet_ok (rs->buf, noack_config) == PACKET_OK)
+      getpkt (&rs->buf);
+      if (m_features.packet_ok (rs->buf, PACKET_QStartNoAckMode) == PACKET_OK)
        rs->noack_mode = 1;
     }
 
@@ -4818,7 +5038,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
     {
       /* Tell the remote that we are using the extended protocol.  */
       putpkt ("!");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
     }
 
   /* Let the target know which signals it is allowed to pass down to
@@ -4835,17 +5055,17 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
 
   /* On OSs where the list of libraries is global to all
      processes, we fetch them early.  */
-  if (gdbarch_has_global_solist (target_gdbarch ()))
+  if (gdbarch_has_global_solist (current_inferior ()->arch ()))
     solib_add (NULL, from_tty, auto_solib_add);
 
   if (target_is_non_stop_p ())
     {
-      if (packet_support (PACKET_QNonStop) != PACKET_ENABLE)
+      if (m_features.packet_support (PACKET_QNonStop) != PACKET_ENABLE)
        error (_("Non-stop mode requested, but remote "
                 "does not support non-stop"));
 
       putpkt ("QNonStop:1");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("Remote refused setting non-stop mode with: %s"),
@@ -4857,12 +5077,12 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
         stopped.  */
       this->update_thread_list ();
     }
-  else if (packet_support (PACKET_QNonStop) == PACKET_ENABLE)
+  else if (m_features.packet_support (PACKET_QNonStop) == PACKET_ENABLE)
     {
       /* Don't assume that the stub can operate in all-stop mode.
         Request it explicitly.  */
       putpkt ("QNonStop:0");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("Remote refused setting all-stop mode with: %s"),
@@ -4882,7 +5102,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
 
   /* Check whether the target is running now.  */
   putpkt ("?");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   if (!target_is_non_stop_p ())
     {
@@ -4940,7 +5160,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
                }
            }
          else
-           switch_to_thread (find_thread_ptid (this, curr_thread));
+           switch_to_thread (this->find_thread (curr_thread));
        }
 
       /* init_wait_for_inferior should be called before get_offsets in order
@@ -4961,7 +5181,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
         supported for non-stop; it could be, but it is tricky if
         there are no stopped threads when we connect.  */
       if (remote_read_description_p (this)
-         && gdbarch_target_desc (target_gdbarch ()) == NULL)
+         && gdbarch_target_desc (current_inferior ()->arch ()) == NULL)
        {
          target_clear_description ();
          target_find_description ();
@@ -4969,8 +5189,9 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
 
       /* Use the previously fetched status.  */
       gdb_assert (wait_status != NULL);
-      strcpy (rs->buf.data (), wait_status);
-      rs->cached_wait_status = 1;
+      struct notif_event *reply
+       = remote_notif_parse (this, &notif_client_stop, wait_status);
+      push_stop_reply ((struct stop_reply *) reply);
 
       ::start_remote (from_tty); /* Initialize gdb process mechanisms.  */
     }
@@ -4990,7 +5211,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
         mechanism.  */
       if (strcmp (rs->buf.data (), "OK") != 0)
        {
-         struct notif_client *notif = &notif_client_stop;
+         const notif_client *notif = &notif_client_stop;
 
          /* remote_notif_get_pending_replies acks this one, and gets
             the rest out.  */
@@ -5014,15 +5235,27 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
       process_initial_stop_replies (from_tty);
 
       if (target_can_async_p ())
-       target_async (1);
+       target_async (true);
     }
 
-  /* If we connected to a live target, do some additional setup.  */
-  if (target_has_execution ())
+  /* Give the target a chance to look up symbols.  */
+  for (inferior *inf : all_inferiors (this))
     {
+      /* The inferiors that exist at this point were created from what
+        was found already running on the remote side, so we know they
+        have execution.  */
+      gdb_assert (this->has_execution (inf));
+
       /* No use without a symbol-file.  */
-      if (current_program_space->symfile_object_file)
-       remote_check_symbols ();
+      if (inf->pspace->symfile_object_file == nullptr)
+       continue;
+
+      /* Need to switch to a specific thread, because remote_check_symbols
+        uses INFERIOR_PTID to set the general thread.  */
+      scoped_restore_current_thread restore_thread;
+      thread_info *thread = any_thread_of_inferior (inf);
+      switch_to_thread (thread);
+      this->remote_check_symbols ();
     }
 
   /* Possibly the target has been engaged in a trace run started
@@ -5032,7 +5265,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
       struct uploaded_tp *uploaded_tps = NULL;
 
       if (current_trace_status ()->running)
-       printf_filtered (_("Trace is already running on the target.\n"));
+       gdb_printf (_("Trace is already running on the target.\n"));
 
       upload_tracepoints (&uploaded_tps);
 
@@ -5085,16 +5318,13 @@ extended_remote_target::open (const char *name, int from_tty)
   open_1 (name, from_tty, 1 /*extended_p */);
 }
 
-/* Reset all packets back to "unknown support".  Called when opening a
-   new connection to a remote target.  */
-
-static void
-reset_all_packet_configs_support (void)
+void
+remote_features::reset_all_packet_configs_support ()
 {
   int i;
 
   for (i = 0; i < PACKET_MAX; i++)
-    remote_protocol_packets[i].support = PACKET_SUPPORT_UNKNOWN;
+    m_protocol_packets[i].support = PACKET_SUPPORT_UNKNOWN;
 }
 
 /* Initialize all packet configs.  */
@@ -5119,15 +5349,12 @@ remote_target::remote_check_symbols ()
   char *tmp;
   int end;
 
-  /* The remote side has no concept of inferiors that aren't running
-     yet, it only knows about running processes.  If we're connected
-     but our current inferior is not running, we should not invite the
-     remote target to request symbol lookups related to its
-     (unrelated) current process.  */
-  if (!target_has_execution ())
-    return;
+  /* It doesn't make sense to send a qSymbol packet for an inferior that
+     doesn't have execution, because the remote side doesn't know about
+     inferiors without execution.  */
+  gdb_assert (target_has_execution ());
 
-  if (packet_support (PACKET_qSymbol) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qSymbol) == PACKET_DISABLE)
     return;
 
   /* Make sure the remote is pointing at the right process.  Note
@@ -5142,8 +5369,8 @@ remote_target::remote_check_symbols ()
   /* Invite target to request symbol lookups.  */
 
   putpkt ("qSymbol::");
-  getpkt (&reply, 0);
-  packet_ok (reply, &remote_protocol_packets[PACKET_qSymbol]);
+  getpkt (&reply);
+  m_features.packet_ok (reply, PACKET_qSymbol);
 
   while (startswith (reply.data (), "qSymbol:"))
     {
@@ -5159,20 +5386,21 @@ remote_target::remote_check_symbols ()
                   &reply[8]);
       else
        {
-         int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
-         CORE_ADDR sym_addr = BMSYMBOL_VALUE_ADDRESS (sym);
+         int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
+         CORE_ADDR sym_addr = sym.value_address ();
 
          /* If this is a function address, return the start of code
             instead of any data function descriptor.  */
          sym_addr = gdbarch_convert_from_func_ptr_addr
-           (target_gdbarch (), sym_addr, current_inferior ()->top_target ());
+           (current_inferior ()->arch (), sym_addr,
+            current_inferior ()->top_target ());
 
          xsnprintf (msg.data (), get_remote_packet_size (), "qSymbol:%s:%s",
                     phex_nz (sym_addr, addr_size), &reply[8]);
        }
 
       putpkt (msg.data ());
-      getpkt (&reply, 0);
+      getpkt (&reply);
     }
 }
 
@@ -5218,7 +5446,7 @@ remote_target::set_permissions ()
             may_insert_breakpoints, may_insert_tracepoints,
             may_insert_fast_tracepoints, may_stop);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   /* If the target didn't like the packet, warn the user.  Do not try
      to undo the user's settings, that would just be maddening.  */
@@ -5267,7 +5495,7 @@ remote_supported_packet (remote_target *remote,
       return;
     }
 
-  remote_protocol_packets[feature->packet].support = support;
+  remote->m_features.m_protocol_packets[feature->packet].support = support;
 }
 
 void
@@ -5475,58 +5703,67 @@ remote_target::remote_query_supported ()
      containing no features.  */
 
   rs->buf[0] = 0;
-  if (packet_support (PACKET_qSupported) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qSupported) != PACKET_DISABLE)
     {
       std::string q;
 
-      if (packet_set_cmd_state (PACKET_multiprocess_feature) != AUTO_BOOLEAN_FALSE)
+      if (m_features.packet_set_cmd_state (PACKET_multiprocess_feature)
+         != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "multiprocess+");
 
-      if (packet_set_cmd_state (PACKET_swbreak_feature) != AUTO_BOOLEAN_FALSE)
+      if (m_features.packet_set_cmd_state (PACKET_swbreak_feature)
+         != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "swbreak+");
-      if (packet_set_cmd_state (PACKET_hwbreak_feature) != AUTO_BOOLEAN_FALSE)
+
+      if (m_features.packet_set_cmd_state (PACKET_hwbreak_feature)
+         != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "hwbreak+");
 
       remote_query_supported_append (&q, "qRelocInsn+");
 
-      if (packet_set_cmd_state (PACKET_fork_event_feature)
+      if (m_features.packet_set_cmd_state (PACKET_fork_event_feature)
          != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "fork-events+");
-      if (packet_set_cmd_state (PACKET_vfork_event_feature)
+
+      if (m_features.packet_set_cmd_state (PACKET_vfork_event_feature)
          != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "vfork-events+");
-      if (packet_set_cmd_state (PACKET_exec_event_feature)
+
+      if (m_features.packet_set_cmd_state (PACKET_exec_event_feature)
          != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "exec-events+");
 
-      if (packet_set_cmd_state (PACKET_vContSupported) != AUTO_BOOLEAN_FALSE)
+      if (m_features.packet_set_cmd_state (PACKET_vContSupported)
+         != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "vContSupported+");
 
-      if (packet_set_cmd_state (PACKET_QThreadEvents) != AUTO_BOOLEAN_FALSE)
+      if (m_features.packet_set_cmd_state (PACKET_QThreadEvents)
+         != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "QThreadEvents+");
 
-      if (packet_set_cmd_state (PACKET_no_resumed) != AUTO_BOOLEAN_FALSE)
+      if (m_features.packet_set_cmd_state (PACKET_no_resumed)
+         != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "no-resumed+");
 
-      if (packet_set_cmd_state (PACKET_memory_tagging_feature)
+      if (m_features.packet_set_cmd_state (PACKET_memory_tagging_feature)
          != AUTO_BOOLEAN_FALSE)
        remote_query_supported_append (&q, "memory-tagging+");
 
       /* Keep this one last to work around a gdbserver <= 7.10 bug in
         the qSupported:xmlRegisters=i386 handling.  */
       if (remote_support_xml != NULL
-         && packet_support (PACKET_qXfer_features) != PACKET_DISABLE)
+         && (m_features.packet_support (PACKET_qXfer_features)
+             != PACKET_DISABLE))
        remote_query_supported_append (&q, remote_support_xml);
 
       q = "qSupported:" + q;
       putpkt (q.c_str ());
 
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
-      /* If an error occured, warn, but do not return - just reset the
+      /* If an error occurred, warn, but do not return - just reset the
         buffer to empty and go on to disable features.  */
-      if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qSupported])
-         == PACKET_ERROR)
+      if (m_features.packet_ok (rs->buf, PACKET_qSupported) == PACKET_ERROR)
        {
          warning (_("Remote failure reply: %s"), rs->buf.data ());
          rs->buf[0] = 0;
@@ -5702,7 +5939,7 @@ remote_unpush_target (remote_target *target)
   for (inferior *inf : all_inferiors (target))
     {
       switch_to_inferior_no_thread (inf);
-      pop_all_targets_at_and_above (process_stratum);
+      inf->pop_all_targets_at_and_above (process_stratum);
       generic_mourn_inferior ();
     }
 
@@ -5758,7 +5995,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
 
   /* See FIXME above.  */
   if (!target_async_permitted)
-    rs->wait_forever_enabled_p = 1;
+    rs->wait_forever_enabled_p = true;
 
   rs->remote_desc = remote_serial_open (name);
   if (!rs->remote_desc)
@@ -5787,24 +6024,22 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
 
   if (from_tty)
     {
-      puts_filtered ("Remote debugging using ");
-      puts_filtered (name);
-      puts_filtered ("\n");
+      gdb_puts ("Remote debugging using ");
+      gdb_puts (name);
+      gdb_puts ("\n");
     }
 
   /* Switch to using the remote target now.  */
   current_inferior ()->push_target (std::move (target_holder));
 
   /* Register extra event sources in the event loop.  */
-  rs->remote_async_inferior_event_token
-    = create_async_event_handler (remote_async_inferior_event_handler, nullptr,
-                                 "remote");
+  rs->create_async_event_handler ();
+
   rs->notif_state = remote_notif_state_allocate (remote);
 
   /* Reset the target state; these things will be queried either by
      remote_query_supported or as they are needed.  */
-  reset_all_packet_configs_support ();
-  rs->cached_wait_status = 0;
+  remote->m_features.reset_all_packet_configs_support ();
   rs->explicit_packet_size = 0;
   rs->noack_mode = 0;
   rs->extended = extended_p;
@@ -5833,7 +6068,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
         around this.  Eventually a mechanism that allows
         wait_for_inferior() to expect/get timeouts will be
         implemented.  */
-      rs->wait_forever_enabled_p = 0;
+      rs->wait_forever_enabled_p = false;
     }
 
   /* First delete any symbols previously loaded from shared libraries.  */
@@ -5873,48 +6108,33 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
   remote_btrace_reset (rs);
 
   if (target_async_permitted)
-    rs->wait_forever_enabled_p = 1;
+    rs->wait_forever_enabled_p = true;
 }
 
-/* Determine if THREAD_PTID is a pending fork parent thread.  ARG contains
-   the pid of the process that owns the threads we want to check, or
-   -1 if we want to check all threads.  */
+/* Determine if WS represents a fork status.  */
 
-static int
-is_pending_fork_parent (const target_waitstatus &ws, int event_pid,
-                       ptid_t thread_ptid)
+static bool
+is_fork_status (target_waitkind kind)
 {
-  if (ws.kind () == TARGET_WAITKIND_FORKED
-      || ws.kind () == TARGET_WAITKIND_VFORKED)
-    {
-      if (event_pid == -1 || event_pid == thread_ptid.pid ())
-       return 1;
-    }
-
-  return 0;
+  return (kind == TARGET_WAITKIND_FORKED
+         || kind == TARGET_WAITKIND_VFORKED);
 }
 
-/* Return the thread's pending status used to determine whether the
-   thread is a fork parent stopped at a fork event.  */
+/* Return THREAD's pending status if it is a pending fork parent, else
+   return nullptr.  */
 
-static const target_waitstatus &
+static const target_waitstatus *
 thread_pending_fork_status (struct thread_info *thread)
 {
-  if (thread->has_pending_waitstatus ())
-    return thread->pending_waitstatus ();
-  else
-    return thread->pending_follow;
-}
-
-/* Determine if THREAD is a pending fork parent thread.  */
+  const target_waitstatus &ws
+    = (thread->has_pending_waitstatus ()
+       ? thread->pending_waitstatus ()
+       : thread->pending_follow);
 
-static int
-is_pending_fork_parent_thread (struct thread_info *thread)
-{
-  const target_waitstatus &ws = thread_pending_fork_status (thread);
-  int pid = -1;
+  if (!is_fork_status (ws.kind ()))
+    return nullptr;
 
-  return is_pending_fork_parent (ws, pid, thread->ptid);
+  return &ws;
 }
 
 /* Detach the specified process.  */
@@ -5932,13 +6152,13 @@ remote_target::remote_detach_pid (int pid)
      GDBserver to select GDB's current process.  */
   set_general_process ();
 
-  if (remote_multi_process_p (rs))
+  if (m_features.remote_multi_process_p ())
     xsnprintf (rs->buf.data (), get_remote_packet_size (), "D;%x", pid);
   else
     strcpy (rs->buf.data (), "D");
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   if (rs->buf[0] == 'O' && rs->buf[1] == 'K')
     ;
@@ -5966,7 +6186,7 @@ remote_target::remote_detach_1 (inferior *inf, int from_tty)
 
   target_announce_detach (from_tty);
 
-  if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+  if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
     {
       /* If we're in breakpoints-always-inserted mode, or the inferior
         is running, we have to remove breakpoints before detaching.
@@ -5981,9 +6201,35 @@ remote_target::remote_detach_1 (inferior *inf, int from_tty)
 
   /* Exit only if this is the only active inferior.  */
   if (from_tty && !rs->extended && number_of_live_inferiors (this) == 1)
-    puts_filtered (_("Ending remote debugging.\n"));
+    gdb_puts (_("Ending remote debugging.\n"));
+
+  /* See if any thread of the inferior we are detaching has a pending fork
+     status.  In that case, we must detach from the child resulting from
+     that fork.  */
+  for (thread_info *thread : inf->non_exited_threads ())
+    {
+      const target_waitstatus *ws = thread_pending_fork_status (thread);
+
+      if (ws == nullptr)
+       continue;
+
+      remote_detach_pid (ws->child_ptid ().pid ());
+    }
 
-  thread_info *tp = find_thread_ptid (this, inferior_ptid);
+  /* Check also for any pending fork events in the stop reply queue.  */
+  remote_notif_get_pending_events (&notif_client_stop);
+  for (stop_reply_up &reply : rs->stop_reply_queue)
+    {
+      if (reply->ptid.pid () != pid)
+       continue;
+
+      if (!is_fork_status (reply->ws.kind ()))
+       continue;
+
+      remote_detach_pid (reply->ws.child_ptid ().pid ());
+    }
+
+  thread_info *tp = this->find_thread (inferior_ptid);
 
   /* Check to see if we are detaching a fork parent.  Note that if we
      are detaching a fork child, tp == NULL.  */
@@ -6000,8 +6246,8 @@ remote_target::remote_detach_1 (inferior *inf, int from_tty)
 
       target_mourn_inferior (inferior_ptid);
       if (print_inferior_events)
-       printf_unfiltered (_("[Inferior %d (%s) detached]\n"),
-                          inf->num, infpid.c_str ());
+       gdb_printf (_("[Inferior %d (%s) detached]\n"),
+                   inf->num, infpid.c_str ());
     }
   else
     {
@@ -6037,10 +6283,10 @@ remote_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
   process_stratum_target::follow_fork (child_inf, child_ptid,
                                       fork_kind, follow_child, detach_fork);
 
-  struct remote_state *rs = get_remote_state ();
-
-  if ((fork_kind == TARGET_WAITKIND_FORKED && remote_fork_event_p (rs))
-      || (fork_kind == TARGET_WAITKIND_VFORKED && remote_vfork_event_p (rs)))
+  if ((fork_kind == TARGET_WAITKIND_FORKED
+       && m_features.remote_fork_event_p ())
+      || (fork_kind == TARGET_WAITKIND_VFORKED
+         && m_features.remote_vfork_event_p ()))
     {
       /* When following the parent and detaching the child, we detach
         the child here.  For the case of following the child and
@@ -6088,7 +6334,7 @@ remote_target::disconnect (const char *args, int from_tty)
   remote_unpush_target (this);
 
   if (from_tty)
-    puts_filtered ("Ending remote debugging.\n");
+    gdb_puts ("Ending remote debugging.\n");
 }
 
 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
@@ -6106,27 +6352,16 @@ extended_remote_target::attach (const char *args, int from_tty)
   /* Remote PID can be freely equal to getpid, do not check it here the same
      way as in other targets.  */
 
-  if (packet_support (PACKET_vAttach) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_vAttach) == PACKET_DISABLE)
     error (_("This target does not support attaching to a process"));
 
-  if (from_tty)
-    {
-      const char *exec_file = get_exec_file (0);
-
-      if (exec_file)
-       printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
-                          target_pid_to_str (ptid_t (pid)).c_str ());
-      else
-       printf_unfiltered (_("Attaching to %s\n"),
-                          target_pid_to_str (ptid_t (pid)).c_str ());
-    }
+  target_announce_attach (from_tty, pid);
 
   xsnprintf (rs->buf.data (), get_remote_packet_size (), "vAttach;%x", pid);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf,
-                    &remote_protocol_packets[PACKET_vAttach]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vAttach))
     {
     case PACKET_OK:
       if (!target_is_non_stop_p ())
@@ -6169,14 +6404,11 @@ extended_remote_target::attach (const char *args, int from_tty)
         ptid.  */
       ptid_t curr_ptid = remote_current_thread (ptid_t (pid));
 
-      /* Add the main thread to the thread list.  */
-      thread_info *thr = add_thread_silent (this, curr_ptid);
+      /* Add the main thread to the thread list.  We add the thread
+        silently in this case (the final true parameter).  */
+      thread_info *thr = remote_add_thread (curr_ptid, true, true, true);
 
       switch_to_thread (thr);
-
-      /* Don't consider the thread stopped until we've processed the
-        saved stop reply.  */
-      set_executing (this, thr->ptid, true);
     }
 
   /* Next, if the target can specify a description, read it.  We do
@@ -6188,28 +6420,16 @@ extended_remote_target::attach (const char *args, int from_tty)
       /* Use the previously fetched status.  */
       gdb_assert (wait_status != NULL);
 
-      if (target_can_async_p ())
-       {
-         struct notif_event *reply
-           =  remote_notif_parse (this, &notif_client_stop, wait_status);
-
-         push_stop_reply ((struct stop_reply *) reply);
+      struct notif_event *reply
+       =  remote_notif_parse (this, &notif_client_stop, wait_status);
 
-         target_async (1);
-       }
-      else
-       {
-         gdb_assert (wait_status != NULL);
-         strcpy (rs->buf.data (), wait_status);
-         rs->cached_wait_status = 1;
-       }
+      push_stop_reply ((struct stop_reply *) reply);
     }
   else
     {
       gdb_assert (wait_status == NULL);
 
       gdb_assert (target_can_async_p ());
-      target_async (1);
     }
 }
 
@@ -6242,7 +6462,7 @@ remote_target::remote_vcont_probe ()
 
   strcpy (rs->buf.data (), "vCont?");
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   buf = rs->buf.data ();
 
   /* Make sure that the features we assume are supported.  */
@@ -6282,8 +6502,7 @@ remote_target::remote_vcont_probe ()
        buf[0] = 0;
     }
 
-  packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCont]);
-  rs->supports_vCont_probed = true;
+  m_features.packet_ok (rs->buf, PACKET_vCont);
 }
 
 /* Helper function for building "vCont" resumptions.  Write a
@@ -6292,9 +6511,8 @@ remote_target::remote_vcont_probe ()
    thread to be resumed is PTID; STEP and SIGGNAL indicate whether the
    resumed thread should be single-stepped and/or signalled.  If PTID
    equals minus_one_ptid, then all threads are resumed; if PTID
-   represents a process, then all threads of the process are resumed;
-   the thread to be stepped and/or signalled is given in the global
-   INFERIOR_PTID.  */
+   represents a process, then all threads of the process are
+   resumed.  */
 
 char *
 remote_target::append_resumption (char *p, char *endp,
@@ -6313,7 +6531,7 @@ remote_target::append_resumption (char *p, char *endp,
              threads with a wildcard (though the protocol allows it,
              so stubs shouldn't make an active effort to forbid
              it).  */
-          && !(remote_multi_process_p (rs) && ptid.is_pid ()))
+          && !(m_features.remote_multi_process_p () && ptid.is_pid ()))
     {
       struct thread_info *tp;
 
@@ -6321,15 +6539,15 @@ remote_target::append_resumption (char *p, char *endp,
        {
          /* If we don't know about the target thread's tid, then
             we're resuming magic_null_ptid (see caller).  */
-         tp = find_thread_ptid (this, magic_null_ptid);
+         tp = this->find_thread (magic_null_ptid);
        }
       else
-       tp = find_thread_ptid (this, ptid);
+       tp = this->find_thread (ptid);
       gdb_assert (tp != NULL);
 
       if (tp->control.may_range_step)
        {
-         int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+         int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
 
          p += xsnprintf (p, endp - p, ";r%s,%s",
                          phex_nz (tp->control.step_range_start,
@@ -6347,7 +6565,7 @@ remote_target::append_resumption (char *p, char *endp,
   else
     p += xsnprintf (p, endp - p, ";c");
 
-  if (remote_multi_process_p (rs) && ptid.is_pid ())
+  if (m_features.remote_multi_process_p () && ptid.is_pid ())
     {
       ptid_t nptid;
 
@@ -6431,9 +6649,9 @@ remote_target::remote_resume_with_hc (ptid_t ptid, int step,
        warning (_(" - Can't pass signal %d to target in reverse: ignored."),
                 siggnal);
 
-      if (step && packet_support (PACKET_bs) == PACKET_DISABLE)
+      if (step && m_features.packet_support (PACKET_bs) == PACKET_DISABLE)
        error (_("Remote reverse-step not supported."));
-      if (!step && packet_support (PACKET_bc) == PACKET_DISABLE)
+      if (!step && m_features.packet_support (PACKET_bc) == PACKET_DISABLE)
        error (_("Remote reverse-continue not supported."));
 
       strcpy (buf, step ? "bs" : "bc");
@@ -6451,18 +6669,15 @@ remote_target::remote_resume_with_hc (ptid_t ptid, int step,
   putpkt (buf);
 }
 
-/* Resume the remote inferior by using a "vCont" packet.  The thread
-   to be resumed is PTID; STEP and SIGGNAL indicate whether the
-   resumed thread should be single-stepped and/or signalled.  If PTID
-   equals minus_one_ptid, then all threads are resumed; the thread to
-   be stepped and/or signalled is given in the global INFERIOR_PTID.
-   This function returns non-zero iff it resumes the inferior.
+/* Resume the remote inferior by using a "vCont" packet.  SCOPE_PTID,
+   STEP, and SIGGNAL have the same meaning as in target_resume.  This
+   function returns non-zero iff it resumes the inferior.
 
    This function issues a strict subset of all possible vCont commands
    at the moment.  */
 
 int
-remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
+remote_target::remote_resume_with_vcont (ptid_t scope_ptid, int step,
                                         enum gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
@@ -6473,10 +6688,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
   if (::execution_direction == EXEC_REVERSE)
     return 0;
 
-  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-    remote_vcont_probe ();
-
-  if (packet_support (PACKET_vCont) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_vCont) == PACKET_DISABLE)
     return 0;
 
   p = rs->buf.data ();
@@ -6488,7 +6700,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
 
   p += xsnprintf (p, endp - p, "vCont");
 
-  if (ptid == magic_null_ptid)
+  if (scope_ptid == magic_null_ptid)
     {
       /* MAGIC_NULL_PTID means that we don't have any active threads,
         so we don't have any TID numbers the inferior will
@@ -6496,7 +6708,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
         a TID.  */
       append_resumption (p, endp, minus_one_ptid, step, siggnal);
     }
-  else if (ptid == minus_one_ptid || ptid.is_pid ())
+  else if (scope_ptid == minus_one_ptid || scope_ptid.is_pid ())
     {
       /* Resume all threads (of all processes, or of a single
         process), with preference for INFERIOR_PTID.  This assumes
@@ -6510,15 +6722,15 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
 
       /* Also pass down any pending signaled resumption for other
         threads not the current.  */
-      p = append_pending_thread_resumptions (p, endp, ptid);
+      p = append_pending_thread_resumptions (p, endp, scope_ptid);
 
       /* And continue others without a signal.  */
-      append_resumption (p, endp, ptid, /*step=*/ 0, GDB_SIGNAL_0);
+      append_resumption (p, endp, scope_ptid, /*step=*/ 0, GDB_SIGNAL_0);
     }
   else
     {
-      /* Scheduler locking; resume only PTID.  */
-      append_resumption (p, endp, ptid, step, siggnal);
+      /* Scheduler locking; resume only SCOPE_PTID.  */
+      append_resumption (p, endp, scope_ptid, step, siggnal);
     }
 
   gdb_assert (strlen (rs->buf.data ()) < get_remote_packet_size ());
@@ -6529,7 +6741,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
       /* In non-stop, the stub replies to vCont with "OK".  The stop
         reply will be reported asynchronously by means of a `%Stop'
         notification.  */
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("Unexpected vCont reply in non-stop mode: %s"),
               rs->buf.data ());
@@ -6541,7 +6753,7 @@ remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
 /* Tell the remote machine to resume.  */
 
 void
-remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
+remote_target::resume (ptid_t scope_ptid, int step, enum gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -6554,18 +6766,20 @@ remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
      able to do vCont action coalescing.  */
   if (target_is_non_stop_p () && ::execution_direction != EXEC_REVERSE)
     {
-      remote_thread_info *remote_thr;
-
-      if (minus_one_ptid == ptid || ptid.is_pid ())
-       remote_thr = get_remote_thread_info (this, inferior_ptid);
-      else
-       remote_thr = get_remote_thread_info (this, ptid);
+      remote_thread_info *remote_thr
+       = get_remote_thread_info (inferior_thread ());
 
       /* We don't expect the core to ask to resume an already resumed (from
-         its point of view) thread.  */
+        its point of view) thread.  */
       gdb_assert (remote_thr->get_resume_state () == resume_state::NOT_RESUMED);
 
       remote_thr->set_resumed_pending_vcont (step, siggnal);
+
+      /* There's actually nothing that says that the core can't
+        request a wildcard resume in non-stop mode, though.  It's
+        just that we know it doesn't currently, so we don't bother
+        with it.  */
+      gdb_assert (scope_ptid == inferior_ptid);
       return;
     }
 
@@ -6581,23 +6795,13 @@ remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
   rs->last_resume_exec_dir = ::execution_direction;
 
   /* Prefer vCont, and fallback to s/c/S/C, which use Hc.  */
-  if (!remote_resume_with_vcont (ptid, step, siggnal))
-    remote_resume_with_hc (ptid, step, siggnal);
+  if (!remote_resume_with_vcont (scope_ptid, step, siggnal))
+    remote_resume_with_hc (scope_ptid, step, siggnal);
 
   /* Update resumed state tracked by the remote target.  */
-  for (thread_info *tp : all_non_exited_threads (this, ptid))
+  for (thread_info *tp : all_non_exited_threads (this, scope_ptid))
     get_remote_thread_info (tp)->set_resumed ();
 
-  /* We are about to start executing the inferior, let's register it
-     with the event loop.  NOTE: this is the one place where all the
-     execution commands end up.  We could alternatively do this in each
-     of the execution commands in infcmd.c.  */
-  /* FIXME: ezannoni 1999-09-28: We may need to move this out of here
-     into infcmd.c in order to allow inferior function calls to work
-     NOT asynchronously.  */
-  if (target_can_async_p ())
-    target_async (1);
-
   /* We've just told the target to resume.  The remote server will
      wait for the inferior to stop, and then send a stop reply.  In
      the mean time, we can't start another command/query ourselves
@@ -6625,7 +6829,7 @@ get_remote_inferior (inferior *inf)
   if (inf->priv == NULL)
     inf->priv.reset (new remote_inferior);
 
-  return static_cast<remote_inferior *> (inf->priv.get ());
+  return gdb::checked_static_cast<remote_inferior *> (inf->priv.get ());
 }
 
 /* Class used to track the construction of a vCont packet in the
@@ -6687,7 +6891,7 @@ vcont_builder::flush ()
 
   rs = m_remote->get_remote_state ();
   m_remote->putpkt (rs->buf);
-  m_remote->getpkt (&rs->buf, 0);
+  m_remote->getpkt (&rs->buf);
   if (strcmp (rs->buf.data (), "OK") != 0)
     error (_("Unexpected vCont reply in non-stop mode: %s"), rs->buf.data ());
 }
@@ -6828,7 +7032,7 @@ remote_target::commit_resumed ()
       /* If a thread is the parent of an unfollowed fork, then we
         can't do a global wildcard, as that would resume the fork
         child.  */
-      if (is_pending_fork_parent_thread (tp))
+      if (thread_pending_fork_status (tp) != nullptr)
        may_global_wildcard_vcont = false;
     }
 
@@ -6858,7 +7062,7 @@ remote_target::commit_resumed ()
       gdb_assert (!thread_is_in_step_over_chain (tp));
 
       /* We should never be commit-resuming a thread that has a stop reply.
-         Otherwise, we would end up reporting a stop event for a thread while
+        Otherwise, we would end up reporting a stop event for a thread while
         it is running on the remote target.  */
       remote_state *rs = get_remote_state ();
       for (const auto &stop_reply : rs->stop_reply_queue)
@@ -6868,7 +7072,7 @@ remote_target::commit_resumed ()
        = remote_thr->resumed_pending_vcont_info ();
 
       /* Check if we need to send a specific action for this thread.  If not,
-         it will be included in a wildcard resume instead.  */
+        it will be included in a wildcard resume instead.  */
       if (info.step || info.sig != GDB_SIGNAL_0
          || !get_remote_inferior (tp->inf)->may_wildcard_vcont)
        vcont_builder.push_action (tp->ptid, info.step, info.sig);
@@ -6925,7 +7129,7 @@ remote_target::has_pending_events ()
     {
       remote_state *rs = get_remote_state ();
 
-      if (async_event_handler_marked (rs->remote_async_inferior_event_token))
+      if (rs->async_event_handler_marked ())
        return true;
 
       /* Note that BUFCNT can be negative, indicating sticky
@@ -7000,7 +7204,7 @@ remote_target::remote_stop_ns (ptid_t ptid)
            sr->ptid = tp->ptid;
            sr->rs = rs;
            sr->ws.set_stopped (GDB_SIGNAL_0);
-           sr->arch = tp->inf->gdbarch;
+           sr->arch = tp->inf->arch ();
            sr->stop_reason = TARGET_STOPPED_BY_NO_REASON;
            sr->watch_data_address = 0;
            sr->core = 0;
@@ -7017,17 +7221,11 @@ remote_target::remote_stop_ns (ptid_t ptid)
          }
       }
 
-  /* FIXME: This supports_vCont_probed check is a workaround until
-     packet_support is per-connection.  */
-  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN
-      || !rs->supports_vCont_probed)
-    remote_vcont_probe ();
-
   if (!rs->supports_vCont.t)
     error (_("Remote server does not support stopping threads"));
 
   if (ptid == minus_one_ptid
-      || (!remote_multi_process_p (rs) && ptid.is_pid ()))
+      || (!m_features.remote_multi_process_p () && ptid.is_pid ()))
     p += xsnprintf (p, endp - p, "vCont;t");
   else
     {
@@ -7055,7 +7253,7 @@ remote_target::remote_stop_ns (ptid_t ptid)
   /* In non-stop, we get an immediate OK reply.  The stop reply will
      come in asynchronously by notification.  */
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (strcmp (rs->buf.data (), "OK") != 0)
     error (_("Stopping %s failed: %s"), target_pid_to_str (ptid).c_str (),
           rs->buf.data ());
@@ -7073,9 +7271,9 @@ remote_target::remote_interrupt_as ()
   rs->ctrlc_pending_p = 1;
 
   /* If the inferior is stopped already, but the core didn't know
-     about it yet, just ignore the request.  The cached wait status
+     about it yet, just ignore the request.  The pending stop events
      will be collected in remote_wait.  */
-  if (rs->cached_wait_status)
+  if (stop_reply_queue_length () > 0)
     return;
 
   /* Send interrupt_sequence to remote target.  */
@@ -7099,9 +7297,9 @@ remote_target::remote_interrupt_ns ()
   /* In non-stop, we get an immediate OK reply.  The stop reply will
      come in asynchronously by notification.  */
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCtrlC]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vCtrlC))
     {
     case PACKET_OK:
       break;
@@ -7232,7 +7430,7 @@ remote_target::stop_reply_queue_length ()
 
 static void
 remote_notif_stop_parse (remote_target *remote,
-                        struct notif_client *self, const char *buf,
+                        const notif_client *self, const char *buf,
                         struct notif_event *event)
 {
   remote->remote_parse_stop_reply (buf, (struct stop_reply *) event);
@@ -7240,7 +7438,7 @@ remote_notif_stop_parse (remote_target *remote,
 
 static void
 remote_notif_stop_ack (remote_target *remote,
-                      struct notif_client *self, const char *buf,
+                      const notif_client *self, const char *buf,
                       struct notif_event *event)
 {
   struct stop_reply *stop_reply = (struct stop_reply *) event;
@@ -7257,7 +7455,7 @@ remote_notif_stop_ack (remote_target *remote,
 
 static int
 remote_notif_stop_can_get_pending_events (remote_target *remote,
-                                         struct notif_client *self)
+                                         const notif_client *self)
 {
   /* We can't get pending events in remote_notif_process for
      notification stop, and we have to do this in remote_wait_ns
@@ -7265,7 +7463,7 @@ remote_notif_stop_can_get_pending_events (remote_target *remote,
      may exit and we have no chance to process them back in
      remote_wait_ns.  */
   remote_state *rs = remote->get_remote_state ();
-  mark_async_event_handler (rs->remote_async_inferior_event_token);
+  rs->mark_async_event_handler ();
   return 0;
 }
 
@@ -7283,7 +7481,7 @@ remote_notif_stop_alloc_reply ()
 
 /* A client of notification Stop.  */
 
-struct notif_client notif_client_stop =
+const notif_client notif_client_stop =
 {
   "Stop",
   "vStopped",
@@ -7303,17 +7501,18 @@ struct notif_client notif_client_stop =
 void
 remote_target::remove_new_fork_children (threads_listing_context *context)
 {
-  int pid = -1;
-  struct notif_client *notif = &notif_client_stop;
+  const notif_client *notif = &notif_client_stop;
 
   /* For any threads stopped at a fork event, remove the corresponding
      fork child threads from the CONTEXT list.  */
   for (thread_info *thread : all_non_exited_threads (this))
     {
-      const target_waitstatus &ws = thread_pending_fork_status (thread);
+      const target_waitstatus *ws = thread_pending_fork_status (thread);
 
-      if (is_pending_fork_parent (ws, pid, thread->ptid))
-       context->remove_thread (ws.child_ptid ());
+      if (ws == nullptr)
+       continue;
+
+      context->remove_thread (ws->child_ptid ());
     }
 
   /* Check for any pending fork events (not reported or processed yet)
@@ -7322,9 +7521,10 @@ remote_target::remove_new_fork_children (threads_listing_context *context)
   remote_notif_get_pending_events (notif);
   for (auto &event : get_remote_state ()->stop_reply_queue)
     if (event->ws.kind () == TARGET_WAITKIND_FORKED
-       || event->ws.kind () == TARGET_WAITKIND_VFORKED
-       || event->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
+       || event->ws.kind () == TARGET_WAITKIND_VFORKED)
       context->remove_thread (event->ws.child_ptid ());
+    else if (event->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
+      context->remove_thread (event->ptid);
 }
 
 /* Check whether any event pending in the vStopped queue would prevent a
@@ -7337,7 +7537,7 @@ void
 remote_target::check_pending_events_prevent_wildcard_vcont
   (bool *may_global_wildcard)
 {
-  struct notif_client *notif = &notif_client_stop;
+  const notif_client *notif = &notif_client_stop;
 
   remote_notif_get_pending_events (notif);
   for (auto &event : get_remote_state ()->stop_reply_queue)
@@ -7385,11 +7585,11 @@ remote_target::discard_pending_stop_replies (struct inferior *inf)
       /* Leave the notification pending, since the server expects that
         we acknowledge it with vStopped.  But clear its contents, so
         that later on when we acknowledge it, we also discard it.  */
+      remote_debug_printf
+       ("discarding in-flight notification: ptid: %s, ws: %s\n",
+        reply->ptid.to_string().c_str(),
+        reply->ws.to_string ().c_str ());
       reply->ws.set_ignore ();
-
-      if (remote_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "discarded in-flight notification\n");
     }
 
   /* Discard the stop replies we have already pulled with
@@ -7400,6 +7600,11 @@ remote_target::discard_pending_stop_replies (struct inferior *inf)
                              {
                                return event->ptid.pid () == inf->pid;
                              });
+  for (auto it = iter; it != rs->stop_reply_queue.end (); ++it)
+    remote_debug_printf
+      ("discarding queued stop reply: ptid: %s, ws: %s\n",
+       (*it)->ptid.to_string().c_str(),
+       (*it)->ws.to_string ().c_str ());
   rs->stop_reply_queue.erase (iter, rs->stop_reply_queue.end ());
 }
 
@@ -7445,9 +7650,9 @@ remote_target::remote_notif_remove_queued_reply (ptid_t ptid)
     }
 
   if (notif_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "notif: discard queued event: 'Stop' in %s\n",
-                       target_pid_to_str (ptid).c_str ());
+    gdb_printf (gdb_stdlog,
+               "notif: discard queued event: 'Stop' in %s\n",
+               ptid.to_string ().c_str ());
 
   return result;
 }
@@ -7463,10 +7668,10 @@ remote_target::queued_stop_reply (ptid_t ptid)
   remote_state *rs = get_remote_state ();
   struct stop_reply *r = remote_notif_remove_queued_reply (ptid);
 
-  if (!rs->stop_reply_queue.empty ())
+  if (!rs->stop_reply_queue.empty () && target_can_async_p ())
     {
       /* There's still at least an event left.  */
-      mark_async_event_handler (rs->remote_async_inferior_event_token);
+      rs->mark_async_event_handler ();
     }
 
   return r;
@@ -7483,12 +7688,17 @@ remote_target::push_stop_reply (struct stop_reply *new_event)
   rs->stop_reply_queue.push_back (stop_reply_up (new_event));
 
   if (notif_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "notif: push 'Stop' %s to queue %d\n",
-                       target_pid_to_str (new_event->ptid).c_str (),
-                       int (rs->stop_reply_queue.size ()));
-
-  mark_async_event_handler (rs->remote_async_inferior_event_token);
+    gdb_printf (gdb_stdlog,
+               "notif: push 'Stop' %s to queue %d\n",
+               new_event->ptid.to_string ().c_str (),
+               int (rs->stop_reply_queue.size ()));
+
+  /* Mark the pending event queue only if async mode is currently enabled.
+     If async mode is not currently enabled, then, if it later becomes
+     enabled, and there are events in this queue, we will mark the event
+     token at that point, see remote_target::async.  */
+  if (target_is_async_p ())
+    rs->mark_async_event_handler ();
 }
 
 /* Returns true if we have a stop reply for PTID.  */
@@ -7597,7 +7807,8 @@ Packet: '%s'\n"),
 
              /* Make sure the stub doesn't forget to indicate support
                 with qSupported.  */
-             if (packet_support (PACKET_swbreak_feature) != PACKET_ENABLE)
+             if (m_features.packet_support (PACKET_swbreak_feature)
+                 != PACKET_ENABLE)
                error (_("Unexpected swbreak stop reason"));
 
              /* The value part is documented as "must be empty",
@@ -7611,7 +7822,8 @@ Packet: '%s'\n"),
 
              /* Make sure the stub doesn't forget to indicate support
                 with qSupported.  */
-             if (packet_support (PACKET_hwbreak_feature) != PACKET_ENABLE)
+             if (m_features.packet_support (PACKET_hwbreak_feature)
+                 != PACKET_ENABLE)
                error (_("Unexpected hwbreak stop reason"));
 
              /* See above.  */
@@ -7730,7 +7942,7 @@ Packet: '%s'\n"),
                          continue;
                        }
 
-                     event->arch = inf->gdbarch;
+                     event->arch = inf->arch ();
                      rsa = event->rs->get_remote_arch_state (event->arch);
                    }
 
@@ -7897,16 +8109,16 @@ Packet: '%s'\n"),
 */
 
 void
-remote_target::remote_notif_get_pending_events (notif_client *nc)
+remote_target::remote_notif_get_pending_events (const notif_client *nc)
 {
   struct remote_state *rs = get_remote_state ();
 
   if (rs->notif_state->pending_event[nc->id] != NULL)
     {
       if (notif_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "notif: process: '%s' ack pending event\n",
-                           nc->name);
+       gdb_printf (gdb_stdlog,
+                   "notif: process: '%s' ack pending event\n",
+                   nc->name);
 
       /* acknowledge */
       nc->ack (this, nc, rs->buf.data (),
@@ -7915,7 +8127,7 @@ remote_target::remote_notif_get_pending_events (notif_client *nc)
 
       while (1)
        {
-         getpkt (&rs->buf, 0);
+         getpkt (&rs->buf);
          if (strcmp (rs->buf.data (), "OK") == 0)
            break;
          else
@@ -7925,9 +8137,9 @@ remote_target::remote_notif_get_pending_events (notif_client *nc)
   else
     {
       if (notif_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "notif: process: '%s' no pending reply\n",
-                           nc->name);
+       gdb_printf (gdb_stdlog,
+                   "notif: process: '%s' no pending reply\n",
+                   nc->name);
     }
 }
 
@@ -7935,7 +8147,7 @@ remote_target::remote_notif_get_pending_events (notif_client *nc)
    avoid having to export the whole remote_target class.  */
 
 void
-remote_notif_get_pending_events (remote_target *remote, notif_client *nc)
+remote_notif_get_pending_events (remote_target *remote, const notif_client *nc)
 {
   remote->remote_notif_get_pending_events (nc);
 }
@@ -8005,12 +8217,12 @@ remote_target::select_thread_for_ambiguous_stop_reply
        ambiguous = true;
     }
 
+  gdb_assert (first_resumed_thread != nullptr);
+
   remote_debug_printf ("first resumed thread is %s",
                       pid_to_str (first_resumed_thread->ptid).c_str ());
   remote_debug_printf ("is this guess ambiguous? = %d", ambiguous);
 
-  gdb_assert (first_resumed_thread != nullptr);
-
   /* Warn if the remote target is sending ambiguous stop replies.  */
   if (ambiguous)
     {
@@ -8120,12 +8332,12 @@ remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status,
   struct remote_state *rs = get_remote_state ();
   struct stop_reply *stop_reply;
   int ret;
-  int is_notif = 0;
+  bool is_notif = false;
 
   /* If in non-stop mode, get out of getpkt even if a
      notification is received. */
 
-  ret = getpkt_or_notif_sane (&rs->buf, 0 /* forever */, &is_notif);
+  ret = getpkt (&rs->buf, false /* forever */, &is_notif);
   while (1)
     {
       if (ret != -1 && !is_notif)
@@ -8164,7 +8376,7 @@ remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status,
        }
 
       /* Otherwise do a blocking wait.  */
-      ret = getpkt_or_notif_sane (&rs->buf, 1 /* forever */, &is_notif);
+      ret = getpkt (&rs->buf, true /* forever */, &is_notif);
     }
 }
 
@@ -8197,17 +8409,16 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status,
 
   stop_reply = queued_stop_reply (ptid);
   if (stop_reply != NULL)
-    return process_stop_reply (stop_reply, status);
-
-  if (rs->cached_wait_status)
-    /* Use the cached wait status, but only once.  */
-    rs->cached_wait_status = 0;
+    {
+      /* None of the paths that push a stop reply onto the queue should
+        have set the waiting_for_stop_reply flag.  */
+      gdb_assert (!rs->waiting_for_stop_reply);
+      event_ptid = process_stop_reply (stop_reply, status);
+    }
   else
     {
-      int ret;
-      int is_notif;
-      int forever = ((options & TARGET_WNOHANG) == 0
-                    && rs->wait_forever_enabled_p);
+      bool forever = ((options & TARGET_WNOHANG) == 0
+                     && rs->wait_forever_enabled_p);
 
       if (!rs->waiting_for_stop_reply)
        {
@@ -8219,7 +8430,8 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status,
         _never_ wait for ever -> test on target_is_async_p().
         However, before we do that we need to ensure that the caller
         knows how to take the target into/out of async mode.  */
-      ret = getpkt_or_notif_sane (&rs->buf, forever, &is_notif);
+      bool is_notif;
+      int ret = getpkt (&rs->buf, forever, &is_notif);
 
       /* GDB gets a notification.  Return to core as this event is
         not interesting.  */
@@ -8228,73 +8440,73 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status,
 
       if (ret == -1 && (options & TARGET_WNOHANG) != 0)
        return minus_one_ptid;
-    }
 
-  buf = rs->buf.data ();
+      buf = rs->buf.data ();
 
-  /* Assume that the target has acknowledged Ctrl-C unless we receive
-     an 'F' or 'O' packet.  */
-  if (buf[0] != 'F' && buf[0] != 'O')
-    rs->ctrlc_pending_p = 0;
+      /* Assume that the target has acknowledged Ctrl-C unless we receive
+        an 'F' or 'O' packet.  */
+      if (buf[0] != 'F' && buf[0] != 'O')
+       rs->ctrlc_pending_p = 0;
 
-  switch (buf[0])
-    {
-    case 'E':          /* Error of some sort.  */
-      /* We're out of sync with the target now.  Did it continue or
-        not?  Not is more likely, so report a stop.  */
-      rs->waiting_for_stop_reply = 0;
+      switch (buf[0])
+       {
+       case 'E':               /* Error of some sort.  */
+         /* We're out of sync with the target now.  Did it continue or
+            not?  Not is more likely, so report a stop.  */
+         rs->waiting_for_stop_reply = 0;
 
-      warning (_("Remote failure reply: %s"), buf);
-      status->set_stopped (GDB_SIGNAL_0);
-      break;
-    case 'F':          /* File-I/O request.  */
-      /* GDB may access the inferior memory while handling the File-I/O
-        request, but we don't want GDB accessing memory while waiting
-        for a stop reply.  See the comments in putpkt_binary.  Set
-        waiting_for_stop_reply to 0 temporarily.  */
-      rs->waiting_for_stop_reply = 0;
-      remote_fileio_request (this, buf, rs->ctrlc_pending_p);
-      rs->ctrlc_pending_p = 0;
-      /* GDB handled the File-I/O request, and the target is running
-        again.  Keep waiting for events.  */
-      rs->waiting_for_stop_reply = 1;
-      break;
-    case 'N': case 'T': case 'S': case 'X': case 'W':
-      {
-       /* There is a stop reply to handle.  */
-       rs->waiting_for_stop_reply = 0;
+         warning (_("Remote failure reply: %s"), buf);
+         status->set_stopped (GDB_SIGNAL_0);
+         break;
+       case 'F':               /* File-I/O request.  */
+         /* GDB may access the inferior memory while handling the File-I/O
+            request, but we don't want GDB accessing memory while waiting
+            for a stop reply.  See the comments in putpkt_binary.  Set
+            waiting_for_stop_reply to 0 temporarily.  */
+         rs->waiting_for_stop_reply = 0;
+         remote_fileio_request (this, buf, rs->ctrlc_pending_p);
+         rs->ctrlc_pending_p = 0;
+         /* GDB handled the File-I/O request, and the target is running
+            again.  Keep waiting for events.  */
+         rs->waiting_for_stop_reply = 1;
+         break;
+       case 'N': case 'T': case 'S': case 'X': case 'W':
+         {
+           /* There is a stop reply to handle.  */
+           rs->waiting_for_stop_reply = 0;
 
-       stop_reply
-         = (struct stop_reply *) remote_notif_parse (this,
-                                                     &notif_client_stop,
-                                                     rs->buf.data ());
+           stop_reply
+             = (struct stop_reply *) remote_notif_parse (this,
+                                                         &notif_client_stop,
+                                                         rs->buf.data ());
 
-       event_ptid = process_stop_reply (stop_reply, status);
-       break;
-      }
-    case 'O':          /* Console output.  */
-      remote_console_output (buf + 1);
-      break;
-    case '\0':
-      if (rs->last_sent_signal != GDB_SIGNAL_0)
-       {
-         /* Zero length reply means that we tried 'S' or 'C' and the
-            remote system doesn't support it.  */
-         target_terminal::ours_for_output ();
-         printf_filtered
-           ("Can't send signals to this remote system.  %s not sent.\n",
-            gdb_signal_to_name (rs->last_sent_signal));
-         rs->last_sent_signal = GDB_SIGNAL_0;
-         target_terminal::inferior ();
-
-         strcpy (buf, rs->last_sent_step ? "s" : "c");
-         putpkt (buf);
+           event_ptid = process_stop_reply (stop_reply, status);
+           break;
+         }
+       case 'O':               /* Console output.  */
+         remote_console_output (buf + 1);
+         break;
+       case '\0':
+         if (rs->last_sent_signal != GDB_SIGNAL_0)
+           {
+             /* Zero length reply means that we tried 'S' or 'C' and the
+                remote system doesn't support it.  */
+             target_terminal::ours_for_output ();
+             gdb_printf
+               ("Can't send signals to this remote system.  %s not sent.\n",
+                gdb_signal_to_name (rs->last_sent_signal));
+             rs->last_sent_signal = GDB_SIGNAL_0;
+             target_terminal::inferior ();
+
+             strcpy (buf, rs->last_sent_step ? "s" : "c");
+             putpkt (buf);
+             break;
+           }
+         /* fallthrough */
+       default:
+         warning (_("Invalid remote reply: %s"), buf);
          break;
        }
-      /* fallthrough */
-    default:
-      warning (_("Invalid remote reply: %s"), buf);
-      break;
     }
 
   if (status->kind () == TARGET_WAITKIND_NO_RESUMED)
@@ -8343,9 +8555,12 @@ remote_target::wait (ptid_t ptid, struct target_waitstatus *status,
   remote_state *rs = get_remote_state ();
 
   /* Start by clearing the flag that asks for our wait method to be called,
-     we'll mark it again at the end if needed.  */
+     we'll mark it again at the end if needed.  If the target is not in
+     async mode then the async token should not be marked.  */
   if (target_is_async_p ())
-    clear_async_event_handler (rs->remote_async_inferior_event_token);
+    rs->clear_async_event_handler ();
+  else
+    gdb_assert (!rs->async_event_handler_marked ());
 
   ptid_t event_ptid;
 
@@ -8360,7 +8575,7 @@ remote_target::wait (ptid_t ptid, struct target_waitstatus *status,
         notifications, then tell the event loop to call us again.  */
       if (!rs->stop_reply_queue.empty ()
          || rs->notif_state->pending_event[notif_client_stop.id] != nullptr)
-       mark_async_event_handler (rs->remote_async_inferior_event_token);
+       rs->mark_async_event_handler ();
     }
 
   return event_ptid;
@@ -8378,7 +8593,7 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
   gdb_byte *regp = (gdb_byte *) alloca (register_size (gdbarch, reg->regnum));
   int i;
 
-  if (packet_support (PACKET_p) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_p) == PACKET_DISABLE)
     return 0;
 
   if (reg->pnum == -1)
@@ -8389,11 +8604,11 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
   p += hexnumstr (p, reg->pnum);
   *p++ = '\0';
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   buf = rs->buf.data ();
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_p]))
+  switch (m_features.packet_ok (rs->buf, PACKET_p))
     {
     case PACKET_OK:
       break;
@@ -8401,8 +8616,7 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
       return 0;
     case PACKET_ERROR:
       error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
-            gdbarch_register_name (regcache->arch (), 
-                                   reg->regnum), 
+            gdbarch_register_name (regcache->arch (), reg->regnum),
             buf);
     }
 
@@ -8438,7 +8652,7 @@ remote_target::send_g_packet ()
 
   xsnprintf (rs->buf.data (), get_remote_packet_size (), "g");
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
     error (_("Could not read registers; remote failure reply '%s'"),
           rs->buf.data ());
@@ -8452,7 +8666,7 @@ remote_target::send_g_packet ()
         && rs->buf[0] != 'x')  /* New: unavailable register value.  */
     {
       remote_debug_printf ("Bad register packet; fetching a new packet");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
     }
 
   buf_len = strlen (rs->buf.data ());
@@ -8536,8 +8750,7 @@ remote_target::process_g_packet (struct regcache *regcache)
     {
       if (p[0] == 0 || p[1] == 0)
        /* This shouldn't happen - we adjusted sizeof_g_packet above.  */
-       internal_error (__FILE__, __LINE__,
-                       _("unexpected end of 'g' packet reply"));
+       internal_error (_("unexpected end of 'g' packet reply"));
 
       if (p[0] == 'x' && p[1] == 'x')
        regs[i] = 0;            /* 'x' */
@@ -8555,8 +8768,7 @@ remote_target::process_g_packet (struct regcache *regcache)
        {
          if ((r->offset + reg_size) * 2 > strlen (rs->buf.data ()))
            /* This shouldn't happen - we adjusted in_g_packet above.  */
-           internal_error (__FILE__, __LINE__,
-                           _("unexpected end of 'g' packet reply"));
+           internal_error (_("unexpected end of 'g' packet reply"));
          else if (rs->buf[r->offset * 2] == 'x')
            {
              gdb_assert (r->offset * 2 < strlen (rs->buf.data ()));
@@ -8660,7 +8872,7 @@ remote_target::prepare_to_store (struct regcache *regcache)
   int i;
 
   /* Make sure the entire registers array is valid.  */
-  switch (packet_support (PACKET_P))
+  switch (m_features.packet_support (PACKET_P))
     {
     case PACKET_DISABLE:
     case PACKET_SUPPORT_UNKNOWN:
@@ -8688,7 +8900,7 @@ remote_target::store_register_using_P (const struct regcache *regcache,
   gdb_byte *regp = (gdb_byte *) alloca (register_size (gdbarch, reg->regnum));
   char *p;
 
-  if (packet_support (PACKET_P) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_P) == PACKET_DISABLE)
     return 0;
 
   if (reg->pnum == -1)
@@ -8699,9 +8911,9 @@ remote_target::store_register_using_P (const struct regcache *regcache,
   regcache->raw_collect (reg->regnum, regp);
   bin2hex (regp, p, register_size (gdbarch, reg->regnum));
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_P]))
+  switch (m_features.packet_ok (rs->buf, PACKET_P))
     {
     case PACKET_OK:
       return 1;
@@ -8711,7 +8923,7 @@ remote_target::store_register_using_P (const struct regcache *regcache,
     case PACKET_UNKNOWN:
       return 0;
     default:
-      internal_error (__FILE__, __LINE__, _("Bad result from packet_ok"));
+      internal_error (_("Bad result from packet_ok"));
     }
 }
 
@@ -8748,9 +8960,9 @@ remote_target::store_registers_using_G (const struct regcache *regcache)
   *p++ = 'G';
   bin2hex (regs, p, rsa->sizeof_g_packet);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
-    error (_("Could not write registers; remote failure reply '%s'"), 
+    error (_("Could not write registers; remote failure reply '%s'"),
           rs->buf.data ());
 }
 
@@ -8853,7 +9065,7 @@ remote_address_masked (CORE_ADDR addr)
 
   /* If "remoteaddresssize" was not set, default to target address size.  */
   if (!address_size)
-    address_size = gdbarch_addr_bit (target_gdbarch ());
+    address_size = gdbarch_addr_bit (current_inferior ()->arch ());
 
   if (address_size > 0
       && address_size < (sizeof (ULONGEST) * 8))
@@ -8884,7 +9096,7 @@ remote_target::check_binary_download (CORE_ADDR addr)
 {
   struct remote_state *rs = get_remote_state ();
 
-  switch (packet_support (PACKET_X))
+  switch (m_features.packet_support (PACKET_X))
     {
     case PACKET_DISABLE:
       break;
@@ -8903,17 +9115,17 @@ remote_target::check_binary_download (CORE_ADDR addr)
        *p = '\0';
 
        putpkt_binary (rs->buf.data (), (int) (p - rs->buf.data ()));
-       getpkt (&rs->buf, 0);
+       getpkt (&rs->buf);
 
        if (rs->buf[0] == '\0')
          {
            remote_debug_printf ("binary downloading NOT supported by target");
-           remote_protocol_packets[PACKET_X].support = PACKET_DISABLE;
+           m_features.m_protocol_packets[PACKET_X].support = PACKET_DISABLE;
          }
        else
          {
            remote_debug_printf ("binary downloading supported by target");
-           remote_protocol_packets[PACKET_X].support = PACKET_ENABLE;
+           m_features.m_protocol_packets[PACKET_X].support = PACKET_ENABLE;
          }
        break;
       }
@@ -8983,8 +9195,7 @@ remote_target::remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
   int payload_length_bytes;
 
   if (packet_format != 'X' && packet_format != 'M')
-    internal_error (__FILE__, __LINE__,
-                   _("remote_write_bytes_aux: bad packet format"));
+    internal_error (_("remote_write_bytes_aux: bad packet format"));
 
   if (len_units == 0)
     return TARGET_XFER_EOF;
@@ -9033,8 +9244,7 @@ remote_target::remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
     }
 
   if (todo_units <= 0)
-    internal_error (__FILE__, __LINE__,
-                   _("minimum packet size too small to write data"));
+    internal_error (_("minimum packet size too small to write data"));
 
   /* If we already need another packet, then try to align the end
      of this packet to a useful boundary.  */
@@ -9109,7 +9319,7 @@ remote_target::remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
     }
 
   putpkt_binary (rs->buf.data (), (int) (p - rs->buf.data ()));
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   if (rs->buf[0] == 'E')
     return TARGET_XFER_E_IO;
@@ -9140,7 +9350,7 @@ remote_target::remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr,
   /* Check whether the target supports binary download.  */
   check_binary_download (memaddr);
 
-  switch (packet_support (PACKET_X))
+  switch (m_features.packet_support (PACKET_X))
     {
     case PACKET_ENABLE:
       packet_format = "X";
@@ -9149,10 +9359,9 @@ remote_target::remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr,
       packet_format = "M";
       break;
     case PACKET_SUPPORT_UNKNOWN:
-      internal_error (__FILE__, __LINE__,
-                     _("remote_write_bytes: bad internal state"));
+      internal_error (_("remote_write_bytes: bad internal state"));
     default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
+      internal_error (_("bad switch"));
     }
 
   return remote_write_bytes_aux (packet_format,
@@ -9202,7 +9411,7 @@ remote_target::remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr,
   p += hexnumstr (p, (ULONGEST) todo_units);
   *p = '\0';
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (rs->buf[0] == 'E'
       && isxdigit (rs->buf[1]) && isxdigit (rs->buf[2])
       && rs->buf[3] == '\0')
@@ -9237,7 +9446,8 @@ remote_target::remote_xfer_live_readonly_partial (gdb_byte *readbuf,
     {
       ULONGEST memend = memaddr + len;
 
-      const target_section_table *table = target_get_section_table (this);
+      const std::vector<target_section> *table
+       = target_get_section_table (this);
       for (const target_section &p : *table)
        {
          if (memaddr >= p.addr)
@@ -9350,13 +9560,13 @@ remote_target::remote_send_printf (const char *format, ...)
   va_end (ap);
 
   if (size >= max_size)
-    internal_error (__FILE__, __LINE__, _("Too long remote packet."));
+    internal_error (_("Too long remote packet."));
 
   if (putpkt (rs->buf) < 0)
     error (_("Communication problem with target."));
 
   rs->buf[0] = '\0';
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   return packet_check_result (rs->buf);
 }
@@ -9369,7 +9579,7 @@ static const int remote_flash_timeout = 1000;
 void
 remote_target::flash_erase (ULONGEST address, LONGEST length)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+  int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
   enum packet_result ret;
   scoped_restore restore_timeout
     = make_scoped_restore (&remote_timeout, remote_flash_timeout);
@@ -9420,11 +9630,6 @@ remote_target::flash_done ()
     }
 }
 
-void
-remote_target::files_info ()
-{
-  puts_filtered ("Debugging a target over a serial line.\n");
-}
 \f
 /* Stuff for dealing with the packets which are part of this protocol.
    See comment at top of file for details.  */
@@ -9481,7 +9686,7 @@ remote_target::readchar (int timeout)
       /* no return */
     case SERIAL_ERROR:
       unpush_and_perror (this, _("Remote communication error.  "
-                                "Target disconnected."));
+                                "Target disconnected"));
       /* no return */
     case SERIAL_TIMEOUT:
       break;
@@ -9510,7 +9715,7 @@ remote_target::remote_serial_write (const char *str, int len)
   if (serial_write (rs->remote_desc, str, len))
     {
       unpush_and_perror (this, _("Remote communication error.  "
-                                "Target disconnected."));
+                                "Target disconnected"));
     }
 
   if (rs->got_ctrlc_during_io)
@@ -9526,7 +9731,7 @@ escape_buffer (const char *buf, int n)
   string_file stb;
 
   stb.putstrn (buf, n, '\\');
-  return std::move (stb.string ());
+  return stb.release ();
 }
 
 int
@@ -9579,10 +9784,6 @@ remote_target::putpkt_binary (const char *buf, int cnt)
               "and then try again."));
     }
 
-  /* We're sending out a new packet.  Make sure we don't look at a
-     stale cached response.  */
-  rs->cached_wait_status = 0;
-
   /* Copy the packet into buffer BUF2, encapsulating it
      and giving it a checksum.  */
 
@@ -9849,7 +10050,7 @@ remote_target::read_frame (gdb::char_vector *buf_p)
              }
 
            buf[bc] = '\0';
-           printf_filtered (_("Invalid run length encoding: %s\n"), buf);
+           gdb_printf (_("Invalid run length encoding: %s\n"), buf);
            return -1;
          }
        default:
@@ -9878,41 +10079,23 @@ static void
 show_watchdog (struct ui_file *file, int from_tty,
               struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Watchdog timer is %s.\n"), value);
-}
-
-/* Read a packet from the remote machine, with error checking, and
-   store it in *BUF.  Resize *BUF if necessary to hold the result.  If
-   FOREVER, wait forever rather than timing out; this is used (in
-   synchronous mode) to wait for a target that is is executing user
-   code to stop.  */
-/* FIXME: ezannoni 2000-02-01 this wrapper is necessary so that we
-   don't have to change all the calls to getpkt to deal with the
-   return value, because at the moment I don't know what the right
-   thing to do it for those.  */
-
-void
-remote_target::getpkt (gdb::char_vector *buf, int forever)
-{
-  getpkt_sane (buf, forever);
+  gdb_printf (file, _("Watchdog timer is %s.\n"), value);
 }
 
-
 /* Read a packet from the remote machine, with error checking, and
    store it in *BUF.  Resize *BUF if necessary to hold the result.  If
    FOREVER, wait forever rather than timing out; this is used (in
    synchronous mode) to wait for a target that is is executing user
-   code to stop.  If FOREVER == 0, this function is allowed to time
+   code to stop.  If FOREVER == false, this function is allowed to time
    out gracefully and return an indication of this to the caller.
-   Otherwise return the number of bytes read.  If EXPECTING_NOTIF,
-   consider receiving a notification enough reason to return to the
-   caller.  *IS_NOTIF is an output boolean that indicates whether *BUF
-   holds a notification or not (a regular packet).  */
+   Otherwise return the number of bytes read.  If IS_NOTIF is not
+   NULL, then consider receiving a notification enough reason to
+   return to the caller.  In this case, *IS_NOTIF is an output boolean
+   that indicates whether *BUF holds a notification or not (a regular
+   packet).  */
 
 int
-remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
-                                      int forever, int expecting_notif,
-                                      int *is_notif)
+remote_target::getpkt (gdb::char_vector *buf, bool forever, bool *is_notif)
 {
   struct remote_state *rs = get_remote_state ();
   int c;
@@ -9920,15 +10103,11 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
   int timeout;
   int val = -1;
 
-  /* We're reading a new response.  Make sure we don't look at a
-     previously cached response.  */
-  rs->cached_wait_status = 0;
-
   strcpy (buf->data (), "timeout");
 
   if (forever)
     timeout = watchdog > 0 ? watchdog : -1;
-  else if (expecting_notif)
+  else if (is_notif != nullptr)
     timeout = 0; /* There should already be a char in the buffer.  If
                    not, bail out.  */
   else
@@ -9959,7 +10138,7 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
 
          if (c == SERIAL_TIMEOUT)
            {
-             if (expecting_notif)
+             if (is_notif != nullptr)
                return -1; /* Don't complain, it's normal to not get
                              anything in this case.  */
 
@@ -9989,7 +10168,7 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
        {
          /* We have tried hard enough, and just can't receive the
             packet/notification.  Give up.  */
-         printf_unfiltered (_("Ignoring packet error, continuing...\n"));
+         gdb_printf (_("Ignoring packet error, continuing...\n"));
 
          /* Skip the ack char if we're in no-ack mode.  */
          if (!rs->noack_mode)
@@ -10026,7 +10205,7 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
          if (!rs->noack_mode)
            remote_serial_write ("+", 1);
          if (is_notif != NULL)
-           *is_notif = 0;
+           *is_notif = false;
          return val;
        }
 
@@ -10041,70 +10220,60 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
             escape_buffer (buf->data (), val).c_str ());
 
          if (is_notif != NULL)
-           *is_notif = 1;
+           *is_notif = true;
 
          handle_notification (rs->notif_state, buf->data ());
 
          /* Notifications require no acknowledgement.  */
 
-         if (expecting_notif)
-           return val;
-       }
-    }
-}
-
-int
-remote_target::getpkt_sane (gdb::char_vector *buf, int forever)
-{
-  return getpkt_or_notif_sane_1 (buf, forever, 0, NULL);
-}
-
-int
-remote_target::getpkt_or_notif_sane (gdb::char_vector *buf, int forever,
-                                    int *is_notif)
-{
-  return getpkt_or_notif_sane_1 (buf, forever, 1, is_notif);
+         if (is_notif != nullptr)
+           return val;
+       }
+    }
 }
 
-/* Kill any new fork children of process PID that haven't been
+/* Kill any new fork children of inferior INF that haven't been
    processed by follow_fork.  */
 
 void
-remote_target::kill_new_fork_children (int pid)
+remote_target::kill_new_fork_children (inferior *inf)
 {
   remote_state *rs = get_remote_state ();
-  struct notif_client *notif = &notif_client_stop;
+  const notif_client *notif = &notif_client_stop;
 
-  /* Kill the fork child threads of any threads in process PID
-     that are stopped at a fork event.  */
-  for (thread_info *thread : all_non_exited_threads (this))
+  /* Kill the fork child threads of any threads in inferior INF that are stopped
+     at a fork event.  */
+  for (thread_info *thread : inf->non_exited_threads ())
     {
-      const target_waitstatus &ws = thread->pending_follow;
+      const target_waitstatus *ws = thread_pending_fork_status (thread);
 
-      if (is_pending_fork_parent (ws, pid, thread->ptid))
-       {
-         int child_pid = ws.child_ptid ().pid ();
-         int res;
+      if (ws == nullptr)
+       continue;
 
-         res = remote_vkill (child_pid);
-         if (res != 0)
-           error (_("Can't kill fork child process %d"), child_pid);
-       }
+      int child_pid = ws->child_ptid ().pid ();
+      int res = remote_vkill (child_pid);
+
+      if (res != 0)
+       error (_("Can't kill fork child process %d"), child_pid);
     }
 
   /* Check for any pending fork events (not reported or processed yet)
-     in process PID and kill those fork child threads as well.  */
+     in inferior INF and kill those fork child threads as well.  */
   remote_notif_get_pending_events (notif);
   for (auto &event : rs->stop_reply_queue)
-    if (is_pending_fork_parent (event->ws, pid, event->ptid))
-      {
-       int child_pid = event->ws.child_ptid ().pid ();
-       int res;
+    {
+      if (event->ptid.pid () != inf->pid)
+       continue;
 
-       res = remote_vkill (child_pid);
-       if (res != 0)
-         error (_("Can't kill fork child process %d"), child_pid);
-      }
+      if (!is_fork_status (event->ws.kind ()))
+       continue;
+
+      int child_pid = event->ws.child_ptid ().pid ();
+      int res = remote_vkill (child_pid);
+
+      if (res != 0)
+       error (_("Can't kill fork child process %d"), child_pid);
+    }
 }
 
 \f
@@ -10114,18 +10283,19 @@ void
 remote_target::kill ()
 {
   int res = -1;
-  int pid = inferior_ptid.pid ();
-  struct remote_state *rs = get_remote_state ();
+  inferior *inf = find_inferior_pid (this, inferior_ptid.pid ());
 
-  if (packet_support (PACKET_vKill) != PACKET_DISABLE)
+  gdb_assert (inf != nullptr);
+
+  if (m_features.packet_support (PACKET_vKill) != PACKET_DISABLE)
     {
       /* If we're stopped while forking and we haven't followed yet,
         kill the child task.  We need to do this before killing the
         parent task because if this is a vfork then the parent will
         be sleeping.  */
-      kill_new_fork_children (pid);
+      kill_new_fork_children (inf);
 
-      res = remote_vkill (pid);
+      res = remote_vkill (inf->pid);
       if (res == 0)
        {
          target_mourn_inferior (inferior_ptid);
@@ -10136,7 +10306,7 @@ remote_target::kill ()
   /* If we are in 'target remote' mode and we are killing the only
      inferior, then we will tell gdbserver to exit and unpush the
      target.  */
-  if (res == -1 && !remote_multi_process_p (rs)
+  if (res == -1 && !m_features.remote_multi_process_p ()
       && number_of_live_inferiors (this) == 1)
     {
       remote_kill_k ();
@@ -10158,7 +10328,7 @@ remote_target::kill ()
 int
 remote_target::remote_vkill (int pid)
 {
-  if (packet_support (PACKET_vKill) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_vKill) == PACKET_DISABLE)
     return -1;
 
   remote_state *rs = get_remote_state ();
@@ -10166,10 +10336,9 @@ remote_target::remote_vkill (int pid)
   /* Tell the remote target to detach.  */
   xsnprintf (rs->buf.data (), get_remote_packet_size (), "vKill;%x", pid);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf,
-                    &remote_protocol_packets[PACKET_vKill]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vKill))
     {
     case PACKET_OK:
       return 0;
@@ -10178,7 +10347,7 @@ remote_target::remote_vkill (int pid)
     case PACKET_UNKNOWN:
       return -1;
     default:
-      internal_error (__FILE__, __LINE__, _("Bad result from packet_ok"));
+      internal_error (_("Bad result from packet_ok"));
     }
 }
 
@@ -10265,7 +10434,8 @@ remote_target::mourn_inferior ()
 bool
 extended_remote_target::supports_disable_randomization ()
 {
-  return packet_support (PACKET_QDisableRandomization) == PACKET_ENABLE;
+  return (m_features.packet_support (PACKET_QDisableRandomization)
+         == PACKET_ENABLE);
 }
 
 void
@@ -10293,7 +10463,7 @@ remote_target::extended_remote_run (const std::string &args)
 
   /* If the user has disabled vRun support, or we have detected that
      support is not available, do not try it.  */
-  if (packet_support (PACKET_vRun) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_vRun) == PACKET_DISABLE)
     return -1;
 
   strcpy (rs->buf.data (), "vRun;");
@@ -10322,9 +10492,9 @@ remote_target::extended_remote_run (const std::string &args)
   rs->buf[len++] = '\0';
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vRun]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vRun))
     {
     case PACKET_OK:
       /* We have a wait response.  All is well.  */
@@ -10364,7 +10534,7 @@ remote_target::send_environment_packet (const char *action,
             "%s:%s", packet, encoded_value.c_str ());
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   if (strcmp (rs->buf.data (), "OK") != 0)
     warning (_("Unable to %s environment variable '%s' on remote."),
             action, value);
@@ -10377,22 +10547,26 @@ remote_target::extended_remote_environment_support ()
 {
   remote_state *rs = get_remote_state ();
 
-  if (packet_support (PACKET_QEnvironmentReset) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QEnvironmentReset) != PACKET_DISABLE)
     {
       putpkt ("QEnvironmentReset");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       if (strcmp (rs->buf.data (), "OK") != 0)
        warning (_("Unable to reset environment on remote."));
     }
 
   gdb_environ *e = &current_inferior ()->environment;
 
-  if (packet_support (PACKET_QEnvironmentHexEncoded) != PACKET_DISABLE)
-    for (const std::string &el : e->user_set_env ())
-      send_environment_packet ("set", "QEnvironmentHexEncoded",
-                              el.c_str ());
+  if (m_features.packet_support (PACKET_QEnvironmentHexEncoded)
+      != PACKET_DISABLE)
+    {
+      for (const std::string &el : e->user_set_env ())
+       send_environment_packet ("set", "QEnvironmentHexEncoded",
+                                el.c_str ());
+    }
+
 
-  if (packet_support (PACKET_QEnvironmentUnset) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QEnvironmentUnset) != PACKET_DISABLE)
     for (const std::string &el : e->user_unset_env ())
       send_environment_packet ("unset", "QEnvironmentUnset", el.c_str ());
 }
@@ -10403,7 +10577,7 @@ remote_target::extended_remote_environment_support ()
 void
 remote_target::extended_remote_set_inferior_cwd ()
 {
-  if (packet_support (PACKET_QSetWorkingDir) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QSetWorkingDir) != PACKET_DISABLE)
     {
       const std::string &inferior_cwd = current_inferior ()->cwd ();
       remote_state *rs = get_remote_state ();
@@ -10426,10 +10600,8 @@ remote_target::extended_remote_set_inferior_cwd ()
        }
 
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
-      if (packet_ok (rs->buf,
-                    &remote_protocol_packets[PACKET_QSetWorkingDir])
-         != PACKET_OK)
+      getpkt (&rs->buf);
+      if (m_features.packet_ok (rs->buf, PACKET_QSetWorkingDir) != PACKET_OK)
        error (_("\
 Remote replied unexpectedly while setting the inferior's working\n\
 directory: %s"),
@@ -10457,7 +10629,7 @@ extended_remote_target::create_inferior (const char *exec_file,
   /* If running asynchronously, register the target file descriptor
      with the event loop.  */
   if (target_can_async_p ())
-    target_async (1);
+    target_async (true);
 
   /* Disable address space randomization if requested (and supported).  */
   if (supports_disable_randomization ())
@@ -10465,12 +10637,12 @@ extended_remote_target::create_inferior (const char *exec_file,
 
   /* If startup-with-shell is on, we inform gdbserver to start the
      remote inferior using a shell.  */
-  if (packet_support (PACKET_QStartupWithShell) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QStartupWithShell) != PACKET_DISABLE)
     {
       xsnprintf (rs->buf.data (), get_remote_packet_size (),
                 "QStartupWithShell:%d", startup_with_shell ? 1 : 0);
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("\
 Remote replied unexpectedly while setting startup-with-shell: %s"),
@@ -10525,9 +10697,9 @@ remote_add_target_side_condition (struct gdbarch *gdbarch,
   /* Send conditions to the target.  */
   for (agent_expr *aexpr : bp_tgt->conditions)
     {
-      xsnprintf (buf, buf_end - buf, "X%x,", aexpr->len);
+      xsnprintf (buf, buf_end - buf, "X%x,", (int) aexpr->buf.size ());
       buf += strlen (buf);
-      for (int i = 0; i < aexpr->len; ++i)
+      for (int i = 0; i < aexpr->buf.size (); ++i)
        buf = pack_hex_byte (buf, aexpr->buf[i]);
       *buf = '\0';
     }
@@ -10550,9 +10722,9 @@ remote_add_target_side_commands (struct gdbarch *gdbarch,
      cmds parameter.  */
   for (agent_expr *aexpr : bp_tgt->tcommands)
     {
-      sprintf (buf, "X%x,", aexpr->len);
+      sprintf (buf, "X%x,", (int) aexpr->buf.size ());
       buf += strlen (buf);
-      for (int i = 0; i < aexpr->len; ++i)
+      for (int i = 0; i < aexpr->buf.size (); ++i)
        buf = pack_hex_byte (buf, aexpr->buf[i]);
       *buf = '\0';
     }
@@ -10571,7 +10743,7 @@ remote_target::insert_breakpoint (struct gdbarch *gdbarch,
      fails, and the user has explicitly requested the Z support then
      report an error, otherwise, mark it disabled and go on.  */
 
-  if (packet_support (PACKET_Z0) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_Z0) != PACKET_DISABLE)
     {
       CORE_ADDR addr = bp_tgt->reqstd_address;
       struct remote_state *rs;
@@ -10579,7 +10751,7 @@ remote_target::insert_breakpoint (struct gdbarch *gdbarch,
 
       /* Make sure the remote is pointing at the right process, if
         necessary.  */
-      if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+      if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
        set_general_process ();
 
       rs = get_remote_state ();
@@ -10600,9 +10772,9 @@ remote_target::insert_breakpoint (struct gdbarch *gdbarch,
        remote_add_target_side_commands (gdbarch, bp_tgt, p);
 
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
-      switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0]))
+      switch (m_features.packet_ok (rs->buf, PACKET_Z0))
        {
        case PACKET_ERROR:
          return -1;
@@ -10630,14 +10802,14 @@ remote_target::remove_breakpoint (struct gdbarch *gdbarch,
   CORE_ADDR addr = bp_tgt->placed_address;
   struct remote_state *rs = get_remote_state ();
 
-  if (packet_support (PACKET_Z0) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_Z0) != PACKET_DISABLE)
     {
       char *p = rs->buf.data ();
       char *endbuf = p + get_remote_packet_size ();
 
       /* Make sure the remote is pointing at the right process, if
         necessary.  */
-      if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+      if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
        set_general_process ();
 
       *(p++) = 'z';
@@ -10649,7 +10821,7 @@ remote_target::remove_breakpoint (struct gdbarch *gdbarch,
       xsnprintf (p, endbuf - p, ",%d", bp_tgt->kind);
 
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
       return (rs->buf[0] == 'E');
     }
@@ -10672,8 +10844,7 @@ watchpoint_to_Z_packet (int type)
       return Z_PACKET_ACCESS_WP;
       break;
     default:
-      internal_error (__FILE__, __LINE__,
-                     _("hw_bp_to_z: bad watchpoint type %d"), type);
+      internal_error (_("hw_bp_to_z: bad watchpoint type %d"), type);
     }
 }
 
@@ -10686,12 +10857,13 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len,
   char *p;
   enum Z_packet_type packet = watchpoint_to_Z_packet (type);
 
-  if (packet_support (PACKET_Z0 + packet) == PACKET_DISABLE)
+  if (m_features.packet_support ((to_underlying (PACKET_Z0)
+                                 + to_underlying (packet))) == PACKET_DISABLE)
     return 1;
 
   /* Make sure the remote is pointing at the right process, if
      necessary.  */
-  if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+  if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
     set_general_process ();
 
   xsnprintf (rs->buf.data (), endbuf - rs->buf.data (), "Z%x,", packet);
@@ -10701,9 +10873,10 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len,
   xsnprintf (p, endbuf - p, ",%x", len);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+  switch (m_features.packet_ok (rs->buf, (to_underlying (PACKET_Z0)
+                                         + to_underlying (packet))))
     {
     case PACKET_ERROR:
       return -1;
@@ -10712,8 +10885,7 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len,
     case PACKET_OK:
       return 0;
     }
-  internal_error (__FILE__, __LINE__,
-                 _("remote_insert_watchpoint: reached end of function"));
+  internal_error (_("remote_insert_watchpoint: reached end of function"));
 }
 
 bool
@@ -10735,12 +10907,13 @@ remote_target::remove_watchpoint (CORE_ADDR addr, int len,
   char *p;
   enum Z_packet_type packet = watchpoint_to_Z_packet (type);
 
-  if (packet_support (PACKET_Z0 + packet) == PACKET_DISABLE)
+  if (m_features.packet_support ((to_underlying (PACKET_Z0)
+                                 + to_underlying (packet))) == PACKET_DISABLE)
     return -1;
 
   /* Make sure the remote is pointing at the right process, if
      necessary.  */
-  if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+  if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
     set_general_process ();
 
   xsnprintf (rs->buf.data (), endbuf - rs->buf.data (), "z%x,", packet);
@@ -10749,9 +10922,10 @@ remote_target::remove_watchpoint (CORE_ADDR addr, int len,
   p += hexnumstr (p, (ULONGEST) addr);
   xsnprintf (p, endbuf - p, ",%x", len);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+  switch (m_features.packet_ok (rs->buf, (to_underlying (PACKET_Z0)
+                                         + to_underlying (packet))))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -10759,8 +10933,7 @@ remote_target::remove_watchpoint (CORE_ADDR addr, int len,
     case PACKET_OK:
       return 0;
     }
-  internal_error (__FILE__, __LINE__,
-                 _("remote_remove_watchpoint: reached end of function"));
+  internal_error (_("remote_remove_watchpoint: reached end of function"));
 }
 
 
@@ -10825,7 +10998,7 @@ remote_target::stopped_by_sw_breakpoint ()
 bool
 remote_target::supports_stopped_by_sw_breakpoint ()
 {
-  return (packet_support (PACKET_swbreak_feature) == PACKET_ENABLE);
+  return (m_features.packet_support (PACKET_swbreak_feature) == PACKET_ENABLE);
 }
 
 /* The to_stopped_by_hw_breakpoint method of target remote.  */
@@ -10846,7 +11019,7 @@ remote_target::stopped_by_hw_breakpoint ()
 bool
 remote_target::supports_stopped_by_hw_breakpoint ()
 {
-  return (packet_support (PACKET_hwbreak_feature) == PACKET_ENABLE);
+  return (m_features.packet_support (PACKET_hwbreak_feature) == PACKET_ENABLE);
 }
 
 bool
@@ -10885,12 +11058,12 @@ remote_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
   char *p, *endbuf;
   char *message;
 
-  if (packet_support (PACKET_Z1) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_Z1) == PACKET_DISABLE)
     return -1;
 
   /* Make sure the remote is pointing at the right process, if
      necessary.  */
-  if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+  if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
     set_general_process ();
 
   rs = get_remote_state ();
@@ -10912,9 +11085,9 @@ remote_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
     remote_add_target_side_commands (gdbarch, bp_tgt, p);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
+  switch (m_features.packet_ok (rs->buf, PACKET_Z1))
     {
     case PACKET_ERROR:
       if (rs->buf[1] == '.')
@@ -10929,8 +11102,7 @@ remote_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
     case PACKET_OK:
       return 0;
     }
-  internal_error (__FILE__, __LINE__,
-                 _("remote_insert_hw_breakpoint: reached end of function"));
+  internal_error (_("remote_insert_hw_breakpoint: reached end of function"));
 }
 
 
@@ -10943,12 +11115,12 @@ remote_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
   char *p = rs->buf.data ();
   char *endbuf = p + get_remote_packet_size ();
 
-  if (packet_support (PACKET_Z1) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_Z1) == PACKET_DISABLE)
     return -1;
 
   /* Make sure the remote is pointing at the right process, if
      necessary.  */
-  if (!gdbarch_has_global_breakpoints (target_gdbarch ()))
+  if (!gdbarch_has_global_breakpoints (current_inferior ()->arch ()))
     set_general_process ();
 
   *(p++) = 'z';
@@ -10960,9 +11132,9 @@ remote_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
   xsnprintf (p, endbuf  - p, ",%x", bp_tgt->kind);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
+  switch (m_features.packet_ok (rs->buf, PACKET_Z1))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -10970,8 +11142,7 @@ remote_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
     case PACKET_OK:
       return 0;
     }
-  internal_error (__FILE__, __LINE__,
-                 _("remote_remove_hw_breakpoint: reached end of function"));
+  internal_error (_("remote_remove_hw_breakpoint: reached end of function"));
 }
 
 /* Verify memory using the "qCRC:" request.  */
@@ -10986,7 +11157,7 @@ remote_target::verify_memory (const gdb_byte *data, CORE_ADDR lma, ULONGEST size
   /* It doesn't make sense to use qCRC if the remote target is
      connected but not running.  */
   if (target_has_execution ()
-      && packet_support (PACKET_qCRC) != PACKET_DISABLE)
+      && m_features.packet_support (PACKET_qCRC) != PACKET_DISABLE)
     {
       enum packet_result result;
 
@@ -11002,10 +11173,9 @@ remote_target::verify_memory (const gdb_byte *data, CORE_ADDR lma, ULONGEST size
         reply.  */
       host_crc = xcrc32 (data, size, 0xffffffff);
 
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
-      result = packet_ok (rs->buf,
-                         &remote_protocol_packets[PACKET_qCRC]);
+      result = m_features.packet_ok (rs->buf, PACKET_qCRC);
       if (result == PACKET_ERROR)
        return -1;
       else if (result == PACKET_OK)
@@ -11074,25 +11244,25 @@ compare_sections_command (const char *args, int from_tty)
 
       if (res == -1)
        error (_("target memory fault, section %s, range %s -- %s"), sectname,
-              paddress (target_gdbarch (), lma),
-              paddress (target_gdbarch (), lma + size));
+              paddress (current_inferior ()->arch (), lma),
+              paddress (current_inferior ()->arch (), lma + size));
 
-      printf_filtered ("Section %s, range %s -- %s: ", sectname,
-                      paddress (target_gdbarch (), lma),
-                      paddress (target_gdbarch (), lma + size));
+      gdb_printf ("Section %s, range %s -- %s: ", sectname,
+                 paddress (current_inferior ()->arch (), lma),
+                 paddress (current_inferior ()->arch (), lma + size));
       if (res)
-       printf_filtered ("matched.\n");
+       gdb_printf ("matched.\n");
       else
        {
-         printf_filtered ("MIS-MATCHED!\n");
+         gdb_printf ("MIS-MATCHED!\n");
          mismatched++;
        }
     }
   if (mismatched > 0)
-    warning (_("One or more sections of the target image does not match\n\
-the loaded file\n"));
+    warning (_("One or more sections of the target image does "
+              "not match the loaded file"));
   if (args && !matched)
-    printf_filtered (_("No loaded section named '%s'.\n"), args);
+    gdb_printf (_("No loaded section named '%s'.\n"), args);
 }
 
 /* Write LEN bytes from WRITEBUF into OBJECT_NAME/ANNEX at OFFSET
@@ -11104,30 +11274,30 @@ remote_target::remote_write_qxfer (const char *object_name,
                                   const char *annex, const gdb_byte *writebuf,
                                   ULONGEST offset, LONGEST len,
                                   ULONGEST *xfered_len,
-                                  struct packet_config *packet)
+                                  const unsigned int which_packet)
 {
   int i, buf_len;
   ULONGEST n;
   struct remote_state *rs = get_remote_state ();
-  int max_size = get_memory_write_packet_size (); 
+  int max_size = get_memory_write_packet_size ();
 
-  if (packet_config_support (packet) == PACKET_DISABLE)
+  if (m_features.packet_support (which_packet) == PACKET_DISABLE)
     return TARGET_XFER_E_IO;
 
   /* Insert header.  */
-  i = snprintf (rs->buf.data (), max_size, 
+  i = snprintf (rs->buf.data (), max_size,
                "qXfer:%s:write:%s:%s:",
                object_name, annex ? annex : "",
                phex_nz (offset, sizeof offset));
   max_size -= (i + 1);
 
   /* Escape as much data as fits into rs->buf.  */
-  buf_len = remote_escape_output 
+  buf_len = remote_escape_output
     (writebuf, len, 1, (gdb_byte *) rs->buf.data () + i, &max_size, max_size);
 
   if (putpkt_binary (rs->buf.data (), i + buf_len) < 0
-      || getpkt_sane (&rs->buf, 0) < 0
-      || packet_ok (rs->buf, packet) != PACKET_OK)
+      || getpkt (&rs->buf) < 0
+      || m_features.packet_ok (rs->buf, which_packet) != PACKET_OK)
     return TARGET_XFER_E_IO;
 
   unpack_varlen_hex (rs->buf.data (), &n);
@@ -11149,12 +11319,12 @@ remote_target::remote_read_qxfer (const char *object_name,
                                  gdb_byte *readbuf, ULONGEST offset,
                                  LONGEST len,
                                  ULONGEST *xfered_len,
-                                 struct packet_config *packet)
+                                 const unsigned int which_packet)
 {
   struct remote_state *rs = get_remote_state ();
   LONGEST i, n, packet_len;
 
-  if (packet_config_support (packet) == PACKET_DISABLE)
+  if (m_features.packet_support (which_packet) == PACKET_DISABLE)
     return TARGET_XFER_E_IO;
 
   /* Check whether we've cached an end-of-object packet that matches
@@ -11190,8 +11360,9 @@ remote_target::remote_read_qxfer (const char *object_name,
     return TARGET_XFER_E_IO;
 
   rs->buf[0] = '\0';
-  packet_len = getpkt_sane (&rs->buf, 0);
-  if (packet_len < 0 || packet_ok (rs->buf, packet) != PACKET_OK)
+  packet_len = getpkt (&rs->buf);
+  if (packet_len < 0
+      || m_features.packet_ok (rs->buf, which_packet) != PACKET_OK)
     return TARGET_XFER_E_IO;
 
   if (rs->buf[0] != 'l' && rs->buf[0] != 'm')
@@ -11236,7 +11407,8 @@ remote_target::xfer_partial (enum target_object object,
   int i;
   char *p2;
   char query_type;
-  int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
+  int unit_size
+    = gdbarch_addressable_memory_unit_size (current_inferior ()->arch ());
 
   set_remote_traceframe ();
   set_general_thread (inferior_ptid);
@@ -11265,13 +11437,10 @@ remote_target::xfer_partial (enum target_object object,
     {
       if (readbuf)
        return remote_read_qxfer ("siginfo", annex, readbuf, offset, len,
-                                 xfered_len, &remote_protocol_packets
-                                 [PACKET_qXfer_siginfo_read]);
+                                 xfered_len, PACKET_qXfer_siginfo_read);
       else
-       return remote_write_qxfer ("siginfo", annex,
-                                  writebuf, offset, len, xfered_len,
-                                  &remote_protocol_packets
-                                  [PACKET_qXfer_siginfo_write]);
+       return remote_write_qxfer ("siginfo", annex, writebuf, offset, len,
+                                  xfered_len, PACKET_qXfer_siginfo_write);
     }
 
   if (object == TARGET_OBJECT_STATIC_TRACE_DATA)
@@ -11279,8 +11448,7 @@ remote_target::xfer_partial (enum target_object object,
       if (readbuf)
        return remote_read_qxfer ("statictrace", annex,
                                  readbuf, offset, len, xfered_len,
-                                 &remote_protocol_packets
-                                 [PACKET_qXfer_statictrace_read]);
+                                 PACKET_qXfer_statictrace_read);
       else
        return TARGET_XFER_E_IO;
     }
@@ -11309,74 +11477,71 @@ remote_target::xfer_partial (enum target_object object,
 
     case TARGET_OBJECT_AUXV:
       gdb_assert (annex == NULL);
-      return remote_read_qxfer ("auxv", annex, readbuf, offset, len,
-                               xfered_len,
-                               &remote_protocol_packets[PACKET_qXfer_auxv]);
+      return remote_read_qxfer
+       ("auxv", annex, readbuf, offset, len, xfered_len, PACKET_qXfer_auxv);
 
     case TARGET_OBJECT_AVAILABLE_FEATURES:
       return remote_read_qxfer
        ("features", annex, readbuf, offset, len, xfered_len,
-        &remote_protocol_packets[PACKET_qXfer_features]);
+        PACKET_qXfer_features);
 
     case TARGET_OBJECT_LIBRARIES:
       return remote_read_qxfer
        ("libraries", annex, readbuf, offset, len, xfered_len,
-        &remote_protocol_packets[PACKET_qXfer_libraries]);
+        PACKET_qXfer_libraries);
 
     case TARGET_OBJECT_LIBRARIES_SVR4:
       return remote_read_qxfer
        ("libraries-svr4", annex, readbuf, offset, len, xfered_len,
-        &remote_protocol_packets[PACKET_qXfer_libraries_svr4]);
+        PACKET_qXfer_libraries_svr4);
 
     case TARGET_OBJECT_MEMORY_MAP:
       gdb_assert (annex == NULL);
-      return remote_read_qxfer ("memory-map", annex, readbuf, offset, len,
-                                xfered_len,
-                               &remote_protocol_packets[PACKET_qXfer_memory_map]);
+      return remote_read_qxfer
+       ("memory-map", annex, readbuf, offset, len, xfered_len,
+        PACKET_qXfer_memory_map);
 
     case TARGET_OBJECT_OSDATA:
       /* Should only get here if we're connected.  */
       gdb_assert (rs->remote_desc);
       return remote_read_qxfer
        ("osdata", annex, readbuf, offset, len, xfered_len,
-       &remote_protocol_packets[PACKET_qXfer_osdata]);
+        PACKET_qXfer_osdata);
 
     case TARGET_OBJECT_THREADS:
       gdb_assert (annex == NULL);
-      return remote_read_qxfer ("threads", annex, readbuf, offset, len,
-                               xfered_len,
-                               &remote_protocol_packets[PACKET_qXfer_threads]);
+      return remote_read_qxfer
+       ("threads", annex, readbuf, offset, len, xfered_len,
+        PACKET_qXfer_threads);
 
     case TARGET_OBJECT_TRACEFRAME_INFO:
       gdb_assert (annex == NULL);
       return remote_read_qxfer
        ("traceframe-info", annex, readbuf, offset, len, xfered_len,
-        &remote_protocol_packets[PACKET_qXfer_traceframe_info]);
+        PACKET_qXfer_traceframe_info);
 
     case TARGET_OBJECT_FDPIC:
-      return remote_read_qxfer ("fdpic", annex, readbuf, offset, len,
-                               xfered_len,
-                               &remote_protocol_packets[PACKET_qXfer_fdpic]);
+      return remote_read_qxfer
+       ("fdpic", annex, readbuf, offset, len, xfered_len, PACKET_qXfer_fdpic);
 
     case TARGET_OBJECT_OPENVMS_UIB:
-      return remote_read_qxfer ("uib", annex, readbuf, offset, len,
-                               xfered_len,
-                               &remote_protocol_packets[PACKET_qXfer_uib]);
+      return remote_read_qxfer
+       ("uib", annex, readbuf, offset, len, xfered_len, PACKET_qXfer_uib);
 
     case TARGET_OBJECT_BTRACE:
-      return remote_read_qxfer ("btrace", annex, readbuf, offset, len,
-                               xfered_len,
-       &remote_protocol_packets[PACKET_qXfer_btrace]);
+      return remote_read_qxfer
+       ("btrace", annex, readbuf, offset, len, xfered_len,
+        PACKET_qXfer_btrace);
 
     case TARGET_OBJECT_BTRACE_CONF:
-      return remote_read_qxfer ("btrace-conf", annex, readbuf, offset,
-                               len, xfered_len,
-       &remote_protocol_packets[PACKET_qXfer_btrace_conf]);
+      return remote_read_qxfer
+       ("btrace-conf", annex, readbuf, offset, len, xfered_len,
+        PACKET_qXfer_btrace_conf);
 
     case TARGET_OBJECT_EXEC_FILE:
-      return remote_read_qxfer ("exec-file", annex, readbuf, offset,
-                               len, xfered_len,
-       &remote_protocol_packets[PACKET_qXfer_exec_file]);
+      return remote_read_qxfer
+       ("exec-file", annex, readbuf, offset, len, xfered_len,
+        PACKET_qXfer_exec_file);
 
     default:
       return TARGET_XFER_E_IO;
@@ -11419,7 +11584,7 @@ remote_target::xfer_partial (enum target_object object,
   if (i < 0)
     return TARGET_XFER_E_IO;
 
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   strcpy ((char *) readbuf, rs->buf.data ());
 
   *xfered_len = strlen ((char *) readbuf);
@@ -11439,11 +11604,10 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
                              const gdb_byte *pattern, ULONGEST pattern_len,
                              CORE_ADDR *found_addrp)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+  int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
   struct remote_state *rs = get_remote_state ();
   int max_size = get_memory_write_packet_size ();
-  struct packet_config *packet =
-    &remote_protocol_packets[PACKET_qSearch_memory];
+
   /* Number of packet bytes used to encode the pattern;
      this could be more than PATTERN_LEN due to escape characters.  */
   int escaped_pattern_len;
@@ -11453,16 +11617,15 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
   int found;
   ULONGEST found_addr;
 
-  auto read_memory = [=] (CORE_ADDR addr, gdb_byte *result, size_t len)
+  auto read_memory = [this] (CORE_ADDR addr, gdb_byte *result, size_t len)
     {
       return (target_read (this, TARGET_OBJECT_MEMORY, NULL, result, addr, len)
              == len);
     };
 
   /* Don't go to the target if we don't have to.  This is done before
-     checking packet_config_support to avoid the possibility that a
-     success for this edge case means the facility works in
-     general.  */
+     checking packet_support to avoid the possibility that a success for this
+     edge case means the facility works in general.  */
   if (pattern_len > search_space_len)
     return 0;
   if (pattern_len == 0)
@@ -11474,7 +11637,7 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
   /* If we already know the packet isn't supported, fall back to the simple
      way of searching memory.  */
 
-  if (packet_config_support (packet) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qSearch_memory) == PACKET_DISABLE)
     {
       /* Target doesn't provided special support, fall back and use the
         standard support (copy memory and do the search here).  */
@@ -11486,7 +11649,7 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
   set_general_process ();
 
   /* Insert header.  */
-  i = snprintf (rs->buf.data (), max_size, 
+  i = snprintf (rs->buf.data (), max_size,
                "qSearch:memory:%s;%s;",
                phex_nz (start_addr, addr_size),
                phex_nz (search_space_len, sizeof (search_space_len)));
@@ -11503,12 +11666,12 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
     error (_("Pattern is too large to transmit to remote target."));
 
   if (putpkt_binary (rs->buf.data (), i + escaped_pattern_len) < 0
-      || getpkt_sane (&rs->buf, 0) < 0
-      || packet_ok (rs->buf, packet) != PACKET_OK)
+      || getpkt (&rs->buf) < 0
+      || m_features.packet_ok (rs->buf, PACKET_qSearch_memory) != PACKET_OK)
     {
       /* The request may not have worked because the command is not
         supported.  If so, fall back to the simple way.  */
-      if (packet_config_support (packet) == PACKET_DISABLE)
+      if (m_features.packet_support (PACKET_qSearch_memory) == PACKET_DISABLE)
        {
          return simple_search_memory (read_memory, start_addr, search_space_len,
                                       pattern, pattern_len, found_addrp);
@@ -11567,8 +11730,8 @@ remote_target::rcmd (const char *command, struct ui_file *outbuf)
       /* XXX - see also remote_get_noisy_reply().  */
       QUIT;                    /* Allow user to bail out with ^C.  */
       rs->buf[0] = '\0';
-      if (getpkt_sane (&rs->buf, 0) == -1)
-       { 
+      if (getpkt (&rs->buf) == -1)
+       {
          /* Timeout.  Continue to (try to) read responses.
             This is better than stopping with an error, assuming the stub
             is still executing the (long) monitor command.
@@ -11587,7 +11750,7 @@ remote_target::rcmd (const char *command, struct ui_file *outbuf)
       if (strcmp (buf, "OK") == 0)
        break;
       if (strlen (buf) == 3 && buf[0] == 'E'
-         && isdigit (buf[1]) && isdigit (buf[2]))
+         && isxdigit (buf[1]) && isxdigit (buf[2]))
        {
          error (_("Protocol error with Rcmd"));
        }
@@ -11595,7 +11758,7 @@ remote_target::rcmd (const char *command, struct ui_file *outbuf)
        {
          char c = (fromhex (p[0]) << 4) + fromhex (p[1]);
 
-         fputc_unfiltered (c, outbuf);
+         gdb_putc (c, outbuf);
        }
       break;
     }
@@ -11624,18 +11787,18 @@ struct cli_packet_command_callbacks : public send_remote_packet_callbacks
 
   void sending (gdb::array_view<const char> &buf) override
   {
-    puts_filtered ("sending: ");
+    gdb_puts ("sending: ");
     print_packet (buf);
-    puts_filtered ("\n");
+    gdb_puts ("\n");
   }
 
   /* Called with BUF, the reply from the remote target.  */
 
   void received (gdb::array_view<const char> &buf) override
   {
-    puts_filtered ("received: \"");
+    gdb_puts ("received: \"");
     print_packet (buf);
-    puts_filtered ("\"\n");
+    gdb_puts ("\"\n");
   }
 
 private:
@@ -11652,12 +11815,12 @@ private:
       {
        gdb_byte c = buf[i];
        if (isprint (c))
-         fputc_unfiltered (c, &stb);
+         gdb_putc (c, &stb);
        else
-         fprintf_unfiltered (&stb, "\\x%02x", (unsigned char) c);
+         gdb_printf (&stb, "\\x%02x", (unsigned char) c);
       }
 
-    puts_filtered (stb.string ().c_str ());
+    gdb_puts (stb.string ().c_str ());
   }
 };
 
@@ -11678,7 +11841,7 @@ send_remote_packet (gdb::array_view<const char> &buf,
 
   remote->putpkt_binary (buf.data (), buf.size ());
   remote_state *rs = remote->get_remote_state ();
-  int bytes = remote->getpkt_sane (&rs->buf, 0);
+  int bytes = remote->getpkt (&rs->buf);
 
   if (bytes < 0)
     error (_("error while fetching packet from remote target"));
@@ -11726,7 +11889,7 @@ threadset_test_cmd (const char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
 
-  printf_filtered (_("Remote threadset test\n"));
+  gdb_printf (_("Remote threadset test\n"));
   set_general_thread (sample_thread);
 }
 
@@ -11739,9 +11902,9 @@ threadalive_test (const char *cmd, int tty)
   ptid_t ptid = ptid_t (pid, sample_thread, 0);
 
   if (remote_thread_alive (ptid))
-    printf_filtered ("PASS: Thread alive test\n");
+    gdb_printf ("PASS: Thread alive test\n");
   else
-    printf_filtered ("FAIL: Thread alive test\n");
+    gdb_printf ("FAIL: Thread alive test\n");
 }
 
 void output_threadid (char *title, threadref *ref);
@@ -11753,7 +11916,7 @@ output_threadid (char *title, threadref *ref)
 
   pack_threadid (&hexid[0], ref);      /* Convert thread id into hex.  */
   hexid[16] = 0;
-  printf_filtered ("%s  %s\n", title, (&hexid[0]));
+  gdb_printf ("%s  %s\n", title, (&hexid[0]));
 }
 
 static void
@@ -11764,10 +11927,10 @@ threadlist_test_cmd (const char *cmd, int tty)
   int done, result_count;
   threadref threadlist[3];
 
-  printf_filtered ("Remote Threadlist test\n");
+  gdb_printf ("Remote Threadlist test\n");
   if (!remote_get_threadlist (startflag, &nextthread, 3, &done,
                              &result_count, &threadlist[0]))
-    printf_filtered ("FAIL: threadlist test\n");
+    gdb_printf ("FAIL: threadlist test\n");
   else
     {
       threadref *scan = threadlist;
@@ -11782,9 +11945,9 @@ void
 display_thread_info (struct gdb_ext_thread_info *info)
 {
   output_threadid ("Threadid: ", &info->threadid);
-  printf_filtered ("Name: %s\n ", info->shortname);
-  printf_filtered ("State: %s\n", info->display);
-  printf_filtered ("other: %s\n\n", info->more_display);
+  gdb_printf ("Name: %s\n ", info->shortname);
+  gdb_printf ("State: %s\n", info->display);
+  gdb_printf ("other: %s\n\n", info->more_display);
 }
 
 int
@@ -11809,9 +11972,9 @@ threadinfo_test_cmd (const char *cmd, int tty)
   int set;
 
   int_to_threadref (&thread, athread);
-  printf_filtered ("Remote Threadinfo test\n");
+  gdb_printf ("Remote Threadinfo test\n");
   if (!get_and_display_threadinfo (&thread))
-    printf_filtered ("FAIL cannot get thread info\n");
+    gdb_printf ("FAIL cannot get thread info\n");
 }
 
 static int
@@ -11824,7 +11987,7 @@ thread_display_step (threadref *ref, void *context)
 static void
 threadlist_update_test_cmd (const char *cmd, int tty)
 {
-  printf_filtered ("Remote Threadlist update test\n");
+  gdb_printf ("Remote Threadlist update test\n");
   remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
 }
 
@@ -11851,8 +12014,6 @@ init_remote_threadtests (void)
 std::string
 remote_target::pid_to_str (ptid_t ptid)
 {
-  struct remote_state *rs = get_remote_state ();
-
   if (ptid == null_ptid)
     return normal_pid_to_str (ptid);
   else if (ptid.is_pid ())
@@ -11868,7 +12029,7 @@ remote_target::pid_to_str (ptid_t ptid)
         connecting with extended-remote and the stub already being
         attached to a process, and reporting yes to qAttached, hence
         no smart special casing here.  */
-      if (!remote_multi_process_p (rs))
+      if (!m_features.remote_multi_process_p ())
        return "Remote target";
 
       return normal_pid_to_str (ptid);
@@ -11877,7 +12038,7 @@ remote_target::pid_to_str (ptid_t ptid)
     {
       if (magic_null_ptid == ptid)
        return "Thread <main>";
-      else if (remote_multi_process_p (rs))
+      else if (m_features.remote_multi_process_p ())
        if (ptid.lwp () == 0)
          return normal_pid_to_str (ptid);
        else
@@ -11895,7 +12056,7 @@ CORE_ADDR
 remote_target::get_thread_local_address (ptid_t ptid, CORE_ADDR lm,
                                         CORE_ADDR offset)
 {
-  if (packet_support (PACKET_qGetTLSAddr) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qGetTLSAddr) != PACKET_DISABLE)
     {
       struct remote_state *rs = get_remote_state ();
       char *p = rs->buf.data ();
@@ -11912,9 +12073,8 @@ remote_target::get_thread_local_address (ptid_t ptid, CORE_ADDR lm,
       *p++ = '\0';
 
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
-      result = packet_ok (rs->buf,
-                         &remote_protocol_packets[PACKET_qGetTLSAddr]);
+      getpkt (&rs->buf);
+      result = m_features.packet_ok (rs->buf, PACKET_qGetTLSAddr);
       if (result == PACKET_OK)
        {
          ULONGEST addr;
@@ -11942,7 +12102,7 @@ remote_target::get_thread_local_address (ptid_t ptid, CORE_ADDR lm,
 bool
 remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 {
-  if (packet_support (PACKET_qGetTIBAddr) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qGetTIBAddr) != PACKET_DISABLE)
     {
       struct remote_state *rs = get_remote_state ();
       char *p = rs->buf.data ();
@@ -11955,9 +12115,8 @@ remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
       *p++ = '\0';
 
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
-      result = packet_ok (rs->buf,
-                         &remote_protocol_packets[PACKET_qGetTIBAddr]);
+      getpkt (&rs->buf);
+      result = m_features.packet_ok (rs->buf, PACKET_qGetTIBAddr);
       if (result == PACKET_OK)
        {
          ULONGEST val;
@@ -11995,33 +12154,35 @@ struct remote_g_packet_guess
   const struct target_desc *tdesc;
 };
 
-struct remote_g_packet_data : public allocate_on_obstack
+struct remote_g_packet_data
 {
   std::vector<remote_g_packet_guess> guesses;
 };
 
-static struct gdbarch_data *remote_g_packet_data_handle;
+static const registry<gdbarch>::key<struct remote_g_packet_data>
+     remote_g_packet_data_handle;
 
-static void *
-remote_g_packet_data_init (struct obstack *obstack)
+static struct remote_g_packet_data *
+get_g_packet_data (struct gdbarch *gdbarch)
 {
-  return new (obstack) remote_g_packet_data;
+  struct remote_g_packet_data *data
+    = remote_g_packet_data_handle.get (gdbarch);
+  if (data == nullptr)
+    data = remote_g_packet_data_handle.emplace (gdbarch);
+  return data;
 }
 
 void
 register_remote_g_packet_guess (struct gdbarch *gdbarch, int bytes,
                                const struct target_desc *tdesc)
 {
-  struct remote_g_packet_data *data
-    = ((struct remote_g_packet_data *)
-       gdbarch_data (gdbarch, remote_g_packet_data_handle));
+  struct remote_g_packet_data *data = get_g_packet_data (gdbarch);
 
   gdb_assert (tdesc != NULL);
 
   for (const remote_g_packet_guess &guess : data->guesses)
     if (guess.bytes == bytes)
-      internal_error (__FILE__, __LINE__,
-                     _("Duplicate g packet description added for size %d"),
+      internal_error (_("Duplicate g packet description added for size %d"),
                      bytes);
 
   data->guesses.emplace_back (bytes, tdesc);
@@ -12033,9 +12194,7 @@ register_remote_g_packet_guess (struct gdbarch *gdbarch, int bytes,
 static bool
 remote_read_description_p (struct target_ops *target)
 {
-  struct remote_g_packet_data *data
-    = ((struct remote_g_packet_data *)
-       gdbarch_data (target_gdbarch (), remote_g_packet_data_handle));
+  remote_g_packet_data *data = get_g_packet_data (current_inferior ()->arch ());
 
   return !data->guesses.empty ();
 }
@@ -12043,9 +12202,7 @@ remote_read_description_p (struct target_ops *target)
 const struct target_desc *
 remote_target::read_description ()
 {
-  struct remote_g_packet_data *data
-    = ((struct remote_g_packet_data *)
-       gdbarch_data (target_gdbarch (), remote_g_packet_data_handle));
+  remote_g_packet_data *data = get_g_packet_data (current_inferior ()->arch ());
 
   /* Do not try this during initial connection, when we do not know
      whether there is a running but stopped thread.  */
@@ -12137,7 +12294,7 @@ remote_buffer_add_int (char **buffer, int *left, ULONGEST value)
 }
 
 /* Parse an I/O result packet from BUFFER.  Set RETCODE to the return
-   value, *REMOTE_ERRNO to the remote error number or zero if none
+   value, *REMOTE_ERRNO to the remote error number or FILEIO_SUCCESS if none
    was included, and *ATTACHMENT to point to the start of the annex
    if any.  The length of the packet isn't needed here; there may
    be NUL bytes in BUFFER, but they will be after *ATTACHMENT.
@@ -12147,11 +12304,11 @@ remote_buffer_add_int (char **buffer, int *left, ULONGEST value)
 
 static int
 remote_hostio_parse_result (const char *buffer, int *retcode,
-                           int *remote_errno, const char **attachment)
+                           fileio_error *remote_errno, const char **attachment)
 {
   char *p, *p2;
 
-  *remote_errno = 0;
+  *remote_errno = FILEIO_SUCCESS;
   *attachment = NULL;
 
   if (buffer[0] != 'F')
@@ -12166,7 +12323,7 @@ remote_hostio_parse_result (const char *buffer, int *retcode,
   if (*p == ',')
     {
       errno = 0;
-      *remote_errno = strtol (p + 1, &p2, 16);
+      *remote_errno = (fileio_error) strtol (p + 1, &p2, 16);
       if (errno != 0 || p + 1 == p2)
        return -1;
       p = p2;
@@ -12203,21 +12360,21 @@ remote_hostio_parse_result (const char *buffer, int *retcode,
 
 int
 remote_target::remote_hostio_send_command (int command_bytes, int which_packet,
-                                          int *remote_errno, const char **attachment,
+                                          fileio_error *remote_errno, const char **attachment,
                                           int *attachment_len)
 {
   struct remote_state *rs = get_remote_state ();
   int ret, bytes_read;
   const char *attachment_tmp;
 
-  if (packet_support (which_packet) == PACKET_DISABLE)
+  if (m_features.packet_support (which_packet) == PACKET_DISABLE)
     {
       *remote_errno = FILEIO_ENOSYS;
       return -1;
     }
 
   putpkt_binary (rs->buf.data (), command_bytes);
-  bytes_read = getpkt_sane (&rs->buf, 0);
+  bytes_read = getpkt (&rs->buf);
 
   /* If it timed out, something is wrong.  Don't try to parse the
      buffer.  */
@@ -12227,7 +12384,7 @@ remote_target::remote_hostio_send_command (int command_bytes, int which_packet,
       return -1;
     }
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[which_packet]))
+  switch (m_features.packet_ok (rs->buf, which_packet))
     {
     case PACKET_ERROR:
       *remote_errno = FILEIO_EINVAL;
@@ -12288,7 +12445,7 @@ readahead_cache::invalidate_fd (int fd)
 
 int
 remote_target::remote_hostio_set_filesystem (struct inferior *inf,
-                                            int *remote_errno)
+                                            fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   int required_pid = (inf == NULL || inf->fake_pid_p) ? 0 : inf->pid;
@@ -12297,7 +12454,7 @@ remote_target::remote_hostio_set_filesystem (struct inferior *inf,
   char arg[9];
   int ret;
 
-  if (packet_support (PACKET_vFile_setfs) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_vFile_setfs) == PACKET_DISABLE)
     return 0;
 
   if (rs->fs_pid != -1 && required_pid == rs->fs_pid)
@@ -12311,7 +12468,7 @@ remote_target::remote_hostio_set_filesystem (struct inferior *inf,
   ret = remote_hostio_send_command (p - rs->buf.data (), PACKET_vFile_setfs,
                                    remote_errno, NULL, NULL);
 
-  if (packet_support (PACKET_vFile_setfs) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_vFile_setfs) == PACKET_DISABLE)
     return 0;
 
   if (ret == 0)
@@ -12325,7 +12482,7 @@ remote_target::remote_hostio_set_filesystem (struct inferior *inf,
 int
 remote_target::remote_hostio_open (inferior *inf, const char *filename,
                                   int flags, int mode, int warn_if_slow,
-                                  int *remote_errno)
+                                  fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12335,8 +12492,8 @@ remote_target::remote_hostio_open (inferior *inf, const char *filename,
     {
       static int warning_issued = 0;
 
-      printf_unfiltered (_("Reading %s from remote target...\n"),
-                        filename);
+      gdb_printf (_("Reading %s from remote target...\n"),
+                 filename);
 
       if (!warning_issued)
        {
@@ -12368,7 +12525,7 @@ remote_target::remote_hostio_open (inferior *inf, const char *filename,
 int
 remote_target::fileio_open (struct inferior *inf, const char *filename,
                            int flags, int mode, int warn_if_slow,
-                           int *remote_errno)
+                           fileio_error *remote_errno)
 {
   return remote_hostio_open (inf, filename, flags, mode, warn_if_slow,
                             remote_errno);
@@ -12378,7 +12535,7 @@ remote_target::fileio_open (struct inferior *inf, const char *filename,
 
 int
 remote_target::remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                                    ULONGEST offset, int *remote_errno)
+                                    ULONGEST offset, fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12405,7 +12562,7 @@ remote_target::remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len,
 
 int
 remote_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                             ULONGEST offset, int *remote_errno)
+                             ULONGEST offset, fileio_error *remote_errno)
 {
   return remote_hostio_pwrite (fd, write_buf, len, offset, remote_errno);
 }
@@ -12415,7 +12572,7 @@ remote_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
 
 int
 remote_target::remote_hostio_pread_vFile (int fd, gdb_byte *read_buf, int len,
-                                         ULONGEST offset, int *remote_errno)
+                                         ULONGEST offset, fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12457,14 +12614,14 @@ readahead_cache::pread (int fd, gdb_byte *read_buf, size_t len,
 {
   if (this->fd == fd
       && this->offset <= offset
-      && offset < this->offset + this->bufsize)
+      && offset < this->offset + this->buf.size ())
     {
-      ULONGEST max = this->offset + this->bufsize;
+      ULONGEST max = this->offset + this->buf.size ();
 
       if (offset + len > max)
        len = max - offset;
 
-      memcpy (read_buf, this->buf + offset - this->offset, len);
+      memcpy (read_buf, &this->buf[offset - this->offset], len);
       return len;
     }
 
@@ -12475,7 +12632,7 @@ readahead_cache::pread (int fd, gdb_byte *read_buf, size_t len,
 
 int
 remote_target::remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
-                                   ULONGEST offset, int *remote_errno)
+                                   ULONGEST offset, fileio_error *remote_errno)
 {
   int ret;
   struct remote_state *rs = get_remote_state ();
@@ -12498,10 +12655,10 @@ remote_target::remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
 
   cache->fd = fd;
   cache->offset = offset;
-  cache->bufsize = get_remote_packet_size ();
-  cache->buf = (gdb_byte *) xrealloc (cache->buf, cache->bufsize);
+  cache->buf.resize (get_remote_packet_size ());
 
-  ret = remote_hostio_pread_vFile (cache->fd, cache->buf, cache->bufsize,
+  ret = remote_hostio_pread_vFile (cache->fd, &cache->buf[0],
+                                  cache->buf.size (),
                                   cache->offset, remote_errno);
   if (ret <= 0)
     {
@@ -12509,13 +12666,13 @@ remote_target::remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
       return ret;
     }
 
-  cache->bufsize = ret;
+  cache->buf.resize (ret);
   return cache->pread (fd, read_buf, len, offset);
 }
 
 int
 remote_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
-                            ULONGEST offset, int *remote_errno)
+                            ULONGEST offset, fileio_error *remote_errno)
 {
   return remote_hostio_pread (fd, read_buf, len, offset, remote_errno);
 }
@@ -12523,7 +12680,7 @@ remote_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
 /* Implementation of to_fileio_close.  */
 
 int
-remote_target::remote_hostio_close (int fd, int *remote_errno)
+remote_target::remote_hostio_close (int fd, fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12540,7 +12697,7 @@ remote_target::remote_hostio_close (int fd, int *remote_errno)
 }
 
 int
-remote_target::fileio_close (int fd, int *remote_errno)
+remote_target::fileio_close (int fd, fileio_error *remote_errno)
 {
   return remote_hostio_close (fd, remote_errno);
 }
@@ -12549,7 +12706,7 @@ remote_target::fileio_close (int fd, int *remote_errno)
 
 int
 remote_target::remote_hostio_unlink (inferior *inf, const char *filename,
-                                    int *remote_errno)
+                                    fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12569,7 +12726,7 @@ remote_target::remote_hostio_unlink (inferior *inf, const char *filename,
 
 int
 remote_target::fileio_unlink (struct inferior *inf, const char *filename,
-                             int *remote_errno)
+                             fileio_error *remote_errno)
 {
   return remote_hostio_unlink (inf, filename, remote_errno);
 }
@@ -12578,7 +12735,7 @@ remote_target::fileio_unlink (struct inferior *inf, const char *filename,
 
 gdb::optional<std::string>
 remote_target::fileio_readlink (struct inferior *inf, const char *filename,
-                               int *remote_errno)
+                               fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12615,7 +12772,7 @@ remote_target::fileio_readlink (struct inferior *inf, const char *filename,
 /* Implementation of to_fileio_fstat.  */
 
 int
-remote_target::fileio_fstat (int fd, struct stat *st, int *remote_errno)
+remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf.data ();
@@ -12683,11 +12840,12 @@ remote_target::filesystem_is_local ()
      does not support vFile:open.  */
   if (gdb_sysroot == TARGET_SYSROOT_PREFIX)
     {
-      enum packet_support ps = packet_support (PACKET_vFile_open);
+      packet_support ps = m_features.packet_support (PACKET_vFile_open);
 
       if (ps == PACKET_SUPPORT_UNKNOWN)
        {
-         int fd, remote_errno;
+         int fd;
+         fileio_error remote_errno;
 
          /* Try opening a file to probe support.  The supplied
             filename is irrelevant, we only care about whether
@@ -12699,7 +12857,7 @@ remote_target::filesystem_is_local ()
          if (fd >= 0)
            remote_hostio_close (fd, &remote_errno);
 
-         ps = packet_support (PACKET_vFile_open);
+         ps = m_features.packet_support (PACKET_vFile_open);
        }
 
       if (ps == PACKET_DISABLE)
@@ -12721,61 +12879,10 @@ remote_target::filesystem_is_local ()
   return false;
 }
 
-static int
-remote_fileio_errno_to_host (int errnum)
-{
-  switch (errnum)
-    {
-      case FILEIO_EPERM:
-       return EPERM;
-      case FILEIO_ENOENT:
-       return ENOENT;
-      case FILEIO_EINTR:
-       return EINTR;
-      case FILEIO_EIO:
-       return EIO;
-      case FILEIO_EBADF:
-       return EBADF;
-      case FILEIO_EACCES:
-       return EACCES;
-      case FILEIO_EFAULT:
-       return EFAULT;
-      case FILEIO_EBUSY:
-       return EBUSY;
-      case FILEIO_EEXIST:
-       return EEXIST;
-      case FILEIO_ENODEV:
-       return ENODEV;
-      case FILEIO_ENOTDIR:
-       return ENOTDIR;
-      case FILEIO_EISDIR:
-       return EISDIR;
-      case FILEIO_EINVAL:
-       return EINVAL;
-      case FILEIO_ENFILE:
-       return ENFILE;
-      case FILEIO_EMFILE:
-       return EMFILE;
-      case FILEIO_EFBIG:
-       return EFBIG;
-      case FILEIO_ENOSPC:
-       return ENOSPC;
-      case FILEIO_ESPIPE:
-       return ESPIPE;
-      case FILEIO_EROFS:
-       return EROFS;
-      case FILEIO_ENOSYS:
-       return ENOSYS;
-      case FILEIO_ENAMETOOLONG:
-       return ENAMETOOLONG;
-    }
-  return -1;
-}
-
 static char *
-remote_hostio_error (int errnum)
+remote_hostio_error (fileio_error errnum)
 {
-  int host_error = remote_fileio_errno_to_host (errnum);
+  int host_error = fileio_error_to_host (errnum);
 
   if (host_error == -1)
     error (_("Unknown remote I/O error %d"), errnum);
@@ -12799,7 +12906,7 @@ public:
       {
        try
          {
-           int remote_errno;
+           fileio_error remote_errno;
            m_remote->remote_hostio_close (m_fd, &remote_errno);
          }
        catch (...)
@@ -12850,7 +12957,8 @@ void
 remote_target::remote_file_put (const char *local_file, const char *remote_file,
                                int from_tty)
 {
-  int retcode, remote_errno, bytes, io_size;
+  int retcode, bytes, io_size;
+  fileio_error remote_errno;
   int bytes_in_buffer;
   int saw_eof;
   ULONGEST offset;
@@ -12924,7 +13032,7 @@ remote_target::remote_file_put (const char *local_file, const char *remote_file,
     remote_hostio_error (remote_errno);
 
   if (from_tty)
-    printf_filtered (_("Successfully sent file \"%s\".\n"), local_file);
+    gdb_printf (_("Successfully sent file \"%s\".\n"), local_file);
 }
 
 void
@@ -12942,7 +13050,8 @@ void
 remote_target::remote_file_get (const char *remote_file, const char *local_file,
                                int from_tty)
 {
-  int remote_errno, bytes, io_size;
+  fileio_error remote_errno;
+  int bytes, io_size;
   ULONGEST offset;
 
   scoped_remote_fd fd
@@ -12983,7 +13092,7 @@ remote_target::remote_file_get (const char *remote_file, const char *local_file,
     remote_hostio_error (remote_errno);
 
   if (from_tty)
-    printf_filtered (_("Successfully fetched file \"%s\".\n"), remote_file);
+    gdb_printf (_("Successfully fetched file \"%s\".\n"), remote_file);
 }
 
 void
@@ -13000,14 +13109,15 @@ remote_file_delete (const char *remote_file, int from_tty)
 void
 remote_target::remote_file_delete (const char *remote_file, int from_tty)
 {
-  int retcode, remote_errno;
+  int retcode;
+  fileio_error remote_errno;
 
   retcode = remote_hostio_unlink (NULL, remote_file, &remote_errno);
   if (retcode == -1)
     remote_hostio_error (remote_errno);
 
   if (from_tty)
-    printf_filtered (_("Successfully deleted file \"%s\".\n"), remote_file);
+    gdb_printf (_("Successfully deleted file \"%s\".\n"), remote_file);
 }
 
 static void
@@ -13052,8 +13162,8 @@ remote_delete_command (const char *args, int from_tty)
 bool
 remote_target::can_execute_reverse ()
 {
-  if (packet_support (PACKET_bs) == PACKET_ENABLE
-      || packet_support (PACKET_bc) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_bs) == PACKET_ENABLE
+      || m_features.packet_support (PACKET_bc) == PACKET_ENABLE)
     return true;
   else
     return false;
@@ -13075,58 +13185,58 @@ remote_target::supports_disable_randomization ()
 bool
 remote_target::supports_multi_process ()
 {
-  struct remote_state *rs = get_remote_state ();
-
-  return remote_multi_process_p (rs);
+  return m_features.remote_multi_process_p ();
 }
 
-static int
-remote_supports_cond_tracepoints ()
+int
+remote_target::remote_supports_cond_tracepoints ()
 {
-  return packet_support (PACKET_ConditionalTracepoints) == PACKET_ENABLE;
+  return (m_features.packet_support (PACKET_ConditionalTracepoints)
+         == PACKET_ENABLE);
 }
 
 bool
 remote_target::supports_evaluation_of_breakpoint_conditions ()
 {
-  return packet_support (PACKET_ConditionalBreakpoints) == PACKET_ENABLE;
+  return (m_features.packet_support (PACKET_ConditionalBreakpoints)
+         == PACKET_ENABLE);
 }
 
-static int
-remote_supports_fast_tracepoints ()
+int
+remote_target::remote_supports_fast_tracepoints ()
 {
-  return packet_support (PACKET_FastTracepoints) == PACKET_ENABLE;
+  return m_features.packet_support (PACKET_FastTracepoints) == PACKET_ENABLE;
 }
 
-static int
-remote_supports_static_tracepoints ()
+int
+remote_target::remote_supports_static_tracepoints ()
 {
-  return packet_support (PACKET_StaticTracepoints) == PACKET_ENABLE;
+  return m_features.packet_support (PACKET_StaticTracepoints) == PACKET_ENABLE;
 }
 
-static int
-remote_supports_install_in_trace ()
+int
+remote_target::remote_supports_install_in_trace ()
 {
-  return packet_support (PACKET_InstallInTrace) == PACKET_ENABLE;
+  return m_features.packet_support (PACKET_InstallInTrace) == PACKET_ENABLE;
 }
 
 bool
 remote_target::supports_enable_disable_tracepoint ()
 {
-  return (packet_support (PACKET_EnableDisableTracepoints_feature)
+  return (m_features.packet_support (PACKET_EnableDisableTracepoints_feature)
          == PACKET_ENABLE);
 }
 
 bool
 remote_target::supports_string_tracing ()
 {
-  return packet_support (PACKET_tracenz_feature) == PACKET_ENABLE;
+  return m_features.packet_support (PACKET_tracenz_feature) == PACKET_ENABLE;
 }
 
 bool
 remote_target::can_run_breakpoint_commands ()
 {
-  return packet_support (PACKET_BreakpointCommands) == PACKET_ENABLE;
+  return m_features.packet_support (PACKET_BreakpointCommands) == PACKET_ENABLE;
 }
 
 void
@@ -13189,7 +13299,7 @@ remote_target::download_tracepoint (struct bp_location *loc)
   std::vector<std::string> stepping_actions;
   char *pkt;
   struct breakpoint *b = loc->owner;
-  struct tracepoint *t = (struct tracepoint *) b;
+  tracepoint *t = gdb::checked_static_cast<tracepoint *> (b);
   struct remote_state *rs = get_remote_state ();
   int ret;
   const char *err_msg = _("Tracepoint packet too large for target.");
@@ -13235,9 +13345,7 @@ remote_target::download_tracepoint (struct bp_location *loc)
          else
            /* If it passed validation at definition but fails now,
               something is very wrong.  */
-           internal_error (__FILE__, __LINE__,
-                           _("Fast tracepoint not "
-                             "valid during download"));
+           internal_error (_("Fast tracepoint not valid during download"));
        }
       else
        /* Fast tracepoints are functionally identical to regular
@@ -13246,7 +13354,8 @@ remote_target::download_tracepoint (struct bp_location *loc)
        warning (_("Target does not support fast tracepoints, "
                   "downloading %d as regular tracepoint"), b->number);
     }
-  else if (b->type == bp_static_tracepoint)
+  else if (b->type == bp_static_tracepoint
+          || b->type == bp_static_marker_tracepoint)
     {
       /* Only test for support at download time; we may not know
         target capabilities at definition time.  */
@@ -13286,7 +13395,7 @@ remote_target::download_tracepoint (struct bp_location *loc)
          size_left = buf.size () - strlen (buf.data ());
 
          ret = snprintf (buf.data () + strlen (buf.data ()),
-                         size_left, ":X%x,", aexpr->len);
+                         size_left, ":X%x,", (int) aexpr->buf.size ());
 
          if (ret < 0 || ret >= size_left)
            error ("%s", err_msg);
@@ -13295,12 +13404,12 @@ remote_target::download_tracepoint (struct bp_location *loc)
 
          /* Two bytes to encode each aexpr byte, plus the terminating
             null byte.  */
-         if (aexpr->len * 2 + 1 > size_left)
+         if (aexpr->buf.size () * 2 + 1 > size_left)
            error ("%s", err_msg);
 
          pkt = buf.data () + strlen (buf.data ());
 
-         for (int ndx = 0; ndx < aexpr->len; ++ndx)
+         for (int ndx = 0; ndx < aexpr->buf.size (); ++ndx)
            pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
          *pkt = '\0';
        }
@@ -13371,17 +13480,17 @@ remote_target::download_tracepoint (struct bp_location *loc)
        error (_("Error on target while setting tracepoints."));
     }
 
-  if (packet_support (PACKET_TracepointSource) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_TracepointSource) == PACKET_ENABLE)
     {
-      if (b->location != NULL)
+      if (b->locspec != nullptr)
        {
          ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
 
          if (ret < 0 || ret >= buf.size ())
            error ("%s", err_msg);
 
-         encode_source_string (b->number, loc->address, "at",
-                               event_location_to_string (b->location.get ()),
+         const char *str = b->locspec->to_string ();
+         encode_source_string (b->number, loc->address, "at", str,
                                buf.data () + strlen (buf.data ()),
                                buf.size () - strlen (buf.data ()));
          putpkt (buf.data ());
@@ -13501,33 +13610,35 @@ remote_target::trace_set_readonly_regions ()
   bfd_vma vma;
   int anysecs = 0;
   int offset = 0;
+  bfd *abfd = current_program_space->exec_bfd ();
 
-  if (!current_program_space->exec_bfd ())
+  if (!abfd)
     return;                    /* No information to give.  */
 
   struct remote_state *rs = get_remote_state ();
 
   strcpy (rs->buf.data (), "QTro");
   offset = strlen (rs->buf.data ());
-  for (s = current_program_space->exec_bfd ()->sections; s; s = s->next)
+  for (s = abfd->sections; s; s = s->next)
     {
       char tmp1[40], tmp2[40];
       int sec_length;
 
-      if ((s->flags & SEC_LOAD) == 0 ||
-      /*  (s->flags & SEC_CODE) == 0 || */
-         (s->flags & SEC_READONLY) == 0)
+      if ((s->flags & SEC_LOAD) == 0
+         /* || (s->flags & SEC_CODE) == 0 */
+         || (s->flags & SEC_READONLY) == 0)
        continue;
 
       anysecs = 1;
       vma = bfd_section_vma (s);
       size = bfd_section_size (s);
-      sprintf_vma (tmp1, vma);
-      sprintf_vma (tmp2, vma + size);
+      bfd_sprintf_vma (abfd, tmp1, vma);
+      bfd_sprintf_vma (abfd, tmp2, vma + size);
       sec_length = 1 + strlen (tmp1) + 1 + strlen (tmp2);
       if (offset + sec_length + 1 > rs->buf.size ())
        {
-         if (packet_support (PACKET_qXfer_traceframe_info) != PACKET_ENABLE)
+         if (m_features.packet_support (PACKET_qXfer_traceframe_info)
+             != PACKET_ENABLE)
            warning (_("\
 Too many sections for read-only sections definition packet."));
          break;
@@ -13539,7 +13650,7 @@ Too many sections for read-only sections definition packet."));
   if (anysecs)
     {
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
     }
 }
 
@@ -13564,12 +13675,12 @@ remote_target::get_trace_status (struct trace_status *ts)
   enum packet_result result;
   struct remote_state *rs = get_remote_state ();
 
-  if (packet_support (PACKET_qTStatus) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qTStatus) == PACKET_DISABLE)
     return -1;
 
   /* FIXME we need to get register block size some other way.  */
   trace_regblock_size
-    = rs->get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
+    = rs->get_remote_arch_state (current_inferior ()->arch ())->sizeof_g_packet;
 
   putpkt ("qTStatus");
 
@@ -13587,7 +13698,7 @@ remote_target::get_trace_status (struct trace_status *ts)
       throw;
     }
 
-  result = packet_ok (p, &remote_protocol_packets[PACKET_qTStatus]);
+  result = m_features.packet_ok (p, PACKET_qTStatus);
 
   /* If the remote target doesn't do tracing, flag it.  */
   if (result == PACKET_UNKNOWN)
@@ -13607,32 +13718,31 @@ remote_target::get_trace_status (struct trace_status *ts)
 }
 
 void
-remote_target::get_tracepoint_status (struct breakpoint *bp,
+remote_target::get_tracepoint_status (tracepoint *tp,
                                      struct uploaded_tp *utp)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
-  struct tracepoint *tp = (struct tracepoint *) bp;
   size_t size = get_remote_packet_size ();
 
   if (tp)
     {
       tp->hit_count = 0;
       tp->traceframe_usage = 0;
-      for (bp_location *loc : tp->locations ())
+      for (bp_location &loc : tp->locations ())
        {
          /* If the tracepoint was never downloaded, don't go asking for
             any status.  */
          if (tp->number_on_target == 0)
            continue;
          xsnprintf (rs->buf.data (), size, "qTP:%x:%s", tp->number_on_target,
-                    phex_nz (loc->address, 0));
+                    phex_nz (loc.address, 0));
          putpkt (rs->buf);
          reply = remote_get_noisy_reply ();
          if (reply && *reply)
            {
              if (*reply == 'V')
-               parse_tracepoint_status (reply + 1, bp, utp);
+               parse_tracepoint_status (reply + 1, tp, utp);
            }
        }
     }
@@ -13647,7 +13757,7 @@ remote_target::get_tracepoint_status (struct breakpoint *bp,
       if (reply && *reply)
        {
          if (*reply == 'V')
-           parse_tracepoint_status (reply + 1, bp, utp);
+           parse_tracepoint_status (reply + 1, tp, utp);
        }
     }
 }
@@ -13842,7 +13952,8 @@ remote_target::set_disconnected_tracing (int val)
 {
   struct remote_state *rs = get_remote_state ();
 
-  if (packet_support (PACKET_DisconnectedTracing_feature) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_DisconnectedTracing_feature)
+      == PACKET_ENABLE)
     {
       char *reply;
 
@@ -13862,7 +13973,7 @@ remote_target::set_disconnected_tracing (int val)
 int
 remote_target::core_of_thread (ptid_t ptid)
 {
-  thread_info *info = find_thread_ptid (this, ptid);
+  thread_info *info = this->find_thread (ptid);
 
   if (info != NULL && info->priv != NULL)
     return get_remote_thread_info (info)->core;
@@ -13936,7 +14047,7 @@ remote_target::get_min_fast_tracepoint_insn_len ()
 void
 remote_target::set_trace_buffer_size (LONGEST val)
 {
-  if (packet_support (PACKET_QTBuffer_size) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QTBuffer_size) != PACKET_DISABLE)
     {
       struct remote_state *rs = get_remote_state ();
       char *buf = rs->buf.data ();
@@ -13956,8 +14067,7 @@ remote_target::set_trace_buffer_size (LONGEST val)
 
       putpkt (rs->buf);
       remote_get_noisy_reply ();
-      result = packet_ok (rs->buf,
-                 &remote_protocol_packets[PACKET_QTBuffer_size]);
+      result = m_features.packet_ok (rs->buf, PACKET_QTBuffer_size);
 
       if (result != PACKET_OK)
        warning (_("Bogus reply from target: %s"), rs->buf.data ());
@@ -14013,14 +14123,14 @@ remote_target::set_trace_notes (const char *user, const char *notes,
 bool
 remote_target::use_agent (bool use)
 {
-  if (packet_support (PACKET_QAgent) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QAgent) != PACKET_DISABLE)
     {
       struct remote_state *rs = get_remote_state ();
 
       /* If the stub supports QAgent.  */
       xsnprintf (rs->buf.data (), get_remote_packet_size (), "QAgent:%d", use);
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
       if (strcmp (rs->buf.data (), "OK") == 0)
        {
@@ -14035,18 +14145,326 @@ remote_target::use_agent (bool use)
 bool
 remote_target::can_use_agent ()
 {
-  return (packet_support (PACKET_QAgent) != PACKET_DISABLE);
+  return (m_features.packet_support (PACKET_QAgent) != PACKET_DISABLE);
+}
+
+#if defined (HAVE_LIBEXPAT)
+
+/* Check the btrace document version.  */
+
+static void
+check_xml_btrace_version (struct gdb_xml_parser *parser,
+                         const struct gdb_xml_element *element,
+                         void *user_data,
+                         std::vector<gdb_xml_value> &attributes)
+{
+  const char *version
+    = (const char *) xml_find_attribute (attributes, "version")->value.get ();
+
+  if (strcmp (version, "1.0") != 0)
+    gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version);
 }
 
-struct btrace_target_info
+/* Parse a btrace "block" xml record.  */
+
+static void
+parse_xml_btrace_block (struct gdb_xml_parser *parser,
+                       const struct gdb_xml_element *element,
+                       void *user_data,
+                       std::vector<gdb_xml_value> &attributes)
 {
-  /* The ptid of the traced thread.  */
-  ptid_t ptid;
+  struct btrace_data *btrace;
+  ULONGEST *begin, *end;
+
+  btrace = (struct btrace_data *) user_data;
+
+  switch (btrace->format)
+    {
+    case BTRACE_FORMAT_BTS:
+      break;
+
+    case BTRACE_FORMAT_NONE:
+      btrace->format = BTRACE_FORMAT_BTS;
+      btrace->variant.bts.blocks = new std::vector<btrace_block>;
+      break;
+
+    default:
+      gdb_xml_error (parser, _("Btrace format error."));
+    }
+
+  begin = (ULONGEST *) xml_find_attribute (attributes, "begin")->value.get ();
+  end = (ULONGEST *) xml_find_attribute (attributes, "end")->value.get ();
+  btrace->variant.bts.blocks->emplace_back (*begin, *end);
+}
+
+/* Parse a "raw" xml record.  */
+
+static void
+parse_xml_raw (struct gdb_xml_parser *parser, const char *body_text,
+              gdb_byte **pdata, size_t *psize)
+{
+  gdb_byte *bin;
+  size_t len, size;
+
+  len = strlen (body_text);
+  if (len % 2 != 0)
+    gdb_xml_error (parser, _("Bad raw data size."));
+
+  size = len / 2;
+
+  gdb::unique_xmalloc_ptr<gdb_byte> data ((gdb_byte *) xmalloc (size));
+  bin = data.get ();
+
+  /* We use hex encoding - see gdbsupport/rsp-low.h.  */
+  while (len > 0)
+    {
+      char hi, lo;
+
+      hi = *body_text++;
+      lo = *body_text++;
+
+      if (hi == 0 || lo == 0)
+       gdb_xml_error (parser, _("Bad hex encoding."));
+
+      *bin++ = fromhex (hi) * 16 + fromhex (lo);
+      len -= 2;
+    }
+
+  *pdata = data.release ();
+  *psize = size;
+}
+
+/* Parse a btrace pt-config "cpu" xml record.  */
+
+static void
+parse_xml_btrace_pt_config_cpu (struct gdb_xml_parser *parser,
+                               const struct gdb_xml_element *element,
+                               void *user_data,
+                               std::vector<gdb_xml_value> &attributes)
+{
+  struct btrace_data *btrace;
+  const char *vendor;
+  ULONGEST *family, *model, *stepping;
+
+  vendor
+    = (const char *) xml_find_attribute (attributes, "vendor")->value.get ();
+  family
+    = (ULONGEST *) xml_find_attribute (attributes, "family")->value.get ();
+  model
+    = (ULONGEST *) xml_find_attribute (attributes, "model")->value.get ();
+  stepping
+    = (ULONGEST *) xml_find_attribute (attributes, "stepping")->value.get ();
+
+  btrace = (struct btrace_data *) user_data;
+
+  if (strcmp (vendor, "GenuineIntel") == 0)
+    btrace->variant.pt.config.cpu.vendor = CV_INTEL;
+
+  btrace->variant.pt.config.cpu.family = *family;
+  btrace->variant.pt.config.cpu.model = *model;
+  btrace->variant.pt.config.cpu.stepping = *stepping;
+}
+
+/* Parse a btrace pt "raw" xml record.  */
+
+static void
+parse_xml_btrace_pt_raw (struct gdb_xml_parser *parser,
+                        const struct gdb_xml_element *element,
+                        void *user_data, const char *body_text)
+{
+  struct btrace_data *btrace;
+
+  btrace = (struct btrace_data *) user_data;
+  parse_xml_raw (parser, body_text, &btrace->variant.pt.data,
+                &btrace->variant.pt.size);
+}
+
+/* Parse a btrace "pt" xml record.  */
+
+static void
+parse_xml_btrace_pt (struct gdb_xml_parser *parser,
+                    const struct gdb_xml_element *element,
+                    void *user_data,
+                    std::vector<gdb_xml_value> &attributes)
+{
+  struct btrace_data *btrace;
+
+  btrace = (struct btrace_data *) user_data;
+  btrace->format = BTRACE_FORMAT_PT;
+  btrace->variant.pt.config.cpu.vendor = CV_UNKNOWN;
+  btrace->variant.pt.data = NULL;
+  btrace->variant.pt.size = 0;
+}
+
+static const struct gdb_xml_attribute block_attributes[] = {
+  { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_pt_config_cpu_attributes[] = {
+  { "vendor", GDB_XML_AF_NONE, NULL, NULL },
+  { "family", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "model", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "stepping", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_pt_config_children[] = {
+  { "cpu", btrace_pt_config_cpu_attributes, NULL, GDB_XML_EF_OPTIONAL,
+    parse_xml_btrace_pt_config_cpu, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_pt_children[] = {
+  { "pt-config", NULL, btrace_pt_config_children, GDB_XML_EF_OPTIONAL, NULL,
+    NULL },
+  { "raw", NULL, NULL, GDB_XML_EF_OPTIONAL, NULL, parse_xml_btrace_pt_raw },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_attributes[] = {
+  { "version", GDB_XML_AF_NONE, NULL, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_children[] = {
+  { "block", block_attributes, NULL,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL },
+  { "pt", NULL, btrace_pt_children, GDB_XML_EF_OPTIONAL, parse_xml_btrace_pt,
+    NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_elements[] = {
+  { "btrace", btrace_attributes, btrace_children, GDB_XML_EF_NONE,
+    check_xml_btrace_version, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+#endif /* defined (HAVE_LIBEXPAT) */
+
+/* Parse a branch trace xml document XML into DATA.  */
+
+static void
+parse_xml_btrace (struct btrace_data *btrace, const char *buffer)
+{
+#if defined (HAVE_LIBEXPAT)
+
+  int errcode;
+  btrace_data result;
+  result.format = BTRACE_FORMAT_NONE;
+
+  errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements,
+                                buffer, &result);
+  if (errcode != 0)
+    error (_("Error parsing branch trace."));
+
+  /* Keep parse results.  */
+  *btrace = std::move (result);
+
+#else  /* !defined (HAVE_LIBEXPAT) */
+
+  error (_("Cannot process branch trace.  XML support was disabled at "
+          "compile time."));
+
+#endif  /* !defined (HAVE_LIBEXPAT) */
+}
+
+#if defined (HAVE_LIBEXPAT)
+
+/* Parse a btrace-conf "bts" xml record.  */
+
+static void
+parse_xml_btrace_conf_bts (struct gdb_xml_parser *parser,
+                         const struct gdb_xml_element *element,
+                         void *user_data,
+                         std::vector<gdb_xml_value> &attributes)
+{
+  struct btrace_config *conf;
+  struct gdb_xml_value *size;
+
+  conf = (struct btrace_config *) user_data;
+  conf->format = BTRACE_FORMAT_BTS;
+  conf->bts.size = 0;
+
+  size = xml_find_attribute (attributes, "size");
+  if (size != NULL)
+    conf->bts.size = (unsigned int) *(ULONGEST *) size->value.get ();
+}
+
+/* Parse a btrace-conf "pt" xml record.  */
 
-  /* The obtained branch trace configuration.  */
-  struct btrace_config conf;
+static void
+parse_xml_btrace_conf_pt (struct gdb_xml_parser *parser,
+                         const struct gdb_xml_element *element,
+                         void *user_data,
+                         std::vector<gdb_xml_value> &attributes)
+{
+  struct btrace_config *conf;
+  struct gdb_xml_value *size;
+
+  conf = (struct btrace_config *) user_data;
+  conf->format = BTRACE_FORMAT_PT;
+  conf->pt.size = 0;
+
+  size = xml_find_attribute (attributes, "size");
+  if (size != NULL)
+    conf->pt.size = (unsigned int) *(ULONGEST *) size->value.get ();
+}
+
+static const struct gdb_xml_attribute btrace_conf_pt_attributes[] = {
+  { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_conf_bts_attributes[] = {
+  { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_conf_children[] = {
+  { "bts", btrace_conf_bts_attributes, NULL, GDB_XML_EF_OPTIONAL,
+    parse_xml_btrace_conf_bts, NULL },
+  { "pt", btrace_conf_pt_attributes, NULL, GDB_XML_EF_OPTIONAL,
+    parse_xml_btrace_conf_pt, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_conf_attributes[] = {
+  { "version", GDB_XML_AF_NONE, NULL, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
+static const struct gdb_xml_element btrace_conf_elements[] = {
+  { "btrace-conf", btrace_conf_attributes, btrace_conf_children,
+    GDB_XML_EF_NONE, NULL, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+#endif /* defined (HAVE_LIBEXPAT) */
+
+/* Parse a branch trace configuration xml document XML into CONF.  */
+
+static void
+parse_xml_btrace_conf (struct btrace_config *conf, const char *xml)
+{
+#if defined (HAVE_LIBEXPAT)
+
+  int errcode;
+  errcode = gdb_xml_parse_quick (_("btrace-conf"), "btrace-conf.dtd",
+                                btrace_conf_elements, xml, conf);
+  if (errcode != 0)
+    error (_("Error parsing branch trace configuration."));
+
+#else  /* !defined (HAVE_LIBEXPAT) */
+
+  error (_("Cannot process the branch trace configuration.  XML support "
+          "was disabled at compile time."));
+
+#endif  /* !defined (HAVE_LIBEXPAT) */
+}
+
 /* Reset our idea of our target's btrace configuration.  */
 
 static void
@@ -14060,7 +14478,6 @@ remote_btrace_reset (remote_state *rs)
 void
 remote_target::btrace_sync_conf (const btrace_config *conf)
 {
-  struct packet_config *packet;
   struct remote_state *rs;
   char *buf, *pos, *endbuf;
 
@@ -14068,18 +14485,19 @@ remote_target::btrace_sync_conf (const btrace_config *conf)
   buf = rs->buf.data ();
   endbuf = buf + get_remote_packet_size ();
 
-  packet = &remote_protocol_packets[PACKET_Qbtrace_conf_bts_size];
-  if (packet_config_support (packet) == PACKET_ENABLE
+  if (m_features.packet_support (PACKET_Qbtrace_conf_bts_size) == PACKET_ENABLE
       && conf->bts.size != rs->btrace_config.bts.size)
     {
       pos = buf;
-      pos += xsnprintf (pos, endbuf - pos, "%s=0x%x", packet->name,
+      pos += xsnprintf (pos, endbuf - pos, "%s=0x%x",
+                       packets_descriptions[PACKET_Qbtrace_conf_bts_size].name,
                        conf->bts.size);
 
       putpkt (buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
-      if (packet_ok (buf, packet) == PACKET_ERROR)
+      if (m_features.packet_ok (buf, PACKET_Qbtrace_conf_bts_size)
+         == PACKET_ERROR)
        {
          if (buf[0] == 'E' && buf[1] == '.')
            error (_("Failed to configure the BTS buffer size: %s"), buf + 2);
@@ -14090,18 +14508,19 @@ remote_target::btrace_sync_conf (const btrace_config *conf)
       rs->btrace_config.bts.size = conf->bts.size;
     }
 
-  packet = &remote_protocol_packets[PACKET_Qbtrace_conf_pt_size];
-  if (packet_config_support (packet) == PACKET_ENABLE
+  if (m_features.packet_support (PACKET_Qbtrace_conf_pt_size) == PACKET_ENABLE
       && conf->pt.size != rs->btrace_config.pt.size)
     {
       pos = buf;
-      pos += xsnprintf (pos, endbuf - pos, "%s=0x%x", packet->name,
+      pos += xsnprintf (pos, endbuf - pos, "%s=0x%x",
+                       packets_descriptions[PACKET_Qbtrace_conf_pt_size].name,
                        conf->pt.size);
 
       putpkt (buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
 
-      if (packet_ok (buf, packet) == PACKET_ERROR)
+      if (m_features.packet_ok (buf, PACKET_Qbtrace_conf_pt_size)
+         == PACKET_ERROR)
        {
          if (buf[0] == 'E' && buf[1] == '.')
            error (_("Failed to configure the trace buffer size: %s"), buf + 2);
@@ -14113,12 +14532,15 @@ remote_target::btrace_sync_conf (const btrace_config *conf)
     }
 }
 
-/* Read the current thread's btrace configuration from the target and
-   store it into CONF.  */
+/* Read TP's btrace configuration from the target and store it into CONF.  */
 
 static void
-btrace_read_config (struct btrace_config *conf)
+btrace_read_config (thread_info *tp, btrace_config *conf)
 {
+  /* target_read_stralloc relies on INFERIOR_PTID.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
+
   gdb::optional<gdb::char_vector> xml
     = target_read_stralloc (current_inferior ()->top_target (),
                            TARGET_OBJECT_BTRACE_CONF, "");
@@ -14139,17 +14561,13 @@ remote_target::remote_btrace_maybe_reopen ()
 
   /* Don't bother walking the entirety of the remote thread list when
      we know the feature isn't supported by the remote.  */
-  if (packet_support (PACKET_qXfer_btrace_conf) != PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_qXfer_btrace_conf) != PACKET_ENABLE)
     return;
 
-  scoped_restore_current_thread restore_thread;
-
   for (thread_info *tp : all_non_exited_threads (this))
     {
-      set_general_thread (tp->ptid);
-
       memset (&rs->btrace_config, 0x00, sizeof (struct btrace_config));
-      btrace_read_config (&rs->btrace_config);
+      btrace_read_config (tp, &rs->btrace_config);
 
       if (rs->btrace_config.format == BTRACE_FORMAT_NONE)
        continue;
@@ -14175,50 +14593,55 @@ remote_target::remote_btrace_maybe_reopen ()
        {
          btrace_target_pushed = 1;
          record_btrace_push_target ();
-         printf_filtered (_("Target is recording using %s.\n"),
-                          btrace_format_string (rs->btrace_config.format));
+         gdb_printf (_("Target is recording using %s.\n"),
+                     btrace_format_string (rs->btrace_config.format));
        }
 
-      tp->btrace.target = XCNEW (struct btrace_target_info);
-      tp->btrace.target->ptid = tp->ptid;
-      tp->btrace.target->conf = rs->btrace_config;
+      tp->btrace.target
+       = new btrace_target_info { tp->ptid, rs->btrace_config };
     }
 }
 
 /* Enable branch tracing.  */
 
 struct btrace_target_info *
-remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf)
+remote_target::enable_btrace (thread_info *tp,
+                             const struct btrace_config *conf)
 {
-  struct btrace_target_info *tinfo = NULL;
   struct packet_config *packet = NULL;
   struct remote_state *rs = get_remote_state ();
   char *buf = rs->buf.data ();
   char *endbuf = buf + get_remote_packet_size ();
 
+  unsigned int which_packet;
   switch (conf->format)
     {
       case BTRACE_FORMAT_BTS:
-       packet = &remote_protocol_packets[PACKET_Qbtrace_bts];
+       which_packet = PACKET_Qbtrace_bts;
        break;
-
       case BTRACE_FORMAT_PT:
-       packet = &remote_protocol_packets[PACKET_Qbtrace_pt];
+       which_packet = PACKET_Qbtrace_pt;
        break;
+      default:
+       internal_error (_("Bad branch btrace format: %u."),
+                       (unsigned int) conf->format);
     }
 
+  packet = &m_features.m_protocol_packets[which_packet];
   if (packet == NULL || packet_config_support (packet) != PACKET_ENABLE)
     error (_("Target does not support branch tracing."));
 
   btrace_sync_conf (conf);
 
+  ptid_t ptid = tp->ptid;
   set_general_thread (ptid);
 
-  buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+  buf += xsnprintf (buf, endbuf - buf, "%s",
+                   packets_descriptions[which_packet].name);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  if (packet_ok (rs->buf, packet) == PACKET_ERROR)
+  if (m_features.packet_ok (rs->buf, which_packet) == PACKET_ERROR)
     {
       if (rs->buf[0] == 'E' && rs->buf[1] == '.')
        error (_("Could not enable branch tracing for %s: %s"),
@@ -14228,14 +14651,13 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf)
               target_pid_to_str (ptid).c_str ());
     }
 
-  tinfo = XCNEW (struct btrace_target_info);
-  tinfo->ptid = ptid;
+  btrace_target_info *tinfo = new btrace_target_info { ptid };
 
   /* If we fail to read the configuration, we lose some information, but the
      tracing itself is not impacted.  */
   try
     {
-      btrace_read_config (&tinfo->conf);
+      btrace_read_config (tp, &tinfo->conf);
     }
   catch (const gdb_exception_error &err)
     {
@@ -14251,21 +14673,21 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 void
 remote_target::disable_btrace (struct btrace_target_info *tinfo)
 {
-  struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace_off];
   struct remote_state *rs = get_remote_state ();
   char *buf = rs->buf.data ();
   char *endbuf = buf + get_remote_packet_size ();
 
-  if (packet_config_support (packet) != PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_Qbtrace_off) != PACKET_ENABLE)
     error (_("Target does not support branch tracing."));
 
   set_general_thread (tinfo->ptid);
 
-  buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+  buf += xsnprintf (buf, endbuf - buf, "%s",
+                   packets_descriptions[PACKET_Qbtrace_off].name);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  if (packet_ok (rs->buf, packet) == PACKET_ERROR)
+  if (m_features.packet_ok (rs->buf, PACKET_Qbtrace_off) == PACKET_ERROR)
     {
       if (rs->buf[0] == 'E' && rs->buf[1] == '.')
        error (_("Could not disable branch tracing for %s: %s"),
@@ -14275,7 +14697,7 @@ remote_target::disable_btrace (struct btrace_target_info *tinfo)
               target_pid_to_str (tinfo->ptid).c_str ());
     }
 
-  xfree (tinfo);
+  delete tinfo;
 }
 
 /* Teardown branch tracing.  */
@@ -14284,7 +14706,7 @@ void
 remote_target::teardown_btrace (struct btrace_target_info *tinfo)
 {
   /* We must not talk to the target during teardown.  */
-  xfree (tinfo);
+  delete tinfo;
 }
 
 /* Read the branch trace.  */
@@ -14294,10 +14716,9 @@ remote_target::read_btrace (struct btrace_data *btrace,
                            struct btrace_target_info *tinfo,
                            enum btrace_read_type type)
 {
-  struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
   const char *annex;
 
-  if (packet_config_support (packet) != PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_qXfer_btrace) != PACKET_ENABLE)
     error (_("Target does not support branch tracing."));
 
 #if !defined(HAVE_LIBEXPAT)
@@ -14316,8 +14737,7 @@ remote_target::read_btrace (struct btrace_data *btrace,
       annex = "delta";
       break;
     default:
-      internal_error (__FILE__, __LINE__,
-                     _("Bad branch tracing read type: %u."),
+      internal_error (_("Bad branch tracing read type: %u."),
                      (unsigned int) type);
     }
 
@@ -14341,8 +14761,9 @@ remote_target::btrace_conf (const struct btrace_target_info *tinfo)
 bool
 remote_target::augmented_libraries_svr4_read ()
 {
-  return (packet_support (PACKET_augmented_libraries_svr4_read_feature)
-         == PACKET_ENABLE);
+  return
+    (m_features.packet_support (PACKET_augmented_libraries_svr4_read_feature)
+     == PACKET_ENABLE);
 }
 
 /* Implementation of to_load.  */
@@ -14357,19 +14778,18 @@ remote_target::load (const char *name, int from_tty)
    can be opened on the remote side to get the symbols for the child
    process.  Returns NULL if the operation is not supported.  */
 
-char *
+const char *
 remote_target::pid_to_exec_file (int pid)
 {
   static gdb::optional<gdb::char_vector> filename;
   char *annex = NULL;
 
-  if (packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE)
     return NULL;
 
   inferior *inf = find_inferior_pid (this, pid);
   if (inf == NULL)
-    internal_error (__FILE__, __LINE__,
-                   _("not currently attached to process %d"), pid);
+    internal_error (_("not currently attached to process %d"), pid);
 
   if (!inf->fake_pid_p)
     {
@@ -14395,13 +14815,10 @@ remote_target::can_do_single_step ()
      feature.  If the stub doesn't support vContSupported feature,
      we have conservatively to think target doesn't supports single
      step.  */
-  if (packet_support (PACKET_vContSupported) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_vContSupported) == PACKET_ENABLE)
     {
       struct remote_state *rs = get_remote_state ();
 
-      if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-       remote_vcont_probe ();
-
       return rs->supports_vCont.s && rs->supports_vCont.S;
     }
   else
@@ -14445,7 +14862,7 @@ remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
   return NULL;
 }
 
-gdb::byte_vector
+gdb::array_view<const gdb_byte>
 remote_target::thread_info_to_thread_handle (struct thread_info *tp)
 {
   remote_thread_info *priv = get_remote_thread_info (tp);
@@ -14459,16 +14876,14 @@ remote_target::can_async_p ()
   gdb_assert (target_async_permitted);
 
   /* We're async whenever the serial device can.  */
-  struct remote_state *rs = get_remote_state ();
-  return serial_can_async_p (rs->remote_desc);
+  return get_remote_state ()->can_async_p ();
 }
 
 bool
 remote_target::is_async_p ()
 {
   /* We're async whenever the serial device is.  */
-  struct remote_state *rs = get_remote_state ();
-  return serial_is_async_p (rs->remote_desc);
+  return get_remote_state ()->is_async_p ();
 }
 
 /* Pass the SERIAL event on and up to the client.  One day this code
@@ -14485,12 +14900,6 @@ remote_async_serial_handler (struct serial *scb, void *context)
   inferior_event_handler (INF_REG_EVENT);
 }
 
-static void
-remote_async_inferior_event_handler (gdb_client_data data)
-{
-  inferior_event_handler (INF_REG_EVENT);
-}
-
 int
 remote_target::async_wait_fd ()
 {
@@ -14499,7 +14908,7 @@ remote_target::async_wait_fd ()
 }
 
 void
-remote_target::async (int enable)
+remote_target::async (bool enable)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -14510,7 +14919,8 @@ remote_target::async (int enable)
       /* If there are pending events in the stop reply queue tell the
         event loop to process them.  */
       if (!rs->stop_reply_queue.empty ())
-       mark_async_event_handler (rs->remote_async_inferior_event_token);
+       rs->mark_async_event_handler ();
+
       /* For simplicity, below we clear the pending events token
         without remembering whether it is marked, so here we always
         mark it.  If there's actually no pending notification to
@@ -14525,7 +14935,8 @@ remote_target::async (int enable)
       /* If the core is disabling async, it doesn't want to be
         disturbed with target events.  Clear all async event sources
         too.  */
-      clear_async_event_handler (rs->remote_async_inferior_event_token);
+      rs->clear_async_event_handler ();
+
       if (target_is_non_stop_p ())
        clear_async_event_handler (rs->notif_state->get_pending_events_token);
     }
@@ -14539,15 +14950,14 @@ remote_target::thread_events (int enable)
   struct remote_state *rs = get_remote_state ();
   size_t size = get_remote_packet_size ();
 
-  if (packet_support (PACKET_QThreadEvents) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QThreadEvents) == PACKET_DISABLE)
     return;
 
   xsnprintf (rs->buf.data (), size, "QThreadEvents:%x", enable ? 1 : 0);
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
-  switch (packet_ok (rs->buf,
-                    &remote_protocol_packets[PACKET_QThreadEvents]))
+  switch (m_features.packet_ok (rs->buf, PACKET_QThreadEvents))
     {
     case PACKET_OK:
       if (strcmp (rs->buf.data (), "OK") != 0)
@@ -14590,40 +15000,73 @@ show_remote_cmd (const char *args, int from_tty)
       }
 }
 
+/* Some change happened in PSPACE's objfile list (obfiles added or removed),
+   offer all inferiors using that program space a change to look up symbols.  */
 
-/* Function to be called whenever a new objfile (shlib) is detected.  */
 static void
-remote_new_objfile (struct objfile *objfile)
+remote_objfile_changed_check_symbols (program_space *pspace)
 {
-  remote_target *remote = get_current_remote_target ();
+  /* The affected program space is possibly shared by multiple inferiors.
+     Consider sending a qSymbol packet for each of the inferiors using that
+     program space.  */
+  for (inferior *inf : all_inferiors ())
+    {
+      if (inf->pspace != pspace)
+       continue;
 
-  /* First, check whether the current inferior's process target is a remote
-     target.  */
-  if (remote == nullptr)
-    return;
+      /* Check whether the inferior's process target is a remote target.  */
+      remote_target *remote = as_remote_target (inf->process_target ());
+      if (remote == nullptr)
+       continue;
 
-  /* When we are attaching or handling a fork child and the shared library
-     subsystem reads the list of loaded libraries, we receive new objfile
-     events in between each found library.  The libraries are read in an
-     undefined order, so if we gave the remote side a chance to look up
-     symbols between each objfile, we might give it an inconsistent picture
-     of the inferior.  It could appear that a library A appears loaded but
-     a library B does not, even though library A requires library B.  That
-     would present a state that couldn't normally exist in the inferior.
-
-     So, skip these events, we'll give the remote a chance to look up symbols
-     once all the loaded libraries and their symbols are known to GDB.  */
-  if (current_inferior ()->in_initial_library_scan)
-    return;
+      /* When we are attaching or handling a fork child and the shared library
+        subsystem reads the list of loaded libraries, we receive new objfile
+        events in between each found library.  The libraries are read in an
+        undefined order, so if we gave the remote side a chance to look up
+        symbols between each objfile, we might give it an inconsistent picture
+        of the inferior.  It could appear that a library A appears loaded but
+        a library B does not, even though library A requires library B.  That
+        would present a state that couldn't normally exist in the inferior.
+
+        So, skip these events, we'll give the remote a chance to look up
+        symbols once all the loaded libraries and their symbols are known to
+        GDB.  */
+      if (inf->in_initial_library_scan)
+       continue;
+
+      if (!remote->has_execution (inf))
+       continue;
+
+      /* Need to switch to a specific thread, because remote_check_symbols will
+        set the general thread using INFERIOR_PTID.
+
+        It's possible to have inferiors with no thread here, because we are
+        called very early in the connection process, while the inferior is
+        being set up, before threads are added.  Just skip it, start_remote_1
+        also calls remote_check_symbols when it's done setting things up.  */
+      thread_info *thread = any_thread_of_inferior (inf);
+      if (thread != nullptr)
+       {
+         scoped_restore_current_thread restore_thread;
+         switch_to_thread (thread);
+         remote->remote_check_symbols ();
+       }
+  }
+}
 
-  remote->remote_check_symbols ();
+/* Function to be called whenever a new objfile (shlib) is detected.  */
+
+static void
+remote_new_objfile (struct objfile *objfile)
+{
+  remote_objfile_changed_check_symbols (objfile->pspace);
 }
 
 /* Pull all the tracepoints defined on the target and create local
    data structures representing them.  We don't want to create real
    tracepoints yet, we don't want to mess up the user's existing
    collection.  */
-  
+
 int
 remote_target::upload_tracepoints (struct uploaded_tp **utpp)
 {
@@ -14632,14 +15075,14 @@ remote_target::upload_tracepoints (struct uploaded_tp **utpp)
 
   /* Ask for a first packet of tracepoint definition.  */
   putpkt ("qTfP");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   p = rs->buf.data ();
   while (*p && *p != 'l')
     {
       parse_tracepoint_definition (p, utpp);
       /* Ask for another packet of tracepoint definition.  */
       putpkt ("qTsP");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       p = rs->buf.data ();
     }
   return 0;
@@ -14653,14 +15096,14 @@ remote_target::upload_trace_state_variables (struct uploaded_tsv **utsvp)
 
   /* Ask for a first packet of variable definition.  */
   putpkt ("qTfV");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   p = rs->buf.data ();
   while (*p && *p != 'l')
     {
       parse_tsv_definition (p, utsvp);
       /* Ask for another packet of variable definition.  */
       putpkt ("qTsV");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
       p = rs->buf.data ();
     }
   return 0;
@@ -14673,9 +15116,9 @@ show_range_stepping (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c,
                     const char *value)
 {
-  fprintf_filtered (file,
-                   _("Debugger's willingness to use range stepping "
-                     "is %s.\n"), value);
+  gdb_printf (file,
+             _("Debugger's willingness to use range stepping "
+               "is %s.\n"), value);
 }
 
 /* Return true if the vCont;r action is supported by the remote
@@ -14684,10 +15127,7 @@ show_range_stepping (struct ui_file *file, int from_tty,
 bool
 remote_target::vcont_r_supported ()
 {
-  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-    remote_vcont_probe ();
-
-  return (packet_support (PACKET_vCont) == PACKET_ENABLE
+  return (m_features.packet_support (PACKET_vCont) == PACKET_ENABLE
          && get_remote_state ()->supports_vCont.r);
 }
 
@@ -14712,17 +15152,17 @@ static void
 show_remote_debug (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Debugging of remote protocol is %s.\n"),
-                   value);
+  gdb_printf (file, _("Debugging of remote protocol is %s.\n"),
+             value);
 }
 
 static void
 show_remote_timeout (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Timeout limit to wait for target to respond is %s.\n"),
-                   value);
+  gdb_printf (file,
+             _("Timeout limit to wait for target to respond is %s.\n"),
+             value);
 }
 
 /* Implement the "supports_memory_tagging" target_ops method.  */
@@ -14730,7 +15170,7 @@ show_remote_timeout (struct ui_file *file, int from_tty,
 bool
 remote_target::supports_memory_tagging ()
 {
-  return remote_memory_tagging_p ();
+  return m_features.remote_memory_tagging_p ();
 }
 
 /* Create the qMemTags packet given ADDRESS, LEN and TYPE.  */
@@ -14739,7 +15179,7 @@ static void
 create_fetch_memtags_request (gdb::char_vector &packet, CORE_ADDR address,
                              size_t len, int type)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+  int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
 
   std::string request = string_printf ("qMemTags:%s,%s:%s",
                                       phex_nz (address, addr_size),
@@ -14773,7 +15213,7 @@ create_store_memtags_request (gdb::char_vector &packet, CORE_ADDR address,
                              size_t len, int type,
                              const gdb::byte_vector &tags)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
+  int addr_size = gdbarch_addr_bit (current_inferior ()->arch ()) / 8;
 
   /* Put together the main packet, address and length.  */
   std::string request = string_printf ("QMemTags:%s,%s:%s:",
@@ -14796,7 +15236,7 @@ remote_target::fetch_memtags (CORE_ADDR address, size_t len,
                              gdb::byte_vector &tags, int type)
 {
   /* Make sure the qMemTags packet is supported.  */
-  if (!remote_memory_tagging_p ())
+  if (!m_features.remote_memory_tagging_p ())
     gdb_assert_not_reached ("remote fetch_memtags called with packet disabled");
 
   struct remote_state *rs = get_remote_state ();
@@ -14804,7 +15244,7 @@ remote_target::fetch_memtags (CORE_ADDR address, size_t len,
   create_fetch_memtags_request (rs->buf, address, len, type);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   return parse_fetch_memtags_reply (rs->buf, tags);
 }
@@ -14816,7 +15256,7 @@ remote_target::store_memtags (CORE_ADDR address, size_t len,
                              const gdb::byte_vector &tags, int type)
 {
   /* Make sure the QMemTags packet is supported.  */
-  if (!remote_memory_tagging_p ())
+  if (!m_features.remote_memory_tagging_p ())
     gdb_assert_not_reached ("remote store_memtags called with packet disabled");
 
   struct remote_state *rs = get_remote_state ();
@@ -14824,7 +15264,7 @@ remote_target::store_memtags (CORE_ADDR address, size_t len,
   create_store_memtags_request (rs->buf, address, len, type, tags);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
 
   /* Verify if the request was successful.  */
   return packet_check_result (rs->buf.data ()) == PACKET_OK;
@@ -14851,7 +15291,7 @@ test_memory_tagging_functions ()
   remote_target remote;
 
   struct packet_config *config
-    = &remote_protocol_packets[PACKET_memory_tagging_feature];
+    = &remote.m_features.m_protocol_packets[PACKET_memory_tagging_feature];
 
   scoped_restore restore_memtag_support_
     = make_scoped_restore (&config->support);
@@ -14931,15 +15371,13 @@ void _initialize_remote ();
 void
 _initialize_remote ()
 {
-  /* architecture specific data */
-  remote_g_packet_data_handle =
-    gdbarch_data_register_pre_init (remote_g_packet_data_init);
-
   add_target (remote_target_info, remote_target::open);
   add_target (extended_remote_target_info, extended_remote_target::open);
 
   /* Hook into new objfile notification.  */
   gdb::observers::new_objfile.attach (remote_new_objfile, "remote");
+  gdb::observers::all_objfiles_removed.attach
+    (remote_objfile_changed_check_symbols, "remote");
 
 #if 0
   init_remote_threadtests ();
@@ -15016,16 +15454,16 @@ Show the maximum number of bytes per memory write packet (deprecated)."),
 Set the maximum number of bytes per memory-write packet.\n\
 Specify the number of bytes in a packet or 0 (zero) for the\n\
 default packet size.  The actual limit is further reduced\n\
-dependent on the target.  Specify ``fixed'' to disable the\n\
-further restriction and ``limit'' to enable that restriction."),
+dependent on the target.  Specify \"fixed\" to disable the\n\
+further restriction and \"limit\" to enable that restriction."),
           &remote_set_cmdlist);
   add_cmd ("memory-read-packet-size", no_class,
           set_memory_read_packet_size, _("\
 Set the maximum number of bytes per memory-read packet.\n\
 Specify the number of bytes in a packet or 0 (zero) for the\n\
 default packet size.  The actual limit is further reduced\n\
-dependent on the target.  Specify ``fixed'' to disable the\n\
-further restriction and ``limit'' to enable that restriction."),
+dependent on the target.  Specify \"fixed\" to disable the\n\
+further restriction and \"limit\" to enable that restriction."),
           &remote_set_cmdlist);
   add_cmd ("memory-write-packet-size", no_class,
           show_memory_write_packet_size,
@@ -15070,257 +15508,221 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
 
   init_all_packet_configs ();
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_X],
-                        "X", "binary-download", 1);
+  add_packet_config_cmd (PACKET_X, "X", "binary-download", 1);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vCont],
-                        "vCont", "verbose-resume", 0);
+  add_packet_config_cmd (PACKET_vCont, "vCont", "verbose-resume", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QPassSignals],
-                        "QPassSignals", "pass-signals", 0);
+  add_packet_config_cmd (PACKET_QPassSignals, "QPassSignals", "pass-signals",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QCatchSyscalls],
-                        "QCatchSyscalls", "catch-syscalls", 0);
+  add_packet_config_cmd (PACKET_QCatchSyscalls, "QCatchSyscalls",
+                        "catch-syscalls", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QProgramSignals],
-                        "QProgramSignals", "program-signals", 0);
+  add_packet_config_cmd (PACKET_QProgramSignals, "QProgramSignals",
+                        "program-signals", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QSetWorkingDir],
-                        "QSetWorkingDir", "set-working-dir", 0);
+  add_packet_config_cmd (PACKET_QSetWorkingDir, "QSetWorkingDir",
+                        "set-working-dir", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QStartupWithShell],
-                        "QStartupWithShell", "startup-with-shell", 0);
+  add_packet_config_cmd (PACKET_QStartupWithShell, "QStartupWithShell",
+                        "startup-with-shell", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets
-                        [PACKET_QEnvironmentHexEncoded],
-                        "QEnvironmentHexEncoded", "environment-hex-encoded",
-                        0);
+  add_packet_config_cmd (PACKET_QEnvironmentHexEncoded,"QEnvironmentHexEncoded",
+                        "environment-hex-encoded", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QEnvironmentReset],
-                        "QEnvironmentReset", "environment-reset",
-                        0);
+  add_packet_config_cmd (PACKET_QEnvironmentReset, "QEnvironmentReset",
+                        "environment-reset", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QEnvironmentUnset],
-                        "QEnvironmentUnset", "environment-unset",
-                        0);
+  add_packet_config_cmd (PACKET_QEnvironmentUnset, "QEnvironmentUnset",
+                        "environment-unset", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qSymbol],
-                        "qSymbol", "symbol-lookup", 0);
+  add_packet_config_cmd (PACKET_qSymbol, "qSymbol", "symbol-lookup", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_P],
-                        "P", "set-register", 1);
+  add_packet_config_cmd (PACKET_P, "P", "set-register", 1);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_p],
-                        "p", "fetch-register", 1);
+  add_packet_config_cmd (PACKET_p, "p", "fetch-register", 1);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Z0],
-                        "Z0", "software-breakpoint", 0);
+  add_packet_config_cmd (PACKET_Z0, "Z0", "software-breakpoint", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Z1],
-                        "Z1", "hardware-breakpoint", 0);
+  add_packet_config_cmd (PACKET_Z1, "Z1", "hardware-breakpoint", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Z2],
-                        "Z2", "write-watchpoint", 0);
+  add_packet_config_cmd (PACKET_Z2, "Z2", "write-watchpoint", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Z3],
-                        "Z3", "read-watchpoint", 0);
+  add_packet_config_cmd (PACKET_Z3, "Z3", "read-watchpoint", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Z4],
-                        "Z4", "access-watchpoint", 0);
+  add_packet_config_cmd (PACKET_Z4, "Z4", "access-watchpoint", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_auxv],
-                        "qXfer:auxv:read", "read-aux-vector", 0);
+  add_packet_config_cmd (PACKET_qXfer_auxv, "qXfer:auxv:read",
+                        "read-aux-vector", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_exec_file],
-                        "qXfer:exec-file:read", "pid-to-exec-file", 0);
+  add_packet_config_cmd (PACKET_qXfer_exec_file, "qXfer:exec-file:read",
+                        "pid-to-exec-file", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_features],
+  add_packet_config_cmd (PACKET_qXfer_features,
                         "qXfer:features:read", "target-features", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_libraries],
-                        "qXfer:libraries:read", "library-info", 0);
+  add_packet_config_cmd (PACKET_qXfer_libraries, "qXfer:libraries:read",
+                        "library-info", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_libraries_svr4],
+  add_packet_config_cmd (PACKET_qXfer_libraries_svr4,
                         "qXfer:libraries-svr4:read", "library-info-svr4", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map],
-                        "qXfer:memory-map:read", "memory-map", 0);
+  add_packet_config_cmd (PACKET_qXfer_memory_map, "qXfer:memory-map:read",
+                        "memory-map", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_osdata],
-                       "qXfer:osdata:read", "osdata", 0);
+  add_packet_config_cmd (PACKET_qXfer_osdata, "qXfer:osdata:read", "osdata", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_threads],
-                        "qXfer:threads:read", "threads", 0);
+  add_packet_config_cmd (PACKET_qXfer_threads, "qXfer:threads:read", "threads",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_siginfo_read],
-                        "qXfer:siginfo:read", "read-siginfo-object", 0);
+  add_packet_config_cmd (PACKET_qXfer_siginfo_read, "qXfer:siginfo:read",
+                        "read-siginfo-object", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_siginfo_write],
-                        "qXfer:siginfo:write", "write-siginfo-object", 0);
+  add_packet_config_cmd (PACKET_qXfer_siginfo_write, "qXfer:siginfo:write",
+                        "write-siginfo-object", 0);
 
-  add_packet_config_cmd
-    (&remote_protocol_packets[PACKET_qXfer_traceframe_info],
-     "qXfer:traceframe-info:read", "traceframe-info", 0);
+  add_packet_config_cmd (PACKET_qXfer_traceframe_info,
+                        "qXfer:traceframe-info:read", "traceframe-info", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_uib],
-                        "qXfer:uib:read", "unwind-info-block", 0);
+  add_packet_config_cmd (PACKET_qXfer_uib, "qXfer:uib:read",
+                        "unwind-info-block", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
-                        "qGetTLSAddr", "get-thread-local-storage-address",
-                        0);
+  add_packet_config_cmd (PACKET_qGetTLSAddr, "qGetTLSAddr",
+                        "get-thread-local-storage-address", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTIBAddr],
-                        "qGetTIBAddr", "get-thread-information-block-address",
-                        0);
+  add_packet_config_cmd (PACKET_qGetTIBAddr, "qGetTIBAddr",
+                        "get-thread-information-block-address", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_bc],
-                        "bc", "reverse-continue", 0);
+  add_packet_config_cmd (PACKET_bc, "bc", "reverse-continue", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_bs],
-                        "bs", "reverse-step", 0);
+  add_packet_config_cmd (PACKET_bs, "bs", "reverse-step", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qSupported],
-                        "qSupported", "supported-packets", 0);
+  add_packet_config_cmd (PACKET_qSupported, "qSupported", "supported-packets",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qSearch_memory],
-                        "qSearch:memory", "search-memory", 0);
+  add_packet_config_cmd (PACKET_qSearch_memory, "qSearch:memory",
+                        "search-memory", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qTStatus],
-                        "qTStatus", "trace-status", 0);
+  add_packet_config_cmd (PACKET_qTStatus, "qTStatus", "trace-status", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_setfs],
-                        "vFile:setfs", "hostio-setfs", 0);
+  add_packet_config_cmd (PACKET_vFile_setfs, "vFile:setfs", "hostio-setfs", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_open],
-                        "vFile:open", "hostio-open", 0);
+  add_packet_config_cmd (PACKET_vFile_open, "vFile:open", "hostio-open", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_pread],
-                        "vFile:pread", "hostio-pread", 0);
+  add_packet_config_cmd (PACKET_vFile_pread, "vFile:pread", "hostio-pread", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_pwrite],
-                        "vFile:pwrite", "hostio-pwrite", 0);
+  add_packet_config_cmd (PACKET_vFile_pwrite, "vFile:pwrite", "hostio-pwrite",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_close],
-                        "vFile:close", "hostio-close", 0);
+  add_packet_config_cmd (PACKET_vFile_close, "vFile:close", "hostio-close", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_unlink],
-                        "vFile:unlink", "hostio-unlink", 0);
+  add_packet_config_cmd (PACKET_vFile_unlink, "vFile:unlink", "hostio-unlink",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_readlink],
-                        "vFile:readlink", "hostio-readlink", 0);
+  add_packet_config_cmd (PACKET_vFile_readlink, "vFile:readlink",
+                        "hostio-readlink", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_fstat],
-                        "vFile:fstat", "hostio-fstat", 0);
+  add_packet_config_cmd (PACKET_vFile_fstat, "vFile:fstat", "hostio-fstat", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
-                        "vAttach", "attach", 0);
+  add_packet_config_cmd (PACKET_vAttach, "vAttach", "attach", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vRun],
-                        "vRun", "run", 0);
+  add_packet_config_cmd (PACKET_vRun, "vRun", "run", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QStartNoAckMode],
-                        "QStartNoAckMode", "noack", 0);
+  add_packet_config_cmd (PACKET_QStartNoAckMode, "QStartNoAckMode", "noack", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vKill],
-                        "vKill", "kill", 0);
+  add_packet_config_cmd (PACKET_vKill, "vKill", "kill", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qAttached],
-                        "qAttached", "query-attached", 0);
+  add_packet_config_cmd (PACKET_qAttached, "qAttached", "query-attached", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_ConditionalTracepoints],
-                        "ConditionalTracepoints",
-                        "conditional-tracepoints", 0);
+  add_packet_config_cmd (PACKET_ConditionalTracepoints,
+                        "ConditionalTracepoints", "conditional-tracepoints",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_ConditionalBreakpoints],
-                        "ConditionalBreakpoints",
-                        "conditional-breakpoints", 0);
+  add_packet_config_cmd (PACKET_ConditionalBreakpoints,
+                        "ConditionalBreakpoints", "conditional-breakpoints",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_BreakpointCommands],
-                        "BreakpointCommands",
+  add_packet_config_cmd (PACKET_BreakpointCommands, "BreakpointCommands",
                         "breakpoint-commands", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
-                        "FastTracepoints", "fast-tracepoints", 0);
+  add_packet_config_cmd (PACKET_FastTracepoints, "FastTracepoints",
+                        "fast-tracepoints", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_TracepointSource],
-                        "TracepointSource", "TracepointSource", 0);
+  add_packet_config_cmd (PACKET_TracepointSource, "TracepointSource",
+                        "TracepointSource", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QAllow],
-                        "QAllow", "allow", 0);
+  add_packet_config_cmd (PACKET_QAllow, "QAllow", "allow", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_StaticTracepoints],
-                        "StaticTracepoints", "static-tracepoints", 0);
+  add_packet_config_cmd (PACKET_StaticTracepoints, "StaticTracepoints",
+                        "static-tracepoints", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_InstallInTrace],
-                        "InstallInTrace", "install-in-trace", 0);
+  add_packet_config_cmd (PACKET_InstallInTrace, "InstallInTrace",
+                        "install-in-trace", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_statictrace_read],
+  add_packet_config_cmd (PACKET_qXfer_statictrace_read,
                         "qXfer:statictrace:read", "read-sdata-object", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_fdpic],
-                        "qXfer:fdpic:read", "read-fdpic-loadmap", 0);
+  add_packet_config_cmd (PACKET_qXfer_fdpic, "qXfer:fdpic:read",
+                        "read-fdpic-loadmap", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QDisableRandomization],
-                        "QDisableRandomization", "disable-randomization", 0);
+  add_packet_config_cmd (PACKET_QDisableRandomization, "QDisableRandomization",
+                        "disable-randomization", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
-                        "QAgent", "agent", 0);
+  add_packet_config_cmd (PACKET_QAgent, "QAgent", "agent", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QTBuffer_size],
-                        "QTBuffer:size", "trace-buffer-size", 0);
+  add_packet_config_cmd (PACKET_QTBuffer_size, "QTBuffer:size",
+                        "trace-buffer-size", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_off],
-       "Qbtrace:off", "disable-btrace", 0);
+  add_packet_config_cmd (PACKET_Qbtrace_off, "Qbtrace:off", "disable-btrace",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_bts],
-       "Qbtrace:bts", "enable-btrace-bts", 0);
+  add_packet_config_cmd (PACKET_Qbtrace_bts, "Qbtrace:bts", "enable-btrace-bts",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_pt],
-       "Qbtrace:pt", "enable-btrace-pt", 0);
+  add_packet_config_cmd (PACKET_Qbtrace_pt, "Qbtrace:pt", "enable-btrace-pt",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
-       "qXfer:btrace", "read-btrace", 0);
+  add_packet_config_cmd (PACKET_qXfer_btrace, "qXfer:btrace", "read-btrace", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace_conf],
-       "qXfer:btrace-conf", "read-btrace-conf", 0);
+  add_packet_config_cmd (PACKET_qXfer_btrace_conf, "qXfer:btrace-conf",
+                        "read-btrace-conf", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_bts_size],
-       "Qbtrace-conf:bts:size", "btrace-conf-bts-size", 0);
+  add_packet_config_cmd (PACKET_Qbtrace_conf_bts_size, "Qbtrace-conf:bts:size",
+                        "btrace-conf-bts-size", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_multiprocess_feature],
-       "multiprocess-feature", "multiprocess-feature", 0);
+  add_packet_config_cmd (PACKET_multiprocess_feature, "multiprocess-feature",
+                        "multiprocess-feature", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_swbreak_feature],
-                        "swbreak-feature", "swbreak-feature", 0);
+  add_packet_config_cmd (PACKET_swbreak_feature, "swbreak-feature",
+                        "swbreak-feature", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_hwbreak_feature],
-                        "hwbreak-feature", "hwbreak-feature", 0);
+  add_packet_config_cmd (PACKET_hwbreak_feature, "hwbreak-feature",
+                        "hwbreak-feature", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_fork_event_feature],
-                        "fork-event-feature", "fork-event-feature", 0);
+  add_packet_config_cmd (PACKET_fork_event_feature, "fork-event-feature",
+                        "fork-event-feature", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vfork_event_feature],
-                        "vfork-event-feature", "vfork-event-feature", 0);
+  add_packet_config_cmd (PACKET_vfork_event_feature, "vfork-event-feature",
+                        "vfork-event-feature", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_pt_size],
-       "Qbtrace-conf:pt:size", "btrace-conf-pt-size", 0);
+  add_packet_config_cmd (PACKET_Qbtrace_conf_pt_size, "Qbtrace-conf:pt:size",
+                        "btrace-conf-pt-size", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vContSupported],
-                        "vContSupported", "verbose-resume-supported", 0);
+  add_packet_config_cmd (PACKET_vContSupported, "vContSupported",
+                        "verbose-resume-supported", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_exec_event_feature],
-                        "exec-event-feature", "exec-event-feature", 0);
+  add_packet_config_cmd (PACKET_exec_event_feature, "exec-event-feature",
+                        "exec-event-feature", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_vCtrlC],
-                        "vCtrlC", "ctrl-c", 0);
+  add_packet_config_cmd (PACKET_vCtrlC, "vCtrlC", "ctrl-c", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_QThreadEvents],
-                        "QThreadEvents", "thread-events", 0);
+  add_packet_config_cmd (PACKET_QThreadEvents, "QThreadEvents", "thread-events",
+                        0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_no_resumed],
-                        "N stop reply", "no-resumed-stop-reply", 0);
+  add_packet_config_cmd (PACKET_no_resumed, "N stop reply",
+                        "no-resumed-stop-reply", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_memory_tagging_feature],
+  add_packet_config_cmd (PACKET_memory_tagging_feature,
                         "memory-tagging-feature", "memory-tagging-feature", 0);
 
   /* Assert that we've registered "set remote foo-packet" commands
@@ -15353,7 +15755,7 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
 
        /* This catches both forgetting to add a config command, and
           forgetting to remove a packet from the exception list.  */
-       gdb_assert (excepted == (remote_protocol_packets[i].name == NULL));
+       gdb_assert (excepted == (packets_descriptions[i].name == NULL));
       }
   }