gdb: remove interp_pre_command_loop
[binutils-gdb.git] / gdb / remote.c
index 49ed209921172f383e4cc7d6cdb62c9519dc7cc6..6fb3a015967fff7b6977eb9eb58d6967408b8158 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;
@@ -258,15 +433,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 +451,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.  */
@@ -388,7 +551,7 @@ 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:
   /* Mapping of remote protocol data for each gdbarch.  Usually there
@@ -400,10 +563,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 +722,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 *,
@@ -493,14 +778,14 @@ public:
 
   const char *extra_thread_info (struct thread_info *) override;
 
-  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+  ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
 
   thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
                                             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 +804,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 +833,7 @@ public:
 
   bool is_async_p () override;
 
-  void async (int) override;
+  void async (bool) override;
 
   int async_wait_fd () override;
 
@@ -571,33 +856,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;
@@ -669,8 +962,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 +1005,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 +1041,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);
@@ -762,21 +1055,22 @@ public: /* Remote specific methods.  */
                             target_waitstatus *status);
 
   ptid_t select_thread_for_ambiguous_stop_reply
-    (const struct target_waitstatus *status);
+    (const struct target_waitstatus &status);
 
   void remote_notice_new_inferior (ptid_t currthread, bool executing);
 
   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 +1149,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 +1213,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,22 +1233,24 @@ 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 ();
 
-  void packet_command (const char *args, int from_tty);
+  remote_features m_features;
 
-private: /* data fields */
+private:
+
+  bool start_remote_1 (int from_tty, int extended_p);
 
   /* The remote state.  Don't reference this directly.  Use the
      get_remote_state method instead.  */
@@ -967,7 +1259,7 @@ private: /* data fields */
 
 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
 };
 
@@ -996,31 +1288,77 @@ public:
   bool supports_disable_randomization () override;
 };
 
-/* Per-program-space data key.  */
-static const struct program_space_key<char, gdb::xfree_deleter<char>>
-  remote_pspace_data;
+struct stop_reply : public notif_event
+{
+  ~stop_reply ();
 
-/* 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 
-   location of the remote exec-file value.  */
-static char *remote_exec_file_var;
+  /* The identifier of the thread about this event  */
+  ptid_t ptid;
 
-/* The size to align memory write packets, when practical.  The protocol
-   does not guarantee any alignment, and gdb will generate short
-   writes and unaligned writes, but even as a best-effort attempt this
-   can improve bulk transfers.  For instance, if a write is misaligned
-   relative to the target's data bus, the stub may need to make an extra
-   round trip fetching data from the target.  This doesn't make a
-   huge difference, but it's easy to do, so we try to be helpful.
+  /* The remote state this event is associated with.  When the remote
+     connection, represented by a remote_state object, is closed,
+     all the associated stop_reply events should be released.  */
+  struct remote_state *rs;
 
-   The alignment chosen is arbitrary; usually data bus width is
-   important here, not the possibly larger cache line size.  */
-enum { REMOTE_ALIGN_WRITES = 16 };
+  struct target_waitstatus ws;
 
-/* Prototypes for local functions.  */
+  /* The architecture associated with the expedited registers.  */
+  gdbarch *arch;
 
-static int hexnumlen (ULONGEST num);
+  /* Expedited registers.  This makes remote debugging a bit more
+     efficient for those targets that provide critical registers as
+     part of their normal status mechanism (as another roundtrip to
+     fetch them is avoided).  */
+  std::vector<cached_reg_t> regcache;
+
+  enum target_stop_reason stop_reason;
+
+  CORE_ADDR watch_data_address;
+
+  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)
+{
+  return as_remote_target (target) != nullptr;
+}
+
+/* Per-program-space data key.  */
+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 
+   location of the remote exec-file value.  */
+static std::string remote_exec_file_var;
+
+/* The size to align memory write packets, when practical.  The protocol
+   does not guarantee any alignment, and gdb will generate short
+   writes and unaligned writes, but even as a best-effort attempt this
+   can improve bulk transfers.  For instance, if a write is misaligned
+   relative to the target's data bus, the stub may need to make an extra
+   round trip fetching data from the target.  This doesn't make a
+   huge difference, but it's easy to do, so we try to be helpful.
+
+   The alignment chosen is arbitrary; usually data bus width is
+   important here, not the possibly larger cache line size.  */
+enum { REMOTE_ALIGN_WRITES = 16 };
+
+/* Prototypes for local functions.  */
+
+static int hexnumlen (ULONGEST num);
 
 static int stubhex (int ch);
 
@@ -1030,13 +1368,14 @@ static int hexnumnstr (char *, ULONGEST, int);
 
 static CORE_ADDR remote_address_masked (CORE_ADDR);
 
-static void print_packet (const char *);
-
 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,
@@ -1219,7 +1558,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);
@@ -1355,8 +1694,8 @@ static void
 set_remote_exec_file (const char *ignored, int from_tty,
                      struct cmd_list_element *c)
 {
-  gdb_assert (remote_exec_file_var != NULL);
-  set_pspace_remote_exec_file (current_program_space, remote_exec_file_var);
+  set_pspace_remote_exec_file (current_program_space,
+                              remote_exec_file_var.c_str ());
 }
 
 /* The "set/show remote exec-file" show command hook.  */
@@ -1365,7 +1704,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
@@ -1547,22 +1886,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);
 }
 
@@ -1607,21 +1945,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
@@ -1687,13 +2010,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;
@@ -1721,55 +2045,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.  */
@@ -1779,8 +2138,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.  */
@@ -1790,8 +2149,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.  */
@@ -1801,8 +2160,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
@@ -1818,38 +2177,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
@@ -1859,31 +2234,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;
-
-    /* Does the target support this packet?  */
-    enum packet_support support;
-  };
 
