Unify getpkt and getpkt_or_notif_sane
[binutils-gdb.git] / gdb / remote.c
index 0a6e293c0955f81105d9465489feb538e6919fdf..edda9457745dd7ef44cb2af1191112749f0b004f 100644 (file)
 #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"
@@ -116,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.  */
 
@@ -126,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.
@@ -175,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;
@@ -275,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.  */
@@ -378,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
@@ -394,6 +567,130 @@ static const target_info remote_target_info = {
   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:
@@ -487,8 +784,8 @@ public:
                                             int handle_len,
                                             inferior *inf) override;
 
-  gdb::byte_vector thread_info_to_thread_handle (struct thread_info *tp)
-                                                override;
+  gdb::array_view<const gdb_byte> thread_info_to_thread_handle (struct thread_info *tp)
+    override;
 
   void stop (ptid_t) override;
 
@@ -584,8 +881,16 @@ public:
 
   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;
@@ -844,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);
@@ -908,12 +1213,7 @@ 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, bool *is_notif = nullptr);
   int remote_vkill (int pid);
   void remote_kill_k ();
 
@@ -932,19 +1232,21 @@ public: /* Remote specific methods.  */
                                         const gdb_byte *writebuf,
                                         ULONGEST offset, LONGEST len,
                                         ULONGEST *xfered_len,
-                                        struct packet_config *packet);
+                                        const unsigned int which_packet);
 
   target_xfer_status remote_read_qxfer (const char *object_name,
                                        const char *annex,
                                        gdb_byte *readbuf, ULONGEST offset,
                                        LONGEST len,
                                        ULONGEST *xfered_len,
-                                       struct packet_config *packet);
+                                       const unsigned int which_packet);
 
   void push_stop_reply (struct stop_reply *new_event);
 
   bool vcont_r_supported ();
 
+  remote_features m_features;
+
 private:
 
   bool start_remote_1 (int from_tty, int extended_p);
@@ -1067,7 +1369,12 @@ static CORE_ADDR remote_address_masked (CORE_ADDR);
 
 static int stub_unpack_int (const char *buff, int fieldlength);
 
-struct packet_config;
+static void set_remote_protocol_packet_cmd (const char *args, int from_tty,
+                                           cmd_list_element *c);
+
+static void show_packet_config_cmd (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,
@@ -1250,7 +1557,7 @@ remote_target::remote_get_noisy_reply ()
       char *buf;
 
       QUIT;                    /* Allow user to bail out with ^C.  */
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf, false);
       buf = rs->buf.data ();
       if (buf[0] == 'E')
        trace_error (buf);
@@ -1637,21 +1944,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
@@ -1717,13 +2009,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;
@@ -1751,31 +2044,49 @@ 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)
-    gdb_printf (_("The %s is 0 (default). "), config->name);
+    gdb_printf (_("The %s %s is 0 (default). "), config->name, target_type);
   else
-    gdb_printf (_("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)
     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)
+      if (remote != nullptr)
        gdb_printf (_("Packets are limited to %ld bytes.\n"),
                    remote->get_memory_packet_size (config));
       else
@@ -1784,22 +2095,39 @@ show_memory_packet_size (struct memory_packet_config *config)
     }
 }
 
-/* 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.  */
@@ -1855,31 +2183,47 @@ show_remote_packet_max_chars (struct ui_file *file, int from_tty,
 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
@@ -1889,34 +2233,52 @@ remote_target::get_memory_read_packet_size ()
   return size;
 }
 
-\f
+static enum packet_support packet_config_support (const packet_config *config);
 
-struct packet_config
-  {
-    const char *name;
-    const char *title;
 
-    /* If auto, GDB auto-detects support for this packet or feature,
-       either through qSupported, or by trying the packet and looking
-       at the response.  If true, GDB assumes the target supports this
-       packet.  If false, the packet is disabled.  Configs that don't
-       have an associated command always have this set to auto.  */
-    enum auto_boolean detect;
+static void
+set_remote_protocol_packet_cmd (const char *args, int from_tty,
+                               cmd_list_element *c)
+{
+  remote_target *remote = get_current_remote_target ();
+  gdb_assert (c->var.has_value ());
 
-    /* The "show remote foo-packet" command created for this packet.  */
-    cmd_list_element *show_cmd;
+  auto *default_config = static_cast<packet_config *> (c->context ());
+  const int packet_idx = std::distance (remote_protocol_packets,
+                                       default_config);
 
-    /* Does the target support this packet?  */
-    enum packet_support support;
-  };
+  if (packet_idx >= 0 && packet_idx < PACKET_MAX)
+    {
+      const char *name = packets_descriptions[packet_idx].name;
+      const auto_boolean value = c->var->get<auto_boolean> ();
+      const char *support = get_packet_support_name (value);
+      const char *target_type = get_target_type_name (remote != nullptr);
+
+      if (remote != nullptr)
+       remote->m_features.m_protocol_packets[packet_idx].detect = value;
+      else
+       remote_protocol_packets[packet_idx].detect = value;
 
-static enum packet_support packet_config_support (struct packet_config *config);
-static enum packet_support packet_support (int packet);
+      gdb_printf (_("Support for the '%s' packet %s is set to \"%s\".\n"), name,
+                 target_type, support);
+      return;
+    }
+
+  internal_error (_("Could not find config for %s"), c->name);
+}
 
 static void
-show_packet_config_cmd (ui_file *file, 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))
     {
@@ -1934,304 +2296,152 @@ show_packet_config_cmd (ui_file *file, struct packet_config *config)
     {
     case AUTO_BOOLEAN_AUTO:
       gdb_printf (file,
-                 _("Support for the `%s' packet "
-                   "is auto-detected, currently %s.\n"),
-                 config->name, support);
+                 _("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:
       gdb_printf (file,
-                 _("Support for the `%s' packet is currently %s.\n"),
-                 config->name, support);
+                 _("Support for the '%s' packet %s is \"%s\".\n"),
+                 packets_descriptions[which_packet].name, target_type,
+                 get_packet_support_name (config->detect));
       break;
     }
 }
 
 static void
-add_packet_config_cmd (struct packet_config *config, const char *name,
+add_packet_config_cmd (const unsigned int which_packet, const char *name,
                       const char *title, int legacy)
 {
-  config->name = name;
-  config->title = title;
+  packets_descriptions[which_packet].name = name;
+  packets_descriptions[which_packet].title = title;
+
+  packet_config *config = &remote_protocol_packets[which_packet];
+
   gdb::unique_xmalloc_ptr<char> set_doc
     = xstrprintf ("Set use of remote protocol `%s' (%s) packet.",
                  name, title);
   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} */
-  gdb::unique_xmalloc_ptr<char> cmd_name = xstrprintf ("%s-packet", title);
-  set_show_commands cmds
-    = add_setshow_auto_boolean_cmd (cmd_name.release (), class_obscure,
-                                   &config->detect, set_doc.get (),
-                                   show_doc.get (), NULL, /* help_doc */
-                                   NULL,
-                                   show_remote_protocol_packet_cmd,
-                                   &remote_set_cmdlist, &remote_show_cmdlist);
-  config->show_cmd = cmds.show;
-
-  /* set/show remote NAME-packet {auto,on,off} -- legacy.  */
-  if (legacy)
-    {
-      /* It's not clear who should take ownership of the LEGACY_NAME string
-        created below, so, for now, place the string into a static vector
-        which ensures the strings is released when GDB exits.  */
-      static std::vector<gdb::unique_xmalloc_ptr<char>> legacy_names;
-      gdb::unique_xmalloc_ptr<char> legacy_name
-       = xstrprintf ("%s-packet", name);
-      add_alias_cmd (legacy_name.get (), cmds.set, class_obscure, 0,
-                    &remote_set_cmdlist);
-      add_alias_cmd (legacy_name.get (), cmds.show, class_obscure, 0,
-                    &remote_show_cmdlist);
-      legacy_names.emplace_back (std::move (legacy_name));
-    }
-}
-
-static enum packet_result
-packet_check_result (const char *buf)
-{
-  if (buf[0] != '\0')
-    {
-      /* The stub recognized the packet request.  Check that the
-        operation succeeded.  */
-      if (buf[0] == 'E'
-         && isxdigit (buf[1]) && isxdigit (buf[2])
-         && buf[3] == '\0')
-       /* "Enn"  - definitely an error.  */
-       return PACKET_ERROR;
-
-      /* Always treat "E." as an error.  This will be used for
-        more verbose error messages, such as E.memtypes.  */
-      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 (_("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,
+    = xstrprintf ("Show current use of remote protocol `%s' (%s) packet.",
+                 name, title);
+  /* set/show TITLE-packet {auto,on,off} */
+  gdb::unique_xmalloc_ptr<char> cmd_name = xstrprintf ("%s-packet", title);
+  set_show_commands cmds
+    = 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);
+  cmds.show->set_context (config);
+  cmds.set->set_context (config);
 
-  /* Support for fork events.  */
-  PACKET_fork_event_feature,
+  /* set/show remote NAME-packet {auto,on,off} -- legacy.  */
+  if (legacy)
+    {
+      /* It's not clear who should take ownership of the LEGACY_NAME string
+        created below, so, for now, place the string into a static vector
+        which ensures the strings is released when GDB exits.  */
+      static std::vector<gdb::unique_xmalloc_ptr<char>> legacy_names;
+      gdb::unique_xmalloc_ptr<char> legacy_name
+       = xstrprintf ("%s-packet", name);
+      add_alias_cmd (legacy_name.get (), cmds.set, class_obscure, 0,
+                    &remote_set_cmdlist);
+      add_alias_cmd (legacy_name.get (), cmds.show, class_obscure, 0,
+                    &remote_show_cmdlist);
+      legacy_names.emplace_back (std::move (legacy_name));
+    }
+}
 
-  /* Support for vfork events.  */
-  PACKET_vfork_event_feature,
+static enum packet_result
+packet_check_result (const char *buf)
+{
+  if (buf[0] != '\0')
+    {
+      /* The stub recognized the packet request.  Check that the
+        operation succeeded.  */
+      if (buf[0] == 'E'
+         && isxdigit (buf[1]) && isxdigit (buf[2])
+         && buf[3] == '\0')
+       /* "Enn"  - definitely an error.  */
+       return PACKET_ERROR;
 
-  /* Support for the Qbtrace-conf:pt:size packet.  */
-  PACKET_Qbtrace_conf_pt_size,
+      /* Always treat "E." as an error.  This will be used for
+        more verbose error messages, such as E.memtypes.  */
+      if (buf[0] == 'E' && buf[1] == '.')
+       return PACKET_ERROR;
 
-  /* 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
@@ -2239,7 +2449,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)
     {
@@ -2254,14 +2464,10 @@ packet_config_support (struct packet_config *config)
     }
 }
 
-/* Same as packet_config_support, but takes the packet's enum value as
-   argument.  */
-
-static enum packet_support
-packet_support (int packet)
+packet_support
+remote_features::packet_support (int packet) const
 {
-  struct packet_config *config = &remote_protocol_packets[packet];
-
+  const packet_config *config = &m_protocol_packets[packet];
   return packet_config_support (config);
 }
 
@@ -2270,21 +2476,19 @@ show_remote_protocol_packet_cmd (struct ui_file *file, int from_tty,
                                 struct cmd_list_element *c,
                                 const char *value)
 {
-  struct packet_config *packet;
+  remote_target *remote = get_current_remote_target ();
   gdb_assert (c->var.has_value ());
 
-  for (packet = remote_protocol_packets;
-       packet < &remote_protocol_packets[PACKET_MAX];
-       packet++)
+  auto *default_config = static_cast<packet_config *> (c->context ());
+  const int packet_idx = std::distance (remote_protocol_packets,
+                                       default_config);
+
+  if (packet_idx >= 0 && packet_idx < PACKET_MAX)
     {
-      if (c == packet->show_cmd)
-       {
-         show_packet_config_cmd (file, packet);
-         return;
-       }
+       show_packet_config_cmd (file, packet_idx, remote);
+       return;
     }
-  internal_error (_("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?  */
@@ -2308,10 +2512,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
@@ -2319,52 +2536,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 (file, &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
@@ -2373,9 +2549,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
@@ -2393,9 +2567,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
@@ -2413,9 +2585,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
@@ -2444,19 +2614,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, false);
 
-  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)
@@ -2606,7 +2775,7 @@ 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.
@@ -2656,8 +2825,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);
@@ -2699,7 +2867,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);
 }
 
@@ -2720,7 +2888,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;
@@ -2753,8 +2921,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, false);
+         m_features.packet_ok (rs->buf, PACKET_QPassSignals);
          xfree (rs->last_pass_packet);
          rs->last_pass_packet = pass_packet;
        }
@@ -2774,7 +2942,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;
@@ -2826,8 +2994,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, false);
+  result = m_features.packet_ok (rs->buf, PACKET_QCatchSyscalls);
   if (result == PACKET_OK)
     return 0;
   else