-static enum packet_support packet_config_support (struct packet_config *config);
-static enum packet_support packet_support (int packet);
+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 ());
+
+  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)
+    {
+      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;
+
+      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))
     {
@@ -1900,57 +2296,63 @@ 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)
 {
-  char *set_doc;
-  char *show_doc;
-  char *cmd_name;
-
-  config->name = name;
-  config->title = title;
-  set_doc = xstrprintf ("Set use of remote protocol `%s' (%s) packet.",
-                       name, title);
-  show_doc = xstrprintf ("Show current use of remote "
-                        "protocol `%s' (%s) packet.",
-                        name, 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);
+  gdb::unique_xmalloc_ptr<char> show_doc
+    = xstrprintf ("Show current use of remote protocol `%s' (%s) packet.",
+                 name, title);
   /* set/show TITLE-packet {auto,on,off} */
-  cmd_name = xstrprintf ("%s-packet", title);
+  gdb::unique_xmalloc_ptr<char> cmd_name = xstrprintf ("%s-packet", title);
   set_show_commands cmds
-    = add_setshow_auto_boolean_cmd (cmd_name, class_obscure,
-                                   &config->detect, set_doc,
-                                   show_doc, NULL, /* help_doc */
-                                   NULL,
+    = add_setshow_auto_boolean_cmd (cmd_name.release (), class_obscure,
+                                   &config->detect, set_doc.get (),
+                                   show_doc.get (), NULL, /* help_doc */
+                                   set_remote_protocol_packet_cmd,
                                    show_remote_protocol_packet_cmd,
                                    &remote_set_cmdlist, &remote_show_cmdlist);
-
-  /* The command code copies the documentation strings.  */
-  xfree (set_doc);
-  xfree (show_doc);
+  cmds.show->set_context (config);
+  cmds.set->set_context (config);
 
   /* set/show remote NAME-packet {auto,on,off} -- legacy.  */
   if (legacy)
     {
-      char *legacy_name;
-
-      legacy_name = xstrprintf ("%s-packet", name);
-      add_alias_cmd (legacy_name, cmds.set, class_obscure, 0,
+      /* 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, cmds.show, class_obscure, 0,
+      add_alias_cmd (legacy_name.get (), cmds.show, class_obscure, 0,
                     &remote_show_cmdlist);
+      legacy_names.emplace_back (std::move (legacy_name));
     }
 }
 
@@ -1972,234 +2374,75 @@ packet_check_result (const char *buf)
       if (buf[0] == 'E' && buf[1] == '.')
        return PACKET_ERROR;
 
-      /* The packet may or may not be OK.  Just assume it is.  */
-      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 packet may or may not be OK.  Just assume it is.  */
+      return PACKET_OK;
+    }
+  else
+    /* 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
@@ -2207,7 +2450,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)
     {
@@ -2218,18 +2461,14 @@ packet_config_support (struct packet_config *config)
     case AUTO_BOOLEAN_AUTO:
       return config->support;
     default:
-      gdb_assert_not_reached (_("bad switch"));
+      gdb_assert_not_reached ("bad switch");
     }
 }
 
-/* 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);
 }
 
@@ -2238,20 +2477,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 (&packet->detect == c->var)
-       {
-         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?  */
@@ -2275,10 +2513,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
@@ -2286,52 +2537,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
@@ -2340,9 +2550,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
@@ -2360,9 +2568,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
@@ -2380,9 +2586,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
@@ -2411,19 +2615,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)
@@ -2523,10 +2726,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;
@@ -2537,7 +2743,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);
@@ -2570,12 +2776,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;
     }
 
@@ -2597,7 +2803,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;
@@ -2620,8 +2826,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);
@@ -2629,7 +2834,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
@@ -2655,7 +2860,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.  */
@@ -2663,7 +2868,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);
 }
 
@@ -2684,7 +2889,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;
@@ -2717,8 +2922,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;
        }
@@ -2738,7 +2943,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;
@@ -2790,8 +2995,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
@@ -2804,7 +3009,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;
@@ -2838,8 +3043,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;
        }
@@ -2874,7 +3079,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
@@ -2905,12 +3110,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 ())
@@ -2958,7 +3163,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');
 }
 
@@ -2985,7 +3190,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.  */
@@ -3060,9 +3265,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)
@@ -3115,14 +3319,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;
@@ -3458,7 +3663,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;
@@ -3532,7 +3737,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.  */
@@ -3719,7 +3924,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;
@@ -3823,7 +4028,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);
@@ -3853,7 +4058,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 */
        {
@@ -3866,7 +4071,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;
@@ -3963,7 +4168,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);
@@ -4001,8 +4206,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))
@@ -4016,7 +4220,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,
@@ -4034,7 +4238,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);
@@ -4082,7 +4286,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')
@@ -4108,7 +4312,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);
@@ -4125,7 +4329,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 ();
     }
 
@@ -4136,7 +4340,7 @@ remote_target::static_tracepoint_markers_by_strid (const char *strid)
 /* Implement the to_get_ada_task_ptid function for the remote targets.  */
 
 ptid_t
-remote_target::get_ada_task_ptid (long lwp, long thread)
+remote_target::get_ada_task_ptid (long lwp, ULONGEST thread)
 {
   return ptid_t (inferior_ptid.pid (), lwp);
 }
@@ -4206,7 +4410,7 @@ remote_target::get_offsets ()
     return;
 
   putpkt ("qOffsets");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf);
   buf = rs->buf.data ();
 
   if (buf[0] == '\000')
@@ -4281,7 +4485,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;
 
@@ -4316,7 +4520,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);
 
@@ -4361,8 +4565,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);
 }
 
@@ -4442,7 +4645,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 ();
@@ -4453,7 +4655,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
@@ -4496,8 +4698,7 @@ remote_target::print_one_stopped_thread (thread_info *thread)
     }
   else
     {
-      ws.kind = TARGET_WAITKIND_STOPPED;
-      ws.value.sig = GDB_SIGNAL_0;
+      ws.set_stopped (GDB_SIGNAL_0);
     }
 
   switch_to_thread (thread);
@@ -4507,14 +4708,15 @@ remote_target::print_one_stopped_thread (thread_info *thread)
   /* For "info program".  */
   set_last_target_status (this, thread->ptid, ws);
 
-  if (ws.kind == TARGET_WAITKIND_STOPPED)
+  if (ws.kind () == TARGET_WAITKIND_STOPPED)
     {
-      enum gdb_signal sig = ws.value.sig;
+      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
@@ -4541,12 +4743,11 @@ remote_target::process_initial_stop_replies (int from_tty)
       struct target_waitstatus ws;
       int ignore_event = 0;
 
-      memset (&ws, 0, sizeof (ws));
       event_ptid = target_wait (waiton_ptid, &ws, TARGET_WNOHANG);
       if (remote_debug)
-       print_target_wait_results (waiton_ptid, event_ptid, &ws);
+       print_target_wait_results (waiton_ptid, event_ptid, ws);
 
-      switch (ws.kind)
+      switch (ws.kind ())
        {
        case TARGET_WAITKIND_IGNORE:
        case TARGET_WAITKIND_NO_RESUMED:
@@ -4557,9 +4758,6 @@ remote_target::process_initial_stop_replies (int from_tty)
          ignore_event = 1;
          break;
 
-       case TARGET_WAITKIND_EXECD:
-         xfree (ws.value.execd_pathname);
-         break;
        default:
          break;
        }
@@ -4567,22 +4765,22 @@ 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)
+      if (ws.kind () == TARGET_WAITKIND_STOPPED)
        {
-         enum gdb_signal sig = ws.value.sig;
+         enum gdb_signal sig = ws.sig ();
 
          /* Stubs traditionally report SIGTRAP as initial signal,
             instead of signal 0.  Suppress it.  */
          if (sig == GDB_SIGNAL_TRAP)
            sig = GDB_SIGNAL_0;
          evthread->set_stop_signal (sig);
-         ws.value.sig = sig;
+         ws.set_stopped (sig);
        }
 
-      if (ws.kind != TARGET_WAITKIND_STOPPED
-         || ws.value.sig != GDB_SIGNAL_0)
+      if (ws.kind () != TARGET_WAITKIND_STOPPED
+         || ws.sig () != GDB_SIGNAL_0)
        evthread->set_pending_waitstatus (ws);
 
       set_executing (this, event_ptid, false);