@@ -2840,7 +3008,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;
@@ -2874,8 +3042,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, false);
+         m_features.packet_ok (rs->buf, PACKET_QProgramSignals);
          xfree (rs->last_program_signals_packet);
          rs->last_program_signals_packet = packet;
        }
@@ -2910,7 +3078,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, false);
   if (gen)
     rs->general_thread = ptid;
   else
@@ -2941,12 +3109,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 ())
@@ -2994,7 +3162,7 @@ remote_target::thread_alive (ptid_t ptid)
   write_ptid (p, endp, ptid);
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
   return (rs->buf[0] == 'O' && rs->buf[1] == 'K');
 }
 
@@ -3021,7 +3189,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.  */
@@ -3096,9 +3264,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)
@@ -3495,7 +3662,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, false);
 
   if (rs->buf[0] == '\0')
     return 0;
@@ -3569,7 +3736,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, false);
   if (rs->buf[0] == '\0')
     {
       /* Packet not supported.  */
@@ -3756,7 +3923,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, false);
   if (rs->buf[0] == 'Q' && rs->buf[1] == 'C')
     {
       const char *obuf;
@@ -3860,7 +4027,7 @@ int
 remote_target::remote_get_threads_with_qxfer (threads_listing_context *context)
 {
 #if defined(HAVE_LIBEXPAT)
-  if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
     {
       gdb::optional<gdb::char_vector> xml
        = target_read_stralloc (this, TARGET_OBJECT_THREADS, NULL);
@@ -3890,7 +4057,7 @@ remote_target::remote_get_threads_with_qthreadinfo (threads_listing_context *con
       const char *bufp;
 
       putpkt ("qfThreadInfo");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf, false);
       bufp = rs->buf.data ();
       if (bufp[0] != '\0')             /* q packet recognized */
        {
@@ -3903,7 +4070,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, false);
              bufp = rs->buf.data ();
            }
          return 1;
@@ -4000,7 +4167,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);
@@ -4052,7 +4219,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,
@@ -4070,7 +4237,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, false);
       if (rs->buf[0] != 0)
        {
          extra.resize (strlen (rs->buf.data ()) / 2);
@@ -4118,7 +4285,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, false);
   p = rs->buf.data ();
 
   if (*p == 'E')