@@ -4594,7 +4792,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)
        {
@@ -4609,7 +4807,15 @@ remote_target::process_initial_stop_replies (int from_tty)
      the inferiors.  */
   if (!non_stop)
     {
-      stop_all_threads ();
+      {
+       /* At this point, the remote target is not async.  It needs to be for
+          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 (false); };
+       target_async (true);
+       stop_all_threads ("remote connect in all-stop");
+      }
 
       /* If all threads of an inferior were already stopped, we
         haven't setup the inferior yet.  */
@@ -4663,15 +4869,55 @@ remote_target::process_initial_stop_replies (int from_tty)
     }
 }
 
-/* Start the remote connection and sync state.  */
+/* 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.  */
 
-void
-remote_target::start_remote (int from_tty, int extended_p)
+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 (remote_target_ref::new_reference (target)),
+      m_restore_starting_up (set_starting_up_flag (target))
+  { /* Nothing.  */ }
+
+private:
+
+  /* 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 = target->get_remote_state ();
+    gdb_assert (!rs->starting_up);
+    return make_scoped_restore (&rs->starting_up, true);
+  }
+
+  /* A gdb::ref_ptr pointer to a remote_target.  */
+  using remote_target_ref = gdb::ref_ptr<remote_target, target_ops_ref_policy>;
+
+  /* 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
+   sync state.  Return true if everything goes OK, otherwise, return false.
+   This function exists so that the scoped_restore created within it will
+   expire before we return to remote_target::start_remote.  */
+
+bool
+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
@@ -4679,7 +4925,7 @@ remote_target::start_remote (int from_tty, int extended_p)
      Ctrl-C before we're connected and synced up can't interrupt the
      target.  Instead, it offers to drop the (potentially wedged)
      connection.  */
-  rs->starting_up = true;
+  scoped_mark_target_starting target_is_starting (this);
 
   QUIT;
 
@@ -4694,8 +4940,12 @@ remote_target::start_remote (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
@@ -4709,9 +4959,12 @@ remote_target::start_remote (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 ());
@@ -4730,12 +4983,11 @@ remote_target::start_remote (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;
     }
 
@@ -4743,7 +4995,7 @@ remote_target::start_remote (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
@@ -4765,12 +5017,12 @@ remote_target::start_remote (int from_tty, int extended_p)
 
   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"),
@@ -4782,12 +5034,12 @@ remote_target::start_remote (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"),
@@ -4807,7 +5059,7 @@ remote_target::start_remote (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 ())
     {
@@ -4817,11 +5069,7 @@ remote_target::start_remote (int from_tty, int extended_p)
        {
          if (!extended_p)
            error (_("The target is not running (try extended-remote?)"));
-
-         /* We're connected, but not running.  Drop out before we
-            call start_remote.  */
-         rs->starting_up = false;
-         return;
+         return false;
        }
       else
        {
@@ -4869,7 +5117,7 @@ remote_target::start_remote (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
@@ -4898,8 +5146,9 @@ remote_target::start_remote (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.  */
     }
@@ -4919,7 +5168,7 @@ remote_target::start_remote (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.  */
@@ -4932,11 +5181,7 @@ remote_target::start_remote (int from_tty, int extended_p)
        {
          if (!extended_p)
            error (_("The target is not running (try extended-remote?)"));
-
-         /* We're connected, but not running.  Drop out before we
-            call start_remote.  */
-         rs->starting_up = false;
-         return;
+         return false;
        }
 
       /* Report all signals during attach/startup.  */
@@ -4947,15 +5192,27 @@ remote_target::start_remote (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
@@ -4965,7 +5222,7 @@ remote_target::start_remote (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);
 
@@ -4976,14 +5233,16 @@ remote_target::start_remote (int from_tty, int extended_p)
      previously; find out where things are at.  */
   remote_btrace_maybe_reopen ();
 
-  /* The thread and inferior lists are now synchronized with the
-     target, our symbols have been relocated, and we're merged the
-     target's tracepoints with ours.  We're done with basic start
-     up.  */
-  rs->starting_up = false;
+  return true;
+}
+
+/* Start the remote connection and sync state.  */
 
-  /* Maybe breakpoints are global and need to be inserted now.  */
-  if (breakpoints_should_be_inserted_now ())
+void
+remote_target::start_remote (int from_tty, int extended_p)
+{
+  if (start_remote_1 (from_tty, extended_p)
+      && breakpoints_should_be_inserted_now ())
     insert_breakpoints ();
 }
 
@@ -5016,16 +5275,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.  */
@@ -5050,15 +5306,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
@@ -5073,8 +5326,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:"))
     {
@@ -5091,7 +5344,7 @@ remote_target::remote_check_symbols ()
       else
        {
          int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
-         CORE_ADDR sym_addr = BMSYMBOL_VALUE_ADDRESS (sym);
+         CORE_ADDR sym_addr = sym.value_address ();
 
          /* If this is a function address, return the start of code
             instead of any data function descriptor.  */
@@ -5103,7 +5356,7 @@ remote_target::remote_check_symbols ()
        }
 
       putpkt (msg.data ());
-      getpkt (&reply, 0);
+      getpkt (&reply);
     }
 }
 
@@ -5149,7 +5402,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.  */
@@ -5198,7 +5451,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
@@ -5406,58 +5659,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;
@@ -5633,7 +5895,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 ();
     }
 
@@ -5679,7 +5941,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
 
   remote_fileio_reset ();
   reopen_exec_file ();
-  reread_symbols ();
+  reread_symbols (from_tty);
 
   remote_target *remote
     = (extended_p ? new extended_remote_target () : new remote_target ());
@@ -5689,7 +5951,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)
@@ -5718,9 +5980,9 @@ 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.  */
@@ -5734,8 +5996,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
 
   /* 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;
@@ -5764,7 +6025,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.  */
@@ -5804,7 +6065,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 WS represents a fork status.  */
+
+static bool
+is_fork_status (target_waitkind kind)
+{
+  return (kind == TARGET_WAITKIND_FORKED
+         || kind == TARGET_WAITKIND_VFORKED);
+}
+
+/* Return THREAD's pending status if it is a pending fork parent, else
+   return nullptr.  */
+
+static const target_waitstatus *
+thread_pending_fork_status (struct thread_info *thread)
+{
+  const target_waitstatus &ws
+    = (thread->has_pending_waitstatus ()
+       ? thread->pending_waitstatus ()
+       : thread->pending_follow);
+
+  if (!is_fork_status (ws.kind ()))
+    return nullptr;
+
+  return &ws;
 }
 
 /* Detach the specified process.  */
@@ -5822,13 +6109,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')
     ;
@@ -5871,14 +6158,40 @@ 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 ());
+    }
+
+  /* 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 = find_thread_ptid (this, inferior_ptid);
+  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.  */
   is_fork_parent = (tp != NULL
-                   && tp->pending_follow.kind == TARGET_WAITKIND_FORKED);
+                   && tp->pending_follow.kind () == TARGET_WAITKIND_FORKED);
 
   /* If doing detach-on-fork, we don't mourn, because that will delete
      breakpoints that should be available for the followed inferior.  */
@@ -5890,8 +6203,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
     {
@@ -5927,10 +6240,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
@@ -5978,7 +6291,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,
@@ -5996,27 +6309,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 ())
@@ -6059,14 +6361,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
@@ -6078,28 +6377,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);
     }
 }
 
@@ -6132,7 +6419,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.  */
@@ -6172,8 +6459,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
@@ -6182,9 +6468,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,
@@ -6203,7 +6488,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;
 