@@ -4144,7 +4311,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, false);
   p = rs->buf.data ();
   if (*p == 'E')
     error (_("Remote failure reply: %s"), p);
@@ -4161,7 +4328,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, false);
       p = rs->buf.data ();
     }
 
@@ -4242,7 +4409,7 @@ remote_target::get_offsets ()
     return;
 
   putpkt ("qOffsets");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
   buf = rs->buf.data ();
 
   if (buf[0] == '\000')
@@ -4477,7 +4644,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 ();
@@ -4488,7 +4654,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
@@ -4546,9 +4712,10 @@ remote_target::print_one_stopped_thread (thread_info *thread)
       enum gdb_signal sig = ws.sig ();
 
       if (signal_print_state (sig))
-       gdb::observers::signal_received.notify (sig);
+       notify_signal_received (sig);
     }
-  gdb::observers::normal_stop.notify (NULL, 1);
+
+  notify_normal_stop (nullptr, 1);
 }
 
 /* Process all initial stop replies the remote side sent in response
@@ -4597,7 +4764,7 @@ remote_target::process_initial_stop_replies (int from_tty)
       if (ignore_event)
        continue;
 
-      thread_info *evthread = find_thread_ptid (this, event_ptid);
+      thread_info *evthread = this->find_thread (event_ptid);
 
       if (ws.kind () == TARGET_WAITKIND_STOPPED)
        {
@@ -4750,7 +4917,6 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
   REMOTE_SCOPED_DEBUG_ENTER_EXIT;
 
   struct remote_state *rs = get_remote_state ();
-  struct packet_config *noack_config;
 
   /* Signal other parts that we're going through the initial setup,
      and so things may not be stable yet.  E.g., we don't try to
@@ -4773,8 +4939,12 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
      which later probes to skip.  */
   remote_query_supported ();
 
+  /* Check vCont support and set the remote state's vCont_action_support
+     attribute.  */
+  remote_vcont_probe ();
+
   /* If the stub wants to get a QAllow, compose one and send it.  */
-  if (packet_support (PACKET_QAllow) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QAllow) != PACKET_DISABLE)
     set_permissions ();
 
   /* gdbserver < 7.7 (before its fix from 2013-12-11) did reply to any
@@ -4788,9 +4958,12 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
     const char v_mustreplyempty[] = "vMustReplyEmpty";
 
     putpkt (v_mustreplyempty);
-    getpkt (&rs->buf, 0);
+    getpkt (&rs->buf, false);
     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 ());
@@ -4809,12 +4982,11 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
      If FALSE, then don't activate noack mode, regardless of what the
      stub claimed should be the default with qSupported.  */
 
-  noack_config = &remote_protocol_packets[PACKET_QStartNoAckMode];
-  if (packet_config_support (noack_config) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QStartNoAckMode) != PACKET_DISABLE)
     {
       putpkt ("QStartNoAckMode");
-      getpkt (&rs->buf, 0);
-      if (packet_ok (rs->buf, noack_config) == PACKET_OK)
+      getpkt (&rs->buf, false);
+      if (m_features.packet_ok (rs->buf, PACKET_QStartNoAckMode) == PACKET_OK)
        rs->noack_mode = 1;
     }
 
@@ -4822,7 +4994,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
     {
       /* Tell the remote that we are using the extended protocol.  */
       putpkt ("!");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf, false);
     }
 
   /* Let the target know which signals it is allowed to pass down to
@@ -4844,12 +5016,12 @@ remote_target::start_remote_1 (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, false);
 
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("Remote refused setting non-stop mode with: %s"),
@@ -4861,12 +5033,12 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
         stopped.  */
       this->update_thread_list ();
     }
-  else if (packet_support (PACKET_QNonStop) == PACKET_ENABLE)
+  else if (m_features.packet_support (PACKET_QNonStop) == PACKET_ENABLE)
     {
       /* Don't assume that the stub can operate in all-stop mode.
         Request it explicitly.  */
       putpkt ("QNonStop:0");
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf, false);
 
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("Remote refused setting all-stop mode with: %s"),
@@ -4886,7 +5058,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
 
   /* Check whether the target is running now.  */
   putpkt ("?");
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
 
   if (!target_is_non_stop_p ())
     {
@@ -4944,7 +5116,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
                }
            }
          else
-           switch_to_thread (find_thread_ptid (this, curr_thread));
+           switch_to_thread (this->find_thread (curr_thread));
        }
 
       /* init_wait_for_inferior should be called before get_offsets in order
@@ -4995,7 +5167,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
         mechanism.  */
       if (strcmp (rs->buf.data (), "OK") != 0)
        {
-         struct notif_client *notif = &notif_client_stop;
+         const notif_client *notif = &notif_client_stop;
 
          /* remote_notif_get_pending_replies acks this one, and gets
             the rest out.  */
@@ -5035,7 +5207,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
        continue;
 
       /* Need to switch to a specific thread, because remote_check_symbols
-         uses INFERIOR_PTID to set the general thread.  */
+        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);
@@ -5102,16 +5274,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.  */
@@ -5141,7 +5310,7 @@ remote_target::remote_check_symbols ()
      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
@@ -5156,8 +5325,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, false);
+  m_features.packet_ok (reply, PACKET_qSymbol);
 
   while (startswith (reply.data (), "qSymbol:"))
     {
@@ -5186,7 +5355,7 @@ remote_target::remote_check_symbols ()
        }
 
       putpkt (msg.data ());
-      getpkt (&reply, 0);
+      getpkt (&reply, false);
     }
 }
 
@@ -5232,7 +5401,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, false);
 
   /* 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.  */
@@ -5281,7 +5450,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
@@ -5489,58 +5658,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, false);
 
-      /* 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;
@@ -5772,7 +5950,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)
@@ -5817,7 +5995,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 ();
+  remote->m_features.reset_all_packet_configs_support ();
   rs->explicit_packet_size = 0;
   rs->noack_mode = 0;
   rs->extended = extended_p;
@@ -5846,7 +6024,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.  */
@@ -5886,7 +6064,7 @@ 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.  */
@@ -5930,13 +6108,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, false);
 
   if (rs->buf[0] == 'O' && rs->buf[1] == 'K')
     ;
@@ -6007,7 +6185,7 @@ remote_target::remote_detach_1 (inferior *inf, int from_tty)
       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.  */
@@ -6061,10 +6239,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
@@ -6130,17 +6308,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"));
 
   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, false);
 
-  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 ())
@@ -6241,7 +6418,7 @@ remote_target::remote_vcont_probe ()
 
   strcpy (rs->buf.data (), "vCont?");
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
   buf = rs->buf.data ();
 
   /* Make sure that the features we assume are supported.  */
@@ -6281,8 +6458,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
@@ -6311,7 +6487,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;
 
@@ -6319,10 +6495,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)
@@ -6345,7 +6521,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;
 
@@ -6429,9 +6605,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");
@@ -6468,10 +6644,7 @@ remote_target::remote_resume_with_vcont (ptid_t scope_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 ();
@@ -6524,7 +6697,7 @@ remote_target::remote_resume_with_vcont (ptid_t scope_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, false);
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("Unexpected vCont reply in non-stop mode: %s"),
               rs->buf.data ());
@@ -6553,7 +6726,7 @@ remote_target::resume (ptid_t scope_ptid, int step, enum gdb_signal siggnal)
        = 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);
@@ -6674,7 +6847,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, false);
   if (strcmp (rs->buf.data (), "OK") != 0)
     error (_("Unexpected vCont reply in non-stop mode: %s"), rs->buf.data ());
 }
@@ -6845,7 +7018,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)
@@ -6855,7 +7028,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);
@@ -7004,17 +7177,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
     {
@@ -7042,7 +7209,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, false);
   if (strcmp (rs->buf.data (), "OK") != 0)
     error (_("Stopping %s failed: %s"), target_pid_to_str (ptid).c_str (),
           rs->buf.data ());