@@ -6211,10 +6496,10 @@ 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)
@@ -6237,7 +6522,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;
 
@@ -6321,9 +6606,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");
@@ -6341,18 +6626,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 ();
@@ -6363,10 +6645,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 ();
@@ -6378,7 +6657,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
@@ -6386,7 +6665,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
@@ -6400,15 +6679,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 ());
@@ -6419,7 +6698,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 ());
@@ -6431,7 +6710,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 ();
 
@@ -6444,18 +6723,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;
     }
 
@@ -6471,23 +6752,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
@@ -6499,8 +6770,6 @@ remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
     rs->waiting_for_stop_reply = 1;
 }
 
-static int is_pending_fork_parent_thread (struct thread_info *thread);
-
 /* Private per-inferior info for target remote processes.  */
 
 struct remote_inferior : public private_inferior
@@ -6511,44 +6780,14 @@ struct remote_inferior : public private_inferior
 
 /* Get the remote private inferior data associated to INF.  */
 
-static remote_inferior *
-get_remote_inferior (inferior *inf)
-{
-  if (inf->priv == NULL)
-    inf->priv.reset (new remote_inferior);
-
-  return static_cast<remote_inferior *> (inf->priv.get ());
-}
-
-struct stop_reply : public notif_event
-{
-  ~stop_reply ();
-
-  /* The identifier of the thread about this event  */
-  ptid_t ptid;
-
-  /* The remote state this event is associated with.  When the remote
-     connection, represented by a remote_state object, is closed,
-     all the associated stop_reply events should be released.  */
-  struct remote_state *rs;
-
-  struct target_waitstatus ws;
-
-  /* The architecture associated with the expedited registers.  */
-  gdbarch *arch;
-
-  /* Expedited registers.  This makes remote debugging a bit more
-     efficient for those targets that provide critical registers as
-     part of their normal status mechanism (as another roundtrip to
-     fetch them is avoided).  */
-  std::vector<cached_reg_t> regcache;
-
-  enum target_stop_reason stop_reason;
-
-  CORE_ADDR watch_data_address;
+static remote_inferior *
+get_remote_inferior (inferior *inf)
+{
+  if (inf->priv == NULL)
+    inf->priv.reset (new remote_inferior);
 
-  int core;
-};
+  return gdb::checked_static_cast<remote_inferior *> (inf->priv.get ());
+}
 
 /* Class used to track the construction of a vCont packet in the
    outgoing packet buffer.  This is used to send multiple vCont
@@ -6609,7 +6848,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 ());
 }
@@ -6750,7 +6989,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;
     }
 
@@ -6780,7 +7019,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)
@@ -6790,7 +7029,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);
@@ -6907,8 +7146,9 @@ remote_target::remote_stop_ns (ptid_t ptid)
            == resume_state::RESUMED_PENDING_VCONT)
          {
            remote_debug_printf ("Enqueueing phony stop reply for thread pending "
-                                "vCont-resume (%d, %ld, %ld)", tp->ptid.pid(),
-                                tp->ptid.lwp (), tp->ptid.tid ());
+                                "vCont-resume (%d, %ld, %s)", tp->ptid.pid(),
+                                tp->ptid.lwp (),
+                                pulongest (tp->ptid.tid ()));
 
            /* Check that the thread wasn't resumed with a signal.
               Generating a phony stop would result in losing the
@@ -6920,8 +7160,7 @@ remote_target::remote_stop_ns (ptid_t ptid)
            stop_reply *sr = new stop_reply ();
            sr->ptid = tp->ptid;
            sr->rs = rs;
-           sr->ws.kind = TARGET_WAITKIND_STOPPED;
-           sr->ws.value.sig = GDB_SIGNAL_0;
+           sr->ws.set_stopped (GDB_SIGNAL_0);
            sr->arch = tp->inf->gdbarch;
            sr->stop_reason = TARGET_STOPPED_BY_NO_REASON;
            sr->watch_data_address = 0;
@@ -6939,17 +7178,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
     {
@@ -6977,7 +7210,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 ());
@@ -6995,9 +7228,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.  */
@@ -7021,9 +7254,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;
@@ -7154,7 +7387,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);
@@ -7162,7 +7395,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;
@@ -7173,13 +7406,13 @@ remote_notif_stop_ack (remote_target *remote,
   /* Kind can be TARGET_WAITKIND_IGNORE if we have meanwhile discarded
      the notification.  It was left in the queue because we need to
      acknowledge it and pull the rest of the notifications out.  */
-  if (stop_reply->ws.kind != TARGET_WAITKIND_IGNORE)
+  if (stop_reply->ws.kind () != TARGET_WAITKIND_IGNORE)
     remote->push_stop_reply (stop_reply);
 }
 
 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
@@ -7205,7 +7438,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",
@@ -7216,47 +7449,6 @@ struct notif_client notif_client_stop =
   REMOTE_NOTIF_STOP,
 };
 
-/* 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.  */
-
-static int
-is_pending_fork_parent (const target_waitstatus *ws, int event_pid,
-                       ptid_t thread_ptid)
-{
-  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 the thread's pending status used to determine whether the
-   thread is a fork parent stopped at a fork event.  */
-
-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.  */
-
-static int
-is_pending_fork_parent_thread (struct thread_info *thread)
-{
-  const target_waitstatus *ws = thread_pending_fork_status (thread);
-  int pid = -1;
-
-  return is_pending_fork_parent (ws, pid, thread->ptid);
-}
-
 /* If CONTEXT contains any fork child threads that have not been
    reported yet, remove them from the CONTEXT list.  If such a
    thread exists it is because we are stopped at a fork catchpoint
@@ -7266,8 +7458,7 @@ is_pending_fork_parent_thread (struct thread_info *thread)
 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.  */
@@ -7275,8 +7466,10 @@ remote_target::remove_new_fork_children (threads_listing_context *context)
     {
       const target_waitstatus *ws = thread_pending_fork_status (thread);
 
-      if (is_pending_fork_parent (ws, pid, thread->ptid))
-       context->remove_thread (ws->value.related_pid);
+      if (ws == nullptr)
+       continue;
+
+      context->remove_thread (ws->child_ptid ());
     }
 
   /* Check for any pending fork events (not reported or processed yet)
@@ -7284,10 +7477,11 @@ remote_target::remove_new_fork_children (threads_listing_context *context)
      CONTEXT list as well.  */
   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)
-      context->remove_thread (event->ws.value.related_pid);
+    if (event->ws.kind () == TARGET_WAITKIND_FORKED
+       || 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
@@ -7300,17 +7494,17 @@ 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)
     {
-      if (event->ws.kind == TARGET_WAITKIND_NO_RESUMED
-         || event->ws.kind == TARGET_WAITKIND_NO_HISTORY)
+      if (event->ws.kind () == TARGET_WAITKIND_NO_RESUMED
+         || event->ws.kind () == TARGET_WAITKIND_NO_HISTORY)
        continue;
 
-      if (event->ws.kind == TARGET_WAITKIND_FORKED
-         || event->ws.kind == TARGET_WAITKIND_VFORKED)
+      if (event->ws.kind () == TARGET_WAITKIND_FORKED
+         || event->ws.kind () == TARGET_WAITKIND_VFORKED)
        *may_global_wildcard = false;
 
       /* This may be the first time we heard about this process.
@@ -7348,11 +7542,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.  */
-      reply->ws.kind = TARGET_WAITKIND_IGNORE;
-
-      if (remote_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "discarded in-flight notification\n");
+      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 ();
     }
 
   /* Discard the stop replies we have already pulled with
@@ -7363,6 +7557,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 ());
 }
 
@@ -7408,9 +7607,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;
 }
@@ -7426,7 +7625,7 @@ 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);
@@ -7446,12 +7645,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 ())
+    mark_async_event_handler (rs->remote_async_inferior_event_token);
 }
 
 /* Returns true if we have a stop reply for PTID.  */
@@ -7462,7 +7666,7 @@ remote_target::peek_stop_reply (ptid_t ptid)
   remote_state *rs = get_remote_state ();
   for (auto &event : rs->stop_reply_queue)
     if (ptid == event->ptid
-       && event->ws.kind == TARGET_WAITKIND_STOPPED)
+       && event->ws.kind () == TARGET_WAITKIND_STOPPED)
       return 1;
   return 0;
 }
@@ -7492,8 +7696,7 @@ remote_target::remote_parse_stop_reply (const char *buf, stop_reply *event)
 
   event->ptid = null_ptid;
   event->rs = get_remote_state ();
-  event->ws.kind = TARGET_WAITKIND_IGNORE;
-  event->ws.value.integer = 0;
+  event->ws.set_ignore ();
   event->stop_reason = TARGET_STOPPED_BY_NO_REASON;
   event->regcache.clear ();
   event->core = -1;
@@ -7537,17 +7740,15 @@ Packet: '%s'\n"),
            {
              ULONGEST sysno;
 
-             event->ws.kind = TARGET_WAITKIND_SYSCALL_ENTRY;
              p = unpack_varlen_hex (++p1, &sysno);
-             event->ws.value.syscall_number = (int) sysno;
+             event->ws.set_syscall_entry ((int) sysno);
            }
          else if (strprefix (p, p1, "syscall_return"))
            {
              ULONGEST sysno;
 
-             event->ws.kind = TARGET_WAITKIND_SYSCALL_RETURN;
              p = unpack_varlen_hex (++p1, &sysno);
-             event->ws.value.syscall_number = (int) sysno;
+             event->ws.set_syscall_return ((int) sysno);
            }
          else if (strprefix (p, p1, "watch")
                   || strprefix (p, p1, "rwatch")
@@ -7563,7 +7764,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",
@@ -7577,7 +7779,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.  */
@@ -7585,12 +7788,12 @@ Packet: '%s'\n"),
            }
          else if (strprefix (p, p1, "library"))
            {
-             event->ws.kind = TARGET_WAITKIND_LOADED;
+             event->ws.set_loaded ();
              p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "replaylog"))
            {
-             event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
+             event->ws.set_no_history ();
              /* p1 will indicate "begin" or "end", but it makes
                 no difference for now, so ignore it.  */
              p = strchrnul (p1 + 1, ';');
@@ -7603,18 +7806,12 @@ Packet: '%s'\n"),
              event->core = c;
            }
          else if (strprefix (p, p1, "fork"))
-           {
-             event->ws.value.related_pid = read_ptid (++p1, &p);
-             event->ws.kind = TARGET_WAITKIND_FORKED;
-           }
+           event->ws.set_forked (read_ptid (++p1, &p));
          else if (strprefix (p, p1, "vfork"))
-           {
-             event->ws.value.related_pid = read_ptid (++p1, &p);
-             event->ws.kind = TARGET_WAITKIND_VFORKED;
-           }
+           event->ws.set_vforked (read_ptid (++p1, &p));
          else if (strprefix (p, p1, "vforkdone"))
            {
-             event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
+             event->ws.set_vfork_done ();
              p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "exec"))
@@ -7628,14 +7825,13 @@ Packet: '%s'\n"),
 
              /* Save the pathname for event reporting and for
                 the next run command.  */
-             gdb::unique_xmalloc_ptr<char[]> pathname
+             gdb::unique_xmalloc_ptr<char> pathname
                ((char *) xmalloc (pathlen + 1));
              hex2bin (p1, (gdb_byte *) pathname.get (), pathlen);
-             pathname[pathlen] = '\0';
+             pathname.get ()[pathlen] = '\0';
 
              /* This is freed during event handling.  */
-             event->ws.value.execd_pathname = pathname.release ();
-             event->ws.kind = TARGET_WAITKIND_EXECD;
+             event->ws.set_execd (std::move (pathname));
 
              /* Skip the registers included in this packet, since
                 they may be for an architecture different from the
@@ -7644,7 +7840,7 @@ Packet: '%s'\n"),
            }
          else if (strprefix (p, p1, "create"))
            {
-             event->ws.kind = TARGET_WAITKIND_THREAD_CREATED;
+             event->ws.set_thread_created ();
              p = strchrnul (p1 + 1, ';');
            }
          else
@@ -7743,7 +7939,7 @@ Packet: '%s'\n"),
          ++p;
        }
 
-      if (event->ws.kind != TARGET_WAITKIND_IGNORE)
+      if (event->ws.kind () != TARGET_WAITKIND_IGNORE)
        break;
 
       /* fall through */