@@ -7086,9 +7253,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, false);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCtrlC]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vCtrlC))
     {
     case PACKET_OK:
       break;
@@ -7219,7 +7386,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);
@@ -7227,7 +7394,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;
@@ -7244,7 +7411,7 @@ remote_notif_stop_ack (remote_target *remote,
 
 static int
 remote_notif_stop_can_get_pending_events (remote_target *remote,
-                                         struct notif_client *self)
+                                         const notif_client *self)
 {
   /* We can't get pending events in remote_notif_process for
      notification stop, and we have to do this in remote_wait_ns
@@ -7270,7 +7437,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",
@@ -7290,7 +7457,7 @@ struct notif_client notif_client_stop =
 void
 remote_target::remove_new_fork_children (threads_listing_context *context)
 {
-  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.  */
@@ -7326,7 +7493,7 @@ void
 remote_target::check_pending_events_prevent_wildcard_vcont
   (bool *may_global_wildcard)
 {
-  struct notif_client *notif = &notif_client_stop;
+  const notif_client *notif = &notif_client_stop;
 
   remote_notif_get_pending_events (notif);
   for (auto &event : get_remote_state ()->stop_reply_queue)
@@ -7392,8 +7559,8 @@ remote_target::discard_pending_stop_replies (struct inferior *inf)
   for (auto it = iter; it != rs->stop_reply_queue.end (); ++it)
     remote_debug_printf
       ("discarding queued stop reply: ptid: %s, ws: %s\n",
-       reply->ptid.to_string().c_str(),
-       reply->ws.to_string ().c_str ());
+       (*it)->ptid.to_string().c_str(),
+       (*it)->ws.to_string ().c_str ());
   rs->stop_reply_queue.erase (iter, rs->stop_reply_queue.end ());
 }
 
@@ -7596,7 +7763,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",
@@ -7610,7 +7778,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.  */
@@ -7896,7 +8065,7 @@ 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 ();
 
@@ -7914,7 +8083,7 @@ remote_target::remote_notif_get_pending_events (notif_client *nc)
 
       while (1)
        {
-         getpkt (&rs->buf, 0);
+         getpkt (&rs->buf, false);
          if (strcmp (rs->buf.data (), "OK") == 0)
            break;
          else
@@ -7934,7 +8103,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);
 }
@@ -8119,12 +8288,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)
@@ -8163,7 +8332,7 @@ remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status,
        }
 
       /* Otherwise do a blocking wait.  */
-      ret = getpkt_or_notif_sane (&rs->buf, 1 /* forever */, &is_notif);
+      ret = getpkt (&rs->buf, true /* forever */, &is_notif);
     }
 }
 
@@ -8204,8 +8373,8 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status,
     }
   else
     {
-      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)
        {
@@ -8217,8 +8386,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.  */
-      int is_notif;
-      int 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.  */
@@ -8381,7 +8550,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)
@@ -8392,11 +8561,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, false);
 
   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;
@@ -8441,7 +8610,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, false);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
     error (_("Could not read registers; remote failure reply '%s'"),
           rs->buf.data ());
@@ -8455,7 +8624,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, false);
     }
 
   buf_len = strlen (rs->buf.data ());
@@ -8661,7 +8830,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:
@@ -8689,7 +8858,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)
@@ -8700,9 +8869,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, false);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_P]))
+  switch (m_features.packet_ok (rs->buf, PACKET_P))
     {
     case PACKET_OK:
       return 1;
@@ -8749,7 +8918,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, false);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
     error (_("Could not write registers; remote failure reply '%s'"), 
           rs->buf.data ());
@@ -8885,7 +9054,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;
@@ -8904,17 +9073,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, false);
 
        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;
       }
@@ -9108,7 +9277,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, false);
 
   if (rs->buf[0] == 'E')
     return TARGET_XFER_E_IO;
@@ -9139,7 +9308,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";
@@ -9200,7 +9369,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, false);
   if (rs->buf[0] == 'E'
       && isxdigit (rs->buf[1]) && isxdigit (rs->buf[2])
       && rs->buf[3] == '\0')
@@ -9354,7 +9523,7 @@ remote_target::remote_send_printf (const char *format, ...)
     error (_("Communication problem with target."));
 
   rs->buf[0] = '\0';
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
 
   return packet_check_result (rs->buf);
 }
@@ -9474,7 +9643,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;
@@ -9503,7 +9672,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)
@@ -9874,34 +10043,16 @@ show_watchdog (struct ui_file *file, int from_tty,
    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);
-}
-
-
-/* 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;
@@ -9913,7 +10064,7 @@ remote_target::getpkt_or_notif_sane_1 (gdb::char_vector *buf,
 
   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
@@ -9944,7 +10095,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.  */
 
@@ -10011,7 +10162,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;
        }
 
@@ -10026,31 +10177,18 @@ 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 inferior INF that haven't been
    processed by follow_fork.  */
 
@@ -10058,7 +10196,7 @@ void
 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 inferior INF that are stopped
      at a fork event.  */