@@ -7751,21 +7947,19 @@ Packet: '%s'\n"),
       {
        int sig;
 
-       event->ws.kind = TARGET_WAITKIND_STOPPED;
        sig = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
        if (GDB_SIGNAL_FIRST <= sig && sig < GDB_SIGNAL_LAST)
-         event->ws.value.sig = (enum gdb_signal) sig;
+         event->ws.set_stopped ((enum gdb_signal) sig);
        else
-         event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
+         event->ws.set_stopped (GDB_SIGNAL_UNKNOWN);
       }
       break;
     case 'w':          /* Thread exited.  */
       {
        ULONGEST value;
 
-       event->ws.kind = TARGET_WAITKIND_THREAD_EXITED;
        p = unpack_varlen_hex (&buf[1], &value);
-       event->ws.value.integer = value;
+       event->ws.set_thread_exited (value);
        if (*p != ';')
          error (_("stop reply packet badly formatted: %s"), buf);
        event->ptid = read_ptid (++p, NULL);
@@ -7784,17 +7978,15 @@ Packet: '%s'\n"),
        if (buf[0] == 'W')
          {
            /* The remote process exited.  */
-           event->ws.kind = TARGET_WAITKIND_EXITED;
-           event->ws.value.integer = value;
+           event->ws.set_exited (value);
          }
        else
          {
            /* The remote process exited with a signal.  */
-           event->ws.kind = TARGET_WAITKIND_SIGNALLED;
            if (GDB_SIGNAL_FIRST <= value && value < GDB_SIGNAL_LAST)
-             event->ws.value.sig = (enum gdb_signal) value;
+             event->ws.set_signalled ((enum gdb_signal) value);
            else
-             event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
+             event->ws.set_signalled (GDB_SIGNAL_UNKNOWN);
          }
 
        /* If no process is specified, return null_ptid, and let the
@@ -7825,7 +8017,7 @@ Packet: '%s'\n"),
       }
       break;
     case 'N':
-      event->ws.kind = TARGET_WAITKIND_NO_RESUMED;
+      event->ws.set_no_resumed ();
       event->ptid = minus_one_ptid;
       break;
     }
@@ -7874,16 +8066,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 (),
@@ -7892,7 +8084,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
@@ -7902,9 +8094,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);
     }
 }
 
@@ -7912,7 +8104,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);
 }
@@ -7951,15 +8143,15 @@ remote_notif_get_pending_events (remote_target *remote, notif_client *nc)
 
 ptid_t
 remote_target::select_thread_for_ambiguous_stop_reply
-  (const struct target_waitstatus *status)
+  (const target_waitstatus &status)
 {
   REMOTE_SCOPED_DEBUG_ENTER_EXIT;
 
   /* Some stop events apply to all threads in an inferior, while others
      only apply to a single thread.  */
   bool process_wide_stop
-    = (status->kind == TARGET_WAITKIND_EXITED
-       || status->kind == TARGET_WAITKIND_SIGNALLED);
+    = (status.kind () == TARGET_WAITKIND_EXITED
+       || status.kind () == TARGET_WAITKIND_SIGNALLED);
 
   remote_debug_printf ("process_wide_stop = %d", process_wide_stop);
 
@@ -7982,12 +8174,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)
     {
@@ -8041,12 +8233,12 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply,
   /* If no thread/process was reported by the stub then select a suitable
      thread/process.  */
   if (ptid == null_ptid)
-    ptid = select_thread_for_ambiguous_stop_reply (status);
+    ptid = select_thread_for_ambiguous_stop_reply (*status);
   gdb_assert (ptid != null_ptid);
 
-  if (status->kind != TARGET_WAITKIND_EXITED
-      && status->kind != TARGET_WAITKIND_SIGNALLED
-      && status->kind != TARGET_WAITKIND_NO_RESUMED)
+  if (status->kind () != TARGET_WAITKIND_EXITED
+      && status->kind () != TARGET_WAITKIND_SIGNALLED
+      && status->kind () != TARGET_WAITKIND_NO_RESUMED)
     {
       /* Expedited registers.  */
       if (!stop_reply->regcache.empty ())
@@ -8097,12 +8289,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)
@@ -8136,12 +8328,12 @@ remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status,
         return to the event loop.  */
       if (options & TARGET_WNOHANG)
        {
-         status->kind = TARGET_WAITKIND_IGNORE;
+         status->set_ignore ();
          return minus_one_ptid;
        }
 
       /* Otherwise do a blocking wait.  */
-      ret = getpkt_or_notif_sane (&rs->buf, 1 /* forever */, &is_notif);
+      ret = getpkt (&rs->buf, true /* forever */, &is_notif);
     }
 }
 
@@ -8170,26 +8362,24 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status,
 
  again:
 
-  status->kind = TARGET_WAITKIND_IGNORE;
-  status->value.integer = 0;
+  status->set_ignore ();
 
   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)
        {
-         status->kind = TARGET_WAITKIND_NO_RESUMED;
+         status->set_no_resumed ();
          return minus_one_ptid;
        }
 
@@ -8197,7 +8387,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.  */
@@ -8206,79 +8397,78 @@ 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->kind = TARGET_WAITKIND_STOPPED;
-      status->value.sig = 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)
+  if (status->kind () == TARGET_WAITKIND_NO_RESUMED)
     return minus_one_ptid;
-  else if (status->kind == TARGET_WAITKIND_IGNORE)
+  else if (status->kind () == TARGET_WAITKIND_IGNORE)
     {
       /* Nothing interesting happened.  If we're doing a non-blocking
         poll, we're done.  Otherwise, go back to waiting.  */
@@ -8287,8 +8477,8 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status,
       else
        goto again;
     }
-  else if (status->kind != TARGET_WAITKIND_EXITED
-          && status->kind != TARGET_WAITKIND_SIGNALLED)
+  else if (status->kind () != TARGET_WAITKIND_EXITED
+          && status->kind () != TARGET_WAITKIND_SIGNALLED)
     {
       if (event_ptid != null_ptid)
        record_currthread (rs, event_ptid);
@@ -8322,9 +8512,13 @@ 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);
+  else
+    gdb_assert (!async_event_handler_marked
+               (rs->remote_async_inferior_event_token));
 
   ptid_t event_ptid;
 
@@ -8357,7 +8551,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)
@@ -8368,11 +8562,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;
@@ -8417,7 +8611,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 ());
@@ -8431,7 +8625,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 ());
@@ -8515,8 +8709,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' */
@@ -8534,8 +8727,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 ()));
@@ -8639,7 +8831,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:
@@ -8667,7 +8859,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)
@@ -8678,9 +8870,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;
@@ -8690,7 +8882,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"));
     }
 }
 
@@ -8727,7 +8919,7 @@ 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'"), 
           rs->buf.data ());
@@ -8863,7 +9055,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;
@@ -8882,17 +9074,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;
       }
@@ -8962,8 +9154,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;
@@ -9012,8 +9203,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.  */
@@ -9088,7 +9278,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;
@@ -9119,7 +9309,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";
@@ -9128,10 +9318,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,
@@ -9181,7 +9370,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')
@@ -9329,13 +9518,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);
 }
@@ -9399,11 +9588,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.  */
@@ -9460,7 +9644,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;
@@ -9489,7 +9673,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)
@@ -9505,18 +9689,7 @@ escape_buffer (const char *buf, int n)
   string_file stb;
 
   stb.putstrn (buf, n, '\\');
-  return std::move (stb.string ());
-}
-
-/* Display a null-terminated packet on stdout, for debugging, using C
-   string notation.  */
-
-static void
-print_packet (const char *buf)
-{
-  puts_filtered ("\"");
-  fputstr_filtered (buf, '"', gdb_stdout);
-  puts_filtered ("\"");
+  return stb.release ();
 }
 
 int
@@ -9569,10 +9742,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.  */
 
@@ -9839,7 +10008,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:
@@ -9868,41 +10037,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;
@@ -9910,15 +10061,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
@@ -9949,7 +10096,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.  */
 
@@ -9979,7 +10126,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)
@@ -10016,7 +10163,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;
        }
 
@@ -10031,70 +10178,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)
+         if (is_notif != nullptr)
            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);
-}
-
-/* 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 ())
     {
-      struct 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->value.related_pid.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.value.related_pid.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
@@ -10104,18 +10241,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);
@@ -10126,7 +10264,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 ();
@@ -10148,7 +10286,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 ();
@@ -10156,10 +10294,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;
@@ -10168,7 +10305,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"));
     }
 }
 
@@ -10255,7 +10392,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
@@ -10283,7 +10421,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;");
@@ -10312,9 +10450,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.  */
@@ -10329,7 +10467,7 @@ remote_target::extended_remote_run (const std::string &args)
        error (_("Running \"%s\" on the remote target failed"),
               remote_exec_file);
     default:
-      gdb_assert_not_reached (_("bad switch"));
+      gdb_assert_not_reached ("bad switch");
     }
 }
 
@@ -10354,7 +10492,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);
@@ -10367,22 +10505,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 ());
 }
@@ -10393,7 +10535,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 ();
@@ -10416,10 +10558,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"),
@@ -10447,7 +10587,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 ())
@@ -10455,12 +10595,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"),
@@ -10515,9 +10655,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';
     }