@@ -10103,11 +10241,10 @@ remote_target::kill ()
 {
   int res = -1;
   inferior *inf = find_inferior_pid (this, inferior_ptid.pid ());
-  struct remote_state *rs = get_remote_state ();
 
   gdb_assert (inf != nullptr);
 
-  if (packet_support (PACKET_vKill) != PACKET_DISABLE)
+  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
@@ -10126,7 +10263,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 +10285,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 +10293,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, false);
 
-  switch (packet_ok (rs->buf,
-                    &remote_protocol_packets[PACKET_vKill]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vKill))
     {
     case PACKET_OK:
       return 0;
@@ -10255,7 +10391,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 +10420,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 +10449,9 @@ remote_target::extended_remote_run (const std::string &args)
   rs->buf[len++] = '\0';
 
   putpkt (rs->buf);
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
 
-  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.  */
@@ -10354,7 +10491,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, false);
   if (strcmp (rs->buf.data (), "OK") != 0)
     warning (_("Unable to %s environment variable '%s' on remote."),
             action, value);
@@ -10367,22 +10504,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, false);
       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 +10534,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 +10557,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, false);
+      if (m_features.packet_ok (rs->buf, PACKET_QSetWorkingDir) != PACKET_OK)
        error (_("\
 Remote replied unexpectedly while setting the inferior's working\n\
 directory: %s"),
@@ -10455,12 +10594,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, false);
       if (strcmp (rs->buf.data (), "OK") != 0)
        error (_("\
 Remote replied unexpectedly while setting startup-with-shell: %s"),
@@ -10515,9 +10654,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 +10679,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 +10700,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 +10729,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, false);
 
-      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 +10759,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 +10778,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, false);
 
       return (rs->buf[0] == 'E');
     }
@@ -10675,7 +10814,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
@@ -10690,9 +10830,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, false);
 
-  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;
@@ -10723,7 +10864,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
@@ -10737,9 +10879,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, false);
 
-  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:
@@ -10812,7 +10955,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.  */
@@ -10833,7 +10976,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
@@ -10872,7 +11015,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
@@ -10899,9 +11042,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, false);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
+  switch (m_features.packet_ok (rs->buf, PACKET_Z1))
     {
     case PACKET_ERROR:
       if (rs->buf[1] == '.')
@@ -10929,7 +11072,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
@@ -10946,9 +11089,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, false);
 
-  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:
@@ -10971,7 +11114,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;
 
@@ -10987,10 +11130,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, false);
 
-      result = packet_ok (rs->buf,
-                         &remote_protocol_packets[PACKET_qCRC]);
+      result = m_features.packet_ok (rs->buf, PACKET_qCRC);
       if (result == PACKET_ERROR)
        return -1;
       else if (result == PACKET_OK)
@@ -11074,8 +11216,8 @@ compare_sections_command (const char *args, int from_tty)
        }
     }
   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)
     gdb_printf (_("No loaded section named '%s'.\n"), args);
 }
@@ -11089,14 +11231,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.  */
@@ -11111,8 +11253,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, false) < 0
+      || m_features.packet_ok (rs->buf, which_packet) != PACKET_OK)
     return TARGET_XFER_E_IO;
 
   unpack_varlen_hex (rs->buf.data (), &n);
@@ -11134,12 +11276,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
@@ -11175,8 +11317,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, false);
+  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')
@@ -11250,13 +11393,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)
@@ -11264,8 +11404,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;
     }
@@ -11294,74 +11433,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;
@@ -11404,7 +11540,7 @@ remote_target::xfer_partial (enum target_object object,
   if (i < 0)
     return TARGET_XFER_E_IO;
 
-  getpkt (&rs->buf, 0);
+  getpkt (&rs->buf, false);
   strcpy ((char *) readbuf, rs->buf.data ());
 
   *xfered_len = strlen ((char *) readbuf);
@@ -11427,8 +11563,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;
@@ -11438,16 +11573,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)
@@ -11459,7 +11593,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).  */
@@ -11488,12 +11622,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, false) < 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);
@@ -11552,7 +11686,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, false) == -1)
        { 
          /* Timeout.  Continue to (try to) read responses.
             This is better than stopping with an error, assuming the stub
@@ -11663,7 +11797,7 @@ send_remote_packet (gdb::array_view<const char> &buf,
 
   remote->putpkt_binary (buf.data (), buf.size ());
   remote_state *rs = remote->get_remote_state ();
-  int bytes = remote->getpkt_sane (&rs->buf, 0);
+  int bytes = remote->getpkt (&rs->buf, false);
 
   if (bytes < 0)
     error (_("error while fetching packet from remote target"));
@@ -11836,8 +11970,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 ())
@@ -11853,7 +11985,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);
@@ -11862,7 +11994,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
@@ -11880,7 +12012,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 ();
@@ -11897,9 +12029,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, false);
+      result = m_features.packet_ok (rs->buf, PACKET_qGetTLSAddr);
       if (result == PACKET_OK)
        {
          ULONGEST addr;
@@ -11927,7 +12058,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 ();
@@ -11940,9 +12071,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, false);
+      result = m_features.packet_ok (rs->buf, PACKET_qGetTIBAddr);
       if (result == PACKET_OK)
        {
          ULONGEST val;
@@ -12193,14 +12323,14 @@ remote_target::remote_hostio_send_command (int command_bytes, int which_packet,
   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, false);
 
   /* If it timed out, something is wrong.  Don't try to parse the
      buffer.  */
@@ -12210,7 +12340,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;
@@ -12280,7 +12410,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)
@@ -12294,7 +12424,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)
@@ -12440,14 +12570,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;
     }
 
@@ -12481,10 +12611,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)
     {
@@ -12492,7 +12622,7 @@ 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);
 }
 
@@ -12666,7 +12796,7 @@ remote_target::filesystem_is_local ()
      does not support vFile:open.  */
   if (gdb_sysroot == TARGET_SYSROOT_PREFIX)
     {
-      enum packet_support ps = packet_support (PACKET_vFile_open);
+      packet_support ps = m_features.packet_support (PACKET_vFile_open);
 
       if (ps == PACKET_SUPPORT_UNKNOWN)
        {
@@ -12683,7 +12813,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)
@@ -12988,8 +13118,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;
@@ -13011,58 +13141,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
@@ -13221,7 +13351,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);
@@ -13230,12 +13360,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';
        }
@@ -13306,7 +13436,7 @@ 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->locspec != nullptr)
        {
@@ -13463,7 +13593,8 @@ remote_target::trace_set_readonly_regions ()
       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;
@@ -13475,7 +13606,7 @@ Too many sections for read-only sections definition packet."));
   if (anysecs)
     {
       putpkt (rs->buf);
-      getpkt (&rs->buf, 0);
+      getpkt (&rs->buf, false);
     }
 }
 
@@ -13500,7 +13631,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.  */
@@ -13523,7 +13654,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)
@@ -13555,14 +13686,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)
@@ -13778,7 +13909,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;
 
@@ -13798,7 +13930,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;
@@ -13872,7 +14004,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 ();
@@ -13892,8 +14024,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 ());
@@ -13949,14 +14080,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, false);
 
       if (strcmp (rs->buf.data (), "OK") == 0)
        {
@@ -13971,7 +14102,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
@@ -13996,7 +14127,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;
 
@@ -14004,18 +14134,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, false);
 
-      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);
@@ -14026,18 +14157,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, false);
 
-      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);
@@ -14078,7 +14210,7 @@ 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;
 
   for (thread_info *tp : all_non_exited_threads (this))
@@ -14132,17 +14264,21 @@ remote_target::enable_btrace (thread_info *tp,
   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."));
 
@@ -14151,11 +14287,12 @@ remote_target::enable_btrace (thread_info *tp,
   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, false);
 
-  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"),
@@ -14188,21 +14325,21 @@ remote_target::enable_btrace (thread_info *tp,
 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, false);
 
-  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 +14368,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)
@@ -14277,8 +14413,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.  */
@@ -14299,7 +14436,7 @@ 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);
@@ -14330,13 +14467,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
@@ -14380,7 +14514,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);
@@ -14474,15 +14608,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, false);
 
-  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)
@@ -14565,7 +14698,7 @@ remote_new_objfile (struct objfile *objfile)
        continue;
 
       /* Need to switch to a specific thread, because remote_check_symbols will
-         set the general thread using INFERIOR_PTID.
+        set the general thread using INFERIOR_PTID.
 
         It's possible to have inferiors with no thread here, because we are
         called very early in the connection process, while the inferior is
@@ -14594,14 +14727,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, false);
   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, false);
       p = rs->buf.data ();
     }
   return 0;
@@ -14615,14 +14748,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, false);
   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, false);
       p = rs->buf.data ();
     }
   return 0;
@@ -14646,10 +14779,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);
 }
 
@@ -14692,7 +14822,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.  */
@@ -14758,7 +14888,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 ();
@@ -14766,7 +14896,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, false);
 
   return parse_fetch_memtags_reply (rs->buf, tags);
 }
@@ -14778,7 +14908,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 ();
@@ -14786,7 +14916,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, false);
 
   /* Verify if the request was successful.  */
   return packet_check_result (rs->buf.data ()) == PACKET_OK;
@@ -14813,7 +14943,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);
@@ -14974,16 +15104,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,
@@ -15028,257 +15158,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
@@ -15311,7 +15405,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));
       }
   }