@@ -10540,9 +10680,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';
     }
@@ -10561,7 +10701,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;
@@ -10590,9 +10730,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;
@@ -10620,7 +10760,7 @@ 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 ();
@@ -10639,7 +10779,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');
     }
@@ -10662,8 +10802,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);
     }
 }
 
@@ -10676,7 +10815,8 @@ 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
@@ -10691,9 +10831,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;
@@ -10702,8 +10843,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
@@ -10725,7 +10865,8 @@ 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
@@ -10739,9 +10880,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:
@@ -10749,8 +10891,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"));
 }
 
 
@@ -10815,7 +10956,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.  */
@@ -10836,7 +10977,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
@@ -10875,7 +11016,7 @@ 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
@@ -10902,9 +11043,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] == '.')
@@ -10919,8 +11060,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"));
 }
 
 
@@ -10933,7 +11073,7 @@ 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
@@ -10950,9 +11090,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:
@@ -10960,8 +11100,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.  */
@@ -10976,7 +11115,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;
 
@@ -10992,10 +11131,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)
@@ -11067,22 +11205,22 @@ compare_sections_command (const char *args, int from_tty)
               paddress (target_gdbarch (), lma),
               paddress (target_gdbarch (), 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 (target_gdbarch (), lma),
+                 paddress (target_gdbarch (), 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
@@ -11094,14 +11232,14 @@ 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 (); 
 
-  if (packet_config_support (packet) == PACKET_DISABLE)
+  if (m_features.packet_support (which_packet) == PACKET_DISABLE)
     return TARGET_XFER_E_IO;
 
   /* Insert header.  */
@@ -11116,8 +11254,8 @@ remote_target::remote_write_qxfer (const char *object_name,
     (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);
@@ -11139,12 +11277,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
@@ -11180,8 +11318,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')
@@ -11255,13 +11394,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)
@@ -11269,8 +11405,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;
     }
@@ -11299,74 +11434,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;
@@ -11409,7 +11541,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);
@@ -11432,8 +11564,7 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
   int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 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;
@@ -11443,16 +11574,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)
@@ -11464,7 +11594,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).  */
@@ -11493,12 +11623,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);
@@ -11557,7 +11687,7 @@ 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
@@ -11577,7 +11707,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"));
        }
@@ -11585,7 +11715,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;
     }
@@ -11605,34 +11735,87 @@ remote_target::memory_map ()
   return result;
 }
 
-static void
-packet_command (const char *args, int from_tty)
+/* Set of callbacks used to implement the 'maint packet' command.  */
+
+struct cli_packet_command_callbacks : public send_remote_packet_callbacks
 {
-  remote_target *remote = get_current_remote_target ();
+  /* Called before the packet is sent.  BUF is the packet content before
+     the protocol specific prefix, suffix, and escaping is added.  */
 
-  if (remote == nullptr)
-    error (_("command can only be used with remote target"));
+  void sending (gdb::array_view<const char> &buf) override
+  {
+    gdb_puts ("sending: ");
+    print_packet (buf);
+    gdb_puts ("\n");
+  }
 
-  remote->packet_command (args, from_tty);
-}
+  /* Called with BUF, the reply from the remote target.  */
+
+  void received (gdb::array_view<const char> &buf) override
+  {
+    gdb_puts ("received: \"");
+    print_packet (buf);
+    gdb_puts ("\"\n");
+  }
+
+private:
+
+  /* Print BUF o gdb_stdout.  Any non-printable bytes in BUF are printed as
+     '\x??' with '??' replaced by the hexadecimal value of the byte.  */
+
+  static void
+  print_packet (gdb::array_view<const char> &buf)
+  {
+    string_file stb;
+
+    for (int i = 0; i < buf.size (); ++i)
+      {
+       gdb_byte c = buf[i];
+       if (isprint (c))
+         gdb_putc (c, &stb);
+       else
+         gdb_printf (&stb, "\\x%02x", (unsigned char) c);
+      }
+
+    gdb_puts (stb.string ().c_str ());
+  }
+};
+
+/* See remote.h.  */
 
 void
-remote_target::packet_command (const char *args, int from_tty)
+send_remote_packet (gdb::array_view<const char> &buf,
+                   send_remote_packet_callbacks *callbacks)
 {
-  if (!args)
-    error (_("remote-packet command requires packet text as argument"));
+  if (buf.size () == 0 || buf.data ()[0] == '\0')
+    error (_("a remote packet must not be empty"));
 
-  puts_filtered ("sending: ");
-  print_packet (args);
-  puts_filtered ("\n");
-  putpkt (args);
+  remote_target *remote = get_current_remote_target ();
+  if (remote == nullptr)
+    error (_("packets can only be sent to a remote target"));
 
-  remote_state *rs = get_remote_state ();
+  callbacks->sending (buf);
+
+  remote->putpkt_binary (buf.data (), buf.size ());
+  remote_state *rs = remote->get_remote_state ();
+  int bytes = remote->getpkt (&rs->buf);
+
+  if (bytes < 0)
+    error (_("error while fetching packet from remote target"));
+
+  gdb::array_view<const char> view (&rs->buf[0], bytes);
+  callbacks->received (view);
+}
 
-  getpkt (&rs->buf, 0);
-  puts_filtered ("received: ");
-  print_packet (rs->buf.data ());
-  puts_filtered ("\n");
+/* Entry point for the 'maint packet' command.  */
+
+static void
+cli_packet_command (const char *args, int from_tty)
+{
+  cli_packet_command_callbacks cb;
+  gdb::array_view<const char> view
+    = gdb::make_array_view (args, args == nullptr ? 0 : strlen (args));
+  send_remote_packet (view, &cb);
 }
 
 #if 0
@@ -11663,7 +11846,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);
 }
 
@@ -11676,9 +11859,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);
@@ -11690,7 +11873,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
@@ -11701,10 +11884,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;
@@ -11719,9 +11902,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
@@ -11746,9 +11929,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
@@ -11761,7 +11944,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);
 }
 
@@ -11788,8 +11971,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 ())
@@ -11805,7 +11986,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);
@@ -11814,7 +11995,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
@@ -11832,7 +12013,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 ();
@@ -11849,9 +12030,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;
@@ -11879,7 +12059,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 ();
@@ -11892,9 +12072,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;
@@ -11932,33 +12111,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);
@@ -11970,9 +12151,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));
+  struct remote_g_packet_data *data = get_g_packet_data (target_gdbarch ());
 
   return !data->guesses.empty ();
 }
@@ -11980,9 +12159,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));
+  struct remote_g_packet_data *data = get_g_packet_data (target_gdbarch ());
 
   /* Do not try this during initial connection, when we do not know
      whether there is a running but stopped thread.  */
@@ -12074,7 +12251,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.
@@ -12084,11 +12261,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')
@@ -12103,7 +12280,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;
@@ -12140,21 +12317,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.  */
@@ -12164,7 +12341,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;
@@ -12225,7 +12402,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;
@@ -12234,7 +12411,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)
@@ -12248,7 +12425,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)
@@ -12262,7 +12439,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 ();
@@ -12272,8 +12449,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)
        {
@@ -12305,7 +12482,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);
@@ -12315,7 +12492,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 ();
@@ -12342,7 +12519,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);
 }
@@ -12352,7 +12529,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 ();
@@ -12394,14 +12571,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;
     }
 
@@ -12412,7 +12589,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 ();
@@ -12435,10 +12612,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)
     {
@@ -12446,13 +12623,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);
 }
@@ -12460,7 +12637,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 ();
@@ -12477,7 +12654,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);
 }
@@ -12486,7 +12663,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 ();
@@ -12506,7 +12683,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);
 }
@@ -12515,7 +12692,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 ();
@@ -12552,7 +12729,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 ();
@@ -12618,13 +12795,14 @@ remote_target::filesystem_is_local ()
      this case we treat the remote filesystem as local if the
      sysroot is exactly TARGET_SYSROOT_PREFIX and if the stub
      does not support vFile:open.  */
-  if (strcmp (gdb_sysroot, TARGET_SYSROOT_PREFIX) == 0)
+  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
@@ -12636,7 +12814,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)
@@ -12658,61 +12836,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);
@@ -12736,7 +12863,7 @@ public:
       {
        try
          {
-           int remote_errno;
+           fileio_error remote_errno;
            m_remote->remote_hostio_close (m_fd, &remote_errno);
          }
        catch (...)
@@ -12787,7 +12914,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;
@@ -12861,7 +12989,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
@@ -12879,7 +13007,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
@@ -12920,7 +13049,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
@@ -12937,14 +13066,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
@@ -12989,8 +13119,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;
@@ -13012,58 +13142,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
@@ -13172,9 +13302,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
@@ -13183,7 +13311,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.  */
@@ -13223,7 +13352,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);
@@ -13232,12 +13361,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';
        }
@@ -13246,7 +13375,7 @@ remote_target::download_tracepoint (struct bp_location *loc)
                   "ignoring tp %d cond"), b->number);
     }
 
-  if (b->commands || *default_collect)
+  if (b->commands || !default_collect.empty ())
     {
       size_left = buf.size () - strlen (buf.data ());
 
@@ -13308,17 +13437,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 ());
@@ -13334,7 +13463,7 @@ remote_target::download_tracepoint (struct bp_location *loc)
            error ("%s", err_msg);
 
          encode_source_string (b->number, loc->address,
-                               "cond", b->cond_string,
+                               "cond", b->cond_string.get (),
                                buf.data () + strlen (buf.data ()),
                                buf.size () - strlen (buf.data ()));
          putpkt (buf.data ());
@@ -13438,33 +13567,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;
@@ -13476,7 +13607,7 @@ Too many sections for read-only sections definition packet."));
   if (anysecs)
     {
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf);
     }
 }
 
@@ -13501,7 +13632,7 @@ 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.  */
@@ -13524,7 +13655,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)
@@ -13556,14 +13687,14 @@ remote_target::get_tracepoint_status (struct breakpoint *bp,
     {
       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)
@@ -13779,7 +13910,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;
 
@@ -13799,7 +13931,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;
@@ -13873,7 +14005,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 ();
@@ -13893,8 +14025,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 ());
@@ -13950,14 +14081,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)
        {
@@ -13972,7 +14103,7 @@ 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);
 }
 
 struct btrace_target_info
@@ -13997,7 +14128,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;
 
@@ -14005,18 +14135,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);
@@ -14027,18 +14158,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);
@@ -14050,12 +14182,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, struct 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, "");
@@ -14076,17 +14211,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;
@@ -14112,8 +14243,8 @@ 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);
@@ -14125,7 +14256,8 @@ remote_target::remote_btrace_maybe_reopen ()
 /* 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;
@@ -14133,29 +14265,35 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf)
   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"),
@@ -14172,7 +14310,7 @@ remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf)
      tracing itself is not impacted.  */
   try
     {
-      btrace_read_config (&tinfo->conf);
+      btrace_read_config (tp, &tinfo->conf);
     }
   catch (const gdb_exception_error &err)
     {
@@ -14188,21 +14326,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"),
@@ -14231,10 +14369,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)
@@ -14253,8 +14390,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);
     }
 
@@ -14278,8 +14414,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.  */
@@ -14294,19 +14431,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)
     {
@@ -14332,13 +14468,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
@@ -14382,7 +14515,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);
@@ -14392,27 +14525,19 @@ remote_target::thread_info_to_thread_handle (struct thread_info *tp)
 bool
 remote_target::can_async_p ()
 {
-  struct remote_state *rs = get_remote_state ();
-
-  /* We don't go async if the user has explicitly prevented it with the
-     "maint set target-async" command.  */
-  if (!target_async_permitted)
-    return false;
+  /* This flag should be checked in the common target.c code.  */
+  gdb_assert (target_async_permitted);
 
-  /* We're async whenever the serial device is.  */
+  /* We're async whenever the serial device can.  */
+  struct remote_state *rs = get_remote_state ();
   return serial_can_async_p (rs->remote_desc);
 }
 
 bool
 remote_target::is_async_p ()
 {
-  struct remote_state *rs = get_remote_state ();
-
-  if (!target_async_permitted)
-    /* We only enable async when the user specifically asks for it.  */
-    return false;
-
   /* We're async whenever the serial device is.  */
+  struct remote_state *rs = get_remote_state ();
   return serial_is_async_p (rs->remote_desc);
 }
 
@@ -14444,7 +14569,7 @@ remote_target::async_wait_fd ()
 }
 
 void
-remote_target::async (int enable)
+remote_target::async (bool enable)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -14484,15 +14609,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)
@@ -14540,28 +14664,55 @@ show_remote_cmd (const char *args, int from_tty)
 static void
 remote_new_objfile (struct objfile *objfile)
 {
-  remote_target *remote = get_current_remote_target ();
+  /* The objfile change happened in that program space.  */
+  program_space *pspace = current_program_space;
 
-  /* First, check whether the current inferior's process target is a remote
-     target.  */
-  if (remote == nullptr)
-    return;
+  /* 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;
 
-  /* 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;
+      /* 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 (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.
 
-  remote->remote_check_symbols ();
+        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 ();
+       }
+  }
 }
 
 /* Pull all the tracepoints defined on the target and create local
@@ -14577,14 +14728,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;
@@ -14598,14 +14749,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;
@@ -14618,9 +14769,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
@@ -14629,10 +14780,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);
 }
 
@@ -14657,17 +14805,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.  */
@@ -14675,7 +14823,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.  */
@@ -14741,7 +14889,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 ();
@@ -14749,7 +14897,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);
 }
@@ -14761,7 +14909,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 ();
@@ -14769,7 +14917,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;
@@ -14796,7 +14944,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);
@@ -14876,10 +15024,6 @@ 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);
 
@@ -14911,7 +15055,7 @@ Argument is a single section name (default: all loaded sections).\n\
 To compare only read-only loaded sections, specify the -r option."),
           &cmdlist);
 
-  add_cmd ("packet", class_maintenance, packet_command, _("\
+  add_cmd ("packet", class_maintenance, cli_packet_command, _("\
 Send an arbitrary packet to a remote target.\n\
    maintenance packet TEXT\n\
 If GDB is talking to an inferior via the GDB serial protocol, then\n\
@@ -14961,16 +15105,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,
@@ -15015,257 +15159,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
@@ -15298,7 +15406,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));
       }
   }