diff --git a/gdb/NEWS b/gdb/NEWS
index e61f06081de..2d5e8a1cdbe 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,20 @@
 
 *** Changes since GDB 13
 
+* Multi-target feature configuration
+
+  GDB now supports the individual configuration of remote target's feature
+  sets.  Based on the current selection of a target, the commands 'set remote
+  <name>-packet (on|off|auto)' and 'show remote <name>-packet' can be used to
+  configure a target's feature packet and to display its configuration,
+  respectively.
+
+  The configuration of the packet itself applies to the currently selected
+  target (if available).  If no target is selected, it applies to future remote
+  connections.  Similarly, the show commands print the configuration of the
+  currently selected target.  If no remote target is selected, the default
+  configuration for future connections is shown.
+
 * MI version 1 has been removed.
 
 *** Changes in GDB 13
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index bef63eb4e8e..3babe8b2a9d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23845,8 +23845,14 @@ in @value{GDBN}.  You may want to report the problem to the
 @value{GDBN} developers.
 
 For each packet @var{name}, the command to enable or disable the
-packet is @code{set remote @var{name}-packet}.  The available settings
-are:
+packet is @code{set remote @var{name}-packet}.  If you configure a packet, the
+configuration will apply for all future remote targets if no target is selected.
+In case there is a target selected, only the configuration of the current target
+is changed.  All other existing remote targets' features are not affected.
+The command to print the current configuration of a packet is
+@code{show remote @var{name}-packet}.  It displays the current remote target's
+configuration.  If no remote target is selected, the default configuration for
+future connections is shown.  The available settings are:
 
 @multitable @columnfractions 0.28 0.32 0.25
 @item Command Name
diff --git a/gdb/remote.c b/gdb/remote.c
index ea968ee0c59..3fc70c19a91 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -71,12 +71,12 @@
 #include "gdbsupport/agent.h"
 #include "btrace.h"
 #include "record-btrace.h"
-#include <algorithm>
 #include "gdbsupport/scoped_restore.h"
 #include "gdbsupport/environ.h"
 #include "gdbsupport/byte-vector.h"
 #include "gdbsupport/search.h"
 #include <algorithm>
+#include <iterator>
 #include <unordered_map>
 #include "async-event.h"
 #include "gdbsupport/selftest.h"
@@ -117,6 +117,36 @@ enum packet_support
     PACKET_DISABLE
   };
 
+/* Convert the packet support auto_boolean to a name used for gdb printing.  */
+
+static const char *
+get_packet_support_name (auto_boolean support)
+{
+  switch (support)
+    {
+      case AUTO_BOOLEAN_TRUE:
+	return "on";
+      case AUTO_BOOLEAN_FALSE:
+	return "off";
+      case AUTO_BOOLEAN_AUTO:
+	return "auto";
+      default:
+	gdb_assert_not_reached ("invalid var_auto_boolean");
+    }
+}
+
+/* Convert the target type (future remote target or currently connected target)
+   to a name used for gdb printing.  */
+
+static const char *
+get_target_type_name (bool target_connected)
+{
+  if (target_connected)
+    return _("on the current remote target");
+  else
+    return _("on future remote targets");
+}
+
 /* Analyze a packet's return value and update the packet config
    accordingly.  */
 
@@ -127,6 +157,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.
@@ -395,6 +574,97 @@ 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;
+  };
+
+/* 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 ()
+  {
+    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);
+
+  /* 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:
@@ -585,8 +855,16 @@ class remote_target : public process_stratum_target
 
   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;
@@ -933,19 +1211,21 @@ class remote_target : public process_stratum_target
 					 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);
@@ -1068,7 +1348,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,
@@ -1890,34 +2175,52 @@ remote_target::get_memory_read_packet_size ()
   return size;
 }
 
-
+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);
 
-static enum packet_support packet_config_support (struct packet_config *config);
-static enum packet_support packet_support (int packet);
+      if (remote != nullptr)
+	remote->m_features.m_protocol_packets[packet_idx].detect = value;
+      else
+	remote_protocol_packets[packet_idx].detect = value;
+
+      gdb_printf (_("Support for the '%s' packet %s is set to \"%s\".\n"), name,
+		  target_type, support);
+      return;
+    }
+
+  internal_error (_("Could not find config for %s"), c->name);
+}
 
 static void
-show_packet_config_cmd (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))
     {
@@ -1931,308 +2234,156 @@ show_packet_config_cmd (ui_file *file, struct packet_config *config)
       support = "unknown";
       break;
     }
-  switch (config->detect)
-    {
-    case AUTO_BOOLEAN_AUTO:
-      gdb_printf (file,
-		  _("Support for the `%s' packet "
-		    "is auto-detected, currently %s.\n"),
-		  config->name, 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);
-      break;
-    }
-}
-
-static void
-add_packet_config_cmd (struct packet_config *config, const char *name,
-		       const char *title, int legacy)
-{
-  config->name = name;
-  config->title = title;
-  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,
+  switch (config->detect)
+    {
+    case AUTO_BOOLEAN_AUTO:
+      gdb_printf (file,
+		  _("Support for the '%s' packet %s is \"auto\", "
+		    "currently %s.\n"),
+		  packets_descriptions[which_packet].name, target_type,
+		  support);
+      break;
+    case AUTO_BOOLEAN_TRUE:
+    case AUTO_BOOLEAN_FALSE:
+      gdb_printf (file,
+		  _("Support for the '%s' packet %s is \"%s\".\n"),
+		  packets_descriptions[which_packet].name, target_type,
+		  get_packet_support_name (config->detect));
+      break;
+    }
+}
 
-  /* Support for the Qbtrace-conf:bts:size packet.  */
-  PACKET_Qbtrace_conf_bts_size,
+static void
+add_packet_config_cmd (const unsigned int which_packet, const char *name,
+		       const char *title, int legacy)
+{
+  packets_descriptions[which_packet].name = name;
+  packets_descriptions[which_packet].title = title;
 
-  /* Support for swbreak+ feature.  */
-  PACKET_swbreak_feature,
+  packet_config *config = &remote_protocol_packets[which_packet];
 
-  /* Support for hwbreak+ feature.  */
-  PACKET_hwbreak_feature,
+  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 */
+				    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
@@ -2240,7 +2391,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)
     {
@@ -2255,14 +2406,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);
 }
 
@@ -2271,21 +2418,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?  */
@@ -2309,10 +2454,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
@@ -2320,52 +2478,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
@@ -2374,9 +2491,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
@@ -2394,9 +2509,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
@@ -2414,9 +2527,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
@@ -2445,10 +2556,10 @@ 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");
@@ -2456,8 +2567,7 @@ remote_target::remote_query_attached (int pid)
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  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)
@@ -2657,8 +2767,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);
@@ -2721,7 +2830,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;
@@ -2755,7 +2864,7 @@ remote_target::pass_signals (gdb::array_view<const unsigned char> pass_signals)
 	{
 	  putpkt (pass_packet);
 	  getpkt (&rs->buf, 0);
-	  packet_ok (rs->buf, &remote_protocol_packets[PACKET_QPassSignals]);
+	  m_features.packet_ok (rs->buf, PACKET_QPassSignals);
 	  xfree (rs->last_pass_packet);
 	  rs->last_pass_packet = pass_packet;
 	}
@@ -2775,7 +2884,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;
@@ -2828,7 +2937,7 @@ remote_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
 
   putpkt (catch_packet);
   getpkt (&rs->buf, 0);
-  result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QCatchSyscalls]);
+  result = m_features.packet_ok (rs->buf, PACKET_QCatchSyscalls);
   if (result == PACKET_OK)
     return 0;
   else
@@ -2841,7 +2950,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;
@@ -2876,7 +2985,7 @@ remote_target::program_signals (gdb::array_view<const unsigned char> signals)
 	{
 	  putpkt (packet);
 	  getpkt (&rs->buf, 0);
-	  packet_ok (rs->buf, &remote_protocol_packets[PACKET_QProgramSignals]);
+	  m_features.packet_ok (rs->buf, PACKET_QProgramSignals);
 	  xfree (rs->last_program_signals_packet);
 	  rs->last_program_signals_packet = packet;
 	}
@@ -2942,12 +3051,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 ())
@@ -3097,9 +3206,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)
@@ -3861,7 +3969,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);
@@ -4053,7 +4161,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,
@@ -4478,7 +4586,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 ();
@@ -4489,7 +4596,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
@@ -4751,7 +4858,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
@@ -4775,7 +4881,7 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
   remote_query_supported ();
 
   /* 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
@@ -4791,7 +4897,10 @@ remote_target::start_remote_1 (int from_tty, int extended_p)
     putpkt (v_mustreplyempty);
     getpkt (&rs->buf, 0);
     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 ());
@@ -4810,12 +4919,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)
+      if (m_features.packet_ok (rs->buf, PACKET_QStartNoAckMode) == PACKET_OK)
 	rs->noack_mode = 1;
     }
 
@@ -4845,7 +4953,7 @@ 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"));
 
@@ -4862,7 +4970,7 @@ 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.  */
@@ -5103,16 +5211,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.  */
@@ -5142,7 +5247,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
@@ -5158,7 +5263,7 @@ remote_target::remote_check_symbols ()
 
   putpkt ("qSymbol::");
   getpkt (&reply, 0);
-  packet_ok (reply, &remote_protocol_packets[PACKET_qSymbol]);
+  m_features.packet_ok (reply, PACKET_qSymbol);
 
   while (startswith (reply.data (), "qSymbol:"))
     {
@@ -5282,7 +5387,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
@@ -5490,47 +5595,57 @@ 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;
@@ -5540,8 +5655,7 @@ remote_target::remote_query_supported ()
 
       /* If an error occured, 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;
@@ -5818,7 +5932,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;
@@ -5931,7 +6045,7 @@ 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");
@@ -6062,10 +6176,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
@@ -6131,7 +6245,7 @@ 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);
@@ -6140,8 +6254,7 @@ extended_remote_target::attach (const char *args, int from_tty)
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  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 ())
@@ -6282,7 +6395,7 @@ remote_target::remote_vcont_probe ()
 	buf[0] = 0;
     }
 
-  packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCont]);
+  m_features.packet_ok (rs->buf, PACKET_vCont);
   rs->supports_vCont_probed = true;
 }
 
@@ -6312,7 +6425,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;
 
@@ -6346,7 +6459,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;
 
@@ -6430,9 +6543,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");
@@ -6469,10 +6582,10 @@ 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)
+  if (m_features.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 ();
@@ -7007,7 +7120,7 @@ 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
+  if (m_features.packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN
       || !rs->supports_vCont_probed)
     remote_vcont_probe ();
 
@@ -7015,7 +7128,7 @@ remote_target::remote_stop_ns (ptid_t ptid)
     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
     {
@@ -7089,7 +7202,7 @@ remote_target::remote_interrupt_ns ()
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCtrlC]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vCtrlC))
     {
     case PACKET_OK:
       break;
@@ -7597,7 +7710,8 @@ Packet: '%s'\n"),
 
 	      /* Make sure the stub doesn't forget to indicate support
 		 with qSupported.  */
-	      if (packet_support (PACKET_swbreak_feature) != PACKET_ENABLE)
+	      if (m_features.packet_support (PACKET_swbreak_feature)
+		  != PACKET_ENABLE)
 		error (_("Unexpected swbreak stop reason"));
 
 	      /* The value part is documented as "must be empty",
@@ -7611,7 +7725,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.  */
@@ -8382,7 +8497,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)
@@ -8397,7 +8512,7 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
 
   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;
@@ -8662,7 +8777,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:
@@ -8690,7 +8805,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)
@@ -8703,7 +8818,7 @@ remote_target::store_register_using_P (const struct regcache *regcache,
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_P]))
+  switch (m_features.packet_ok (rs->buf, PACKET_P))
     {
     case PACKET_OK:
       return 1;
@@ -8886,7 +9001,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;
@@ -8910,12 +9025,12 @@ remote_target::check_binary_download (CORE_ADDR addr)
 	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;
       }
@@ -9140,7 +9255,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";
@@ -10104,11 +10219,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
@@ -10127,7 +10241,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 ();
@@ -10149,7 +10263,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 ();
@@ -10159,8 +10273,7 @@ remote_target::remote_vkill (int pid)
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  switch (packet_ok (rs->buf,
-		     &remote_protocol_packets[PACKET_vKill]))
+  switch (m_features.packet_ok (rs->buf, PACKET_vKill))
     {
     case PACKET_OK:
       return 0;
@@ -10256,7 +10369,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
@@ -10284,7 +10398,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;");
@@ -10315,7 +10429,7 @@ remote_target::extended_remote_run (const std::string &args)
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  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.  */
@@ -10368,7 +10482,7 @@ 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);
@@ -10378,12 +10492,16 @@ remote_target::extended_remote_environment_support ()
 
   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 ());
 }
@@ -10394,7 +10512,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 ();
@@ -10418,9 +10536,7 @@ 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)
+      if (m_features.packet_ok (rs->buf, PACKET_QSetWorkingDir) != PACKET_OK)
 	error (_("\
 Remote replied unexpectedly while setting the inferior's working\n\
 directory: %s"),
@@ -10456,7 +10572,7 @@ 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);
@@ -10562,7 +10678,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;
@@ -10593,7 +10709,7 @@ remote_target::insert_breakpoint (struct gdbarch *gdbarch,
       putpkt (rs->buf);
       getpkt (&rs->buf, 0);
 
-      switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0]))
+      switch (m_features.packet_ok (rs->buf, PACKET_Z0))
 	{
 	case PACKET_ERROR:
 	  return -1;
@@ -10621,7 +10737,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 ();
@@ -10676,7 +10792,7 @@ 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 (PACKET_Z0 + packet) == PACKET_DISABLE)
     return 1;
 
   /* Make sure the remote is pointing at the right process, if
@@ -10693,7 +10809,7 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len,
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+  switch (m_features.packet_ok (rs->buf, PACKET_Z0 + packet))
     {
     case PACKET_ERROR:
       return -1;
@@ -10724,7 +10840,7 @@ 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 (PACKET_Z0 + packet) == PACKET_DISABLE)
     return -1;
 
   /* Make sure the remote is pointing at the right process, if
@@ -10740,7 +10856,7 @@ remote_target::remove_watchpoint (CORE_ADDR addr, int len,
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+  switch (m_features.packet_ok (rs->buf, PACKET_Z0 + packet))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -10813,7 +10929,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.  */
@@ -10834,7 +10950,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
@@ -10873,7 +10989,7 @@ remote_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
   char *p, *endbuf;
   char *message;
 
-  if (packet_support (PACKET_Z1) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_Z1) == PACKET_DISABLE)
     return -1;
 
   /* Make sure the remote is pointing at the right process, if
@@ -10902,7 +11018,7 @@ remote_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  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] == '.')
@@ -10930,7 +11046,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
@@ -10949,7 +11065,7 @@ remote_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
 
-  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:
@@ -10972,7 +11088,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;
 
@@ -10990,8 +11106,7 @@ remote_target::verify_memory (const gdb_byte *data, CORE_ADDR lma, ULONGEST size
 
       getpkt (&rs->buf, 0);
 
-      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)
@@ -11090,14 +11205,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.  */
@@ -11113,7 +11228,7 @@ remote_target::remote_write_qxfer (const char *object_name,
 
   if (putpkt_binary (rs->buf.data (), i + buf_len) < 0
       || getpkt_sane (&rs->buf, 0) < 0
-      || packet_ok (rs->buf, packet) != PACKET_OK)
+      || m_features.packet_ok (rs->buf, which_packet) != PACKET_OK)
     return TARGET_XFER_E_IO;
 
   unpack_varlen_hex (rs->buf.data (), &n);
@@ -11135,12 +11250,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
@@ -11177,7 +11292,8 @@ remote_target::remote_read_qxfer (const char *object_name,
 
   rs->buf[0] = '\0';
   packet_len = getpkt_sane (&rs->buf, 0);
-  if (packet_len < 0 || packet_ok (rs->buf, packet) != PACKET_OK)
+  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')
@@ -11251,13 +11367,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)
@@ -11265,8 +11378,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;
     }
@@ -11295,74 +11407,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;
@@ -11428,8 +11537,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;
@@ -11446,9 +11554,8 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_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)
@@ -11460,7 +11567,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).  */
@@ -11490,11 +11597,11 @@ remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
 
   if (putpkt_binary (rs->buf.data (), i + escaped_pattern_len) < 0
       || getpkt_sane (&rs->buf, 0) < 0
-      || packet_ok (rs->buf, packet) != PACKET_OK)
+      || 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);
@@ -11837,8 +11944,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 ())
@@ -11854,7 +11959,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);
@@ -11863,7 +11968,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
@@ -11881,7 +11986,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 ();
@@ -11899,8 +12004,7 @@ remote_target::get_thread_local_address (ptid_t ptid, CORE_ADDR lm,
 
       putpkt (rs->buf);
       getpkt (&rs->buf, 0);
-      result = packet_ok (rs->buf,
-			  &remote_protocol_packets[PACKET_qGetTLSAddr]);
+      result = m_features.packet_ok (rs->buf, PACKET_qGetTLSAddr);
       if (result == PACKET_OK)
 	{
 	  ULONGEST addr;
@@ -11928,7 +12032,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 ();
@@ -11942,8 +12046,7 @@ remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 
       putpkt (rs->buf);
       getpkt (&rs->buf, 0);
-      result = packet_ok (rs->buf,
-			  &remote_protocol_packets[PACKET_qGetTIBAddr]);
+      result = m_features.packet_ok (rs->buf, PACKET_qGetTIBAddr);
       if (result == PACKET_OK)
 	{
 	  ULONGEST val;
@@ -12194,7 +12297,7 @@ 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;
@@ -12211,7 +12314,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;
@@ -12281,7 +12384,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)
@@ -12295,7 +12398,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)
@@ -12667,7 +12770,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)
 	{
@@ -12684,7 +12787,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)
@@ -12989,8 +13092,8 @@ remote_delete_command (const char *args, int from_tty)
 bool
 remote_target::can_execute_reverse ()
 {
-  if (packet_support (PACKET_bs) == PACKET_ENABLE
-      || packet_support (PACKET_bc) == PACKET_ENABLE)
+  if (m_features.packet_support (PACKET_bs) == PACKET_ENABLE
+      || m_features.packet_support (PACKET_bc) == PACKET_ENABLE)
     return true;
   else
     return false;
@@ -13012,58 +13115,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
@@ -13307,7 +13410,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)
 	{
@@ -13464,7 +13567,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;
@@ -13501,7 +13605,7 @@ remote_target::get_trace_status (struct trace_status *ts)
   enum packet_result result;
   struct remote_state *rs = get_remote_state ();
 
-  if (packet_support (PACKET_qTStatus) == PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_qTStatus) == PACKET_DISABLE)
     return -1;
 
   /* FIXME we need to get register block size some other way.  */
@@ -13524,7 +13628,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)
@@ -13779,7 +13883,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;
 
@@ -13873,7 +13978,7 @@ remote_target::get_min_fast_tracepoint_insn_len ()
 void
 remote_target::set_trace_buffer_size (LONGEST val)
 {
-  if (packet_support (PACKET_QTBuffer_size) != PACKET_DISABLE)
+  if (m_features.packet_support (PACKET_QTBuffer_size) != PACKET_DISABLE)
     {
       struct remote_state *rs = get_remote_state ();
       char *buf = rs->buf.data ();
@@ -13893,8 +13998,7 @@ remote_target::set_trace_buffer_size (LONGEST val)
 
       putpkt (rs->buf);
       remote_get_noisy_reply ();
-      result = packet_ok (rs->buf,
-		  &remote_protocol_packets[PACKET_QTBuffer_size]);
+      result = m_features.packet_ok (rs->buf, PACKET_QTBuffer_size);
 
       if (result != PACKET_OK)
 	warning (_("Bogus reply from target: %s"), rs->buf.data ());
@@ -13950,7 +14054,7 @@ 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 ();
 
@@ -13972,7 +14076,7 @@ remote_target::use_agent (bool use)
 bool
 remote_target::can_use_agent ()
 {
-  return (packet_support (PACKET_QAgent) != PACKET_DISABLE);
+  return (m_features.packet_support (PACKET_QAgent) != PACKET_DISABLE);
 }
 
 struct btrace_target_info
@@ -13997,7 +14101,6 @@ remote_btrace_reset (remote_state *rs)
 void
 remote_target::btrace_sync_conf (const btrace_config *conf)
 {
-  struct packet_config *packet;
   struct remote_state *rs;
   char *buf, *pos, *endbuf;
 
@@ -14005,18 +14108,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);
 
-      if (packet_ok (buf, packet) == PACKET_ERROR)
+      if (m_features.packet_ok (buf, PACKET_Qbtrace_conf_bts_size)
+	  == PACKET_ERROR)
 	{
 	  if (buf[0] == 'E' && buf[1] == '.')
 	    error (_("Failed to configure the BTS buffer size: %s"), buf + 2);
@@ -14027,18 +14131,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);
 
-      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);
@@ -14079,7 +14184,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))
@@ -14133,17 +14238,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."));
 
@@ -14152,11 +14261,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);
 
-  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"),
@@ -14189,21 +14299,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);
 
-  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"),
@@ -14232,10 +14342,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)
@@ -14278,8 +14387,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.  */
@@ -14300,7 +14410,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);
@@ -14331,11 +14441,11 @@ 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)
+      if (m_features.packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
 	remote_vcont_probe ();
 
       return rs->supports_vCont.s && rs->supports_vCont.S;
@@ -14475,15 +14585,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);
 
-  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)
@@ -14647,10 +14756,10 @@ show_range_stepping (struct ui_file *file, int from_tty,
 bool
 remote_target::vcont_r_supported ()
 {
-  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
+  if (m_features.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);
 }
 
@@ -14693,7 +14802,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.  */
@@ -14759,7 +14868,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 ();
@@ -14779,7 +14888,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 ();
@@ -14814,7 +14923,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);
@@ -15029,257 +15138,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
@@ -15312,7 +15385,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));
       }
   }
 
diff --git a/gdb/testsuite/gdb.base/cond-eval-mode.exp b/gdb/testsuite/gdb.base/cond-eval-mode.exp
index 61c28b5925d..749e0334ae1 100644
--- a/gdb/testsuite/gdb.base/cond-eval-mode.exp
+++ b/gdb/testsuite/gdb.base/cond-eval-mode.exp
@@ -59,13 +59,18 @@ gdb_test_multiple $test_target $test_target {
 # evaluation.  Now make sure we can force-disable the
 # ConditionalBreakpoints RSP feature.
 if [gdb_is_target_remote] {
-    gdb_test_no_output "set remote conditional-breakpoints-packet off"
+    gdb_test \
+	"set remote conditional-breakpoints-packet off" \
+	"Support for the 'ConditionalBreakpoints' packet on the current remote target is set to \"off\"."
 
     gdb_test $test_target "$warning" \
 	"set breakpoint condition-evaluation target, with support disabled"
 
     # Confirm we can re-enable it.
-    gdb_test_no_output "set remote conditional-breakpoints-packet on"
+    gdb_test \
+	"set remote conditional-breakpoints-packet on" \
+	"Support for the 'ConditionalBreakpoints' packet on the current remote target is set to \"on\"."
+
     gdb_test_no_output $test_target "restore $test_target"
 }
 
diff --git a/gdb/testsuite/gdb.base/dprintf.exp b/gdb/testsuite/gdb.base/dprintf.exp
index 7b89a0db9bd..5b2fb4c6de9 100644
--- a/gdb/testsuite/gdb.base/dprintf.exp
+++ b/gdb/testsuite/gdb.base/dprintf.exp
@@ -214,7 +214,10 @@ gdb_test "set dprintf-style foobar" "Undefined item: \"foobar\"." \
 # as expected.  dprintf relies on support for target-side breakpoint
 # commands --- use it as proxy.
 if [gdb_is_target_remote] {
-    gdb_test_no_output "set remote breakpoint-commands-packet off"
+    gdb_test \
+	"set remote breakpoint-commands-packet off" \
+	"Support for the 'BreakpointCommands' packet on the current remote target is set to \"off\"."
+
     gdb_test "set dprintf-style agent" \
 	"warning: Target cannot run dprintf commands.*" \
 	"set dprintf-style agent, with feature disabled"
diff --git a/gdb/testsuite/gdb.base/find-unmapped.exp b/gdb/testsuite/gdb.base/find-unmapped.exp
index e9c70e5ada9..f3633decc98 100644
--- a/gdb/testsuite/gdb.base/find-unmapped.exp
+++ b/gdb/testsuite/gdb.base/find-unmapped.exp
@@ -78,7 +78,10 @@ if {[target_info gdb_protocol] == "remote"
     || [target_info gdb_protocol] == "extended-remote"} {
     test_not_found 0
     with_test_prefix "search-memory-packet off" {
-	gdb_test_no_output "set remote search-memory-packet off"
+	gdb_test \
+	    "set remote search-memory-packet off" \
+	    "Support for the 'qSearch:memory' packet on the current remote target is set to \"off\"."
+
 	test_not_found 0
     }
 } else {
diff --git a/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp b/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp
index 4836e133107..a3cfa6d00ba 100644
--- a/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp
+++ b/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp
@@ -54,7 +54,9 @@ gdb_test_no_output "set breakpoint always-inserted on"
 # Force-disable Z1 packets, in case the target actually supports
 # these.
 if {$is_target_remote} {
-    gdb_test_no_output "set remote Z-packet off"
+    gdb_test \
+	"set remote Z-packet off" \
+	"Use of Z packets on the current remote target is set to \"off\"."
 }
 
 # Probe for hw breakpoints support.  With Z packets disabled, this
diff --git a/gdb/testsuite/gdb.base/remote.exp b/gdb/testsuite/gdb.base/remote.exp
index 4c2bc251d47..58d11f5dd1f 100644
--- a/gdb/testsuite/gdb.base/remote.exp
+++ b/gdb/testsuite/gdb.base/remote.exp
@@ -197,7 +197,7 @@ gdb_test_no_output "set remote hardware-breakpoint-limit 2147483647"
 
 # Check the X/P/p alias commands display the correct packet names.
 foreach pkt {X P p} {
-    gdb_test "show remote ${pkt}-packet" "Support for the `${pkt}' packet is.*"
+    gdb_test "show remote ${pkt}-packet" "Support for the '${pkt}' packet on the current remote target is .*"
 }
 
 gdb_exit
diff --git a/gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp b/gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp
index 8b0c6c91a2a..712dd0b7e5a 100644
--- a/gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp
+++ b/gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp
@@ -30,15 +30,13 @@ set run_python_tests [expr ! [skip_python_tests]]
 # indicates whether the multi-process feature of remote targets is
 # turned off or on.
 proc test_info_inferiors {multi_process} {
-    setup "off"
+
+    setup "off" $multi_process
 
     if { $::run_python_tests } {
 	gdb_test_no_output "source ${::remote_python_file}" "load python file"
     }
 
-    gdb_test_no_output \
-	"set remote multiprocess-feature-packet $multi_process"
-
     # Get the description for inferior INF for when the current
     # inferior id is CURRENT.
     proc inf_desc {inf current} {
diff --git a/gdb/testsuite/gdb.multi/multi-target.exp.tcl b/gdb/testsuite/gdb.multi/multi-target.exp.tcl
index 8e0c39679b7..6764d7215db 100644
--- a/gdb/testsuite/gdb.multi/multi-target.exp.tcl
+++ b/gdb/testsuite/gdb.multi/multi-target.exp.tcl
@@ -104,7 +104,7 @@ proc cleanup_gdbservers { } {
 
 # Return true on success, false otherwise.
 
-proc setup {non-stop} {
+proc setup {non-stop {multi_process ""}} {
     global gcorefile gcore_created
     global binfile
 
@@ -123,6 +123,12 @@ proc setup {non-stop} {
 
     gdb_test_no_output "set non-stop ${non-stop}"
 
+    if {${multi_process} ne ""} then {
+	gdb_test \
+	    "set remote multiprocess-feature-packet $multi_process" \
+	    "Support for the 'multiprocess-feature' packet on future remote targets is set to \"${multi_process}\"."
+    }
+
     if ![runto all_started] then {
 	return 0
     }
diff --git a/gdb/testsuite/gdb.server/connect-without-multi-process.exp b/gdb/testsuite/gdb.server/connect-without-multi-process.exp
index c4bbcac72fa..5acbfc282e9 100644
--- a/gdb/testsuite/gdb.server/connect-without-multi-process.exp
+++ b/gdb/testsuite/gdb.server/connect-without-multi-process.exp
@@ -47,7 +47,9 @@ proc do_test {multiprocess} {
     # extended-remote board, therefore already connected.
     gdb_test "disconnect" ".*"
 
-    gdb_test_no_output "set remote multiprocess-feature $multiprocess"
+    gdb_test \
+	"set remote multiprocess-feature $multiprocess" \
+	"Support for the 'multiprocess-feature' packet on future remote targets is set to \"$multiprocess\"."
 
     set res [gdbserver_spawn ""]
     set gdbserver_protocol [lindex $res 0]
diff --git a/gdb/testsuite/gdb.server/exit-multiple-threads.exp b/gdb/testsuite/gdb.server/exit-multiple-threads.exp
index 23ac512ef70..0f84d7262a6 100644
--- a/gdb/testsuite/gdb.server/exit-multiple-threads.exp
+++ b/gdb/testsuite/gdb.server/exit-multiple-threads.exp
@@ -57,9 +57,14 @@ proc prepare_for_test { executable disable_multi_process } {
 
     # Disable XML-based thread listing, and possible the multi-process
     # extensions.
-    gdb_test_no_output "set remote threads-packet off"
+    gdb_test \
+	"set remote threads-packet off" \
+	"Support for the 'qXfer:threads:read' packet on future remote targets is set to \"off\"."
+
     if { $disable_multi_process } {
-	gdb_test_no_output "set remote multiprocess-feature-packet off"
+	gdb_test \
+	    "set remote multiprocess-feature-packet off" \
+	    "Support for the 'multiprocess-feature' packet on future remote targets is set to \"off\"."
     }
 
     # Start gdbserver and connect.
diff --git a/gdb/testsuite/gdb.server/ext-restart.exp b/gdb/testsuite/gdb.server/ext-restart.exp
index ac03caa0aaf..27db715ac66 100644
--- a/gdb/testsuite/gdb.server/ext-restart.exp
+++ b/gdb/testsuite/gdb.server/ext-restart.exp
@@ -53,7 +53,10 @@ gdb_test "run" "Breakpoint.* main .*" "run to main"
 with_test_prefix "restart" {
     # Disable vRun packet and clear remote exec-file, so that GDB will
     # use R packet to restart the process.
-    gdb_test_no_output "set remote run-packet off"
+    gdb_test \
+	"set remote run-packet off" \
+	"Support for the 'vRun' packet on the current remote target is set to \"off\"."
+
     gdb_test_no_output "set remote exec-file"
 
     set test "run to main"
diff --git a/gdb/testsuite/gdb.server/ext-wrapper.exp b/gdb/testsuite/gdb.server/ext-wrapper.exp
index 4c6cea4cd89..7422b904d3e 100644
--- a/gdb/testsuite/gdb.server/ext-wrapper.exp
+++ b/gdb/testsuite/gdb.server/ext-wrapper.exp
@@ -57,7 +57,10 @@ gdb_test "print d" "\\$${decimal} = ${hex} \"1\".*"
 with_test_prefix "restart" {
     # Disable vRun packet and clear remote exec-file, so that GDB will
     # use R packet to restart the process.
-    gdb_test_no_output "set remote run-packet off"
+    gdb_test \
+	"set remote run-packet off" \
+	"Support for the 'vRun' packet on the current remote target is set to \"off\"."
+
     gdb_test_no_output "set remote exec-file"
     set test "run to marker"
     gdb_test_multiple "run" $test {
diff --git a/gdb/testsuite/gdb.server/server-exec-info.exp b/gdb/testsuite/gdb.server/server-exec-info.exp
index 8ab33af3364..a4b727b9c05 100644
--- a/gdb/testsuite/gdb.server/server-exec-info.exp
+++ b/gdb/testsuite/gdb.server/server-exec-info.exp
@@ -31,7 +31,10 @@ if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] {
 # extended-remote board, therefore already connected.
 gdb_test "disconnect" ".*"
 
-gdb_test_no_output "set remote pid-to-exec-file-packet off"
+gdb_test \
+    "set remote pid-to-exec-file-packet off" \
+    "Support for the 'qXfer:exec-file:read' packet on future remote targets is set to \"off\"."
+
 gdb_test "file" ".*" "file" \
 	 {Discard symbol table from `.*'\? \(y or n\) } "y"
 gdbserver_run ""
diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp
index 93daf482907..3d7ef41b4a1 100644
--- a/gdb/testsuite/gdb.server/server-kill.exp
+++ b/gdb/testsuite/gdb.server/server-kill.exp
@@ -116,7 +116,9 @@ proc_with_prefix test_tstatus {} {
     # Enable trace status packet which is disabled after the
     # connection if the remote target doesn't support tracepoint at
     # all.  Otherwise, no RSP packet is sent out.
-    gdb_test_no_output "set remote trace-status-packet on"
+    gdb_test \
+	"set remote trace-status-packet on" \
+	"Support for the 'qTStatus' packet on the current remote target is set to \"on\"."
 
     # Force GDB to talk with GDBserver, so that we can get the
     # "connection closed" error.
diff --git a/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp b/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp
index 3bc7cbed52e..a4b82cf68d4 100644
--- a/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp
+++ b/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp
@@ -71,8 +71,12 @@ proc run_test { target_non_stop disable_feature } {
     set gdbserver_gdbport [lindex $res 1]
 
     # Disable XML-based thread listing, and multi-process extensions.
-    gdb_test_no_output "set remote threads-packet off"
-    gdb_test_no_output "set remote multiprocess-feature-packet off"
+    gdb_test \
+	"set remote threads-packet off" \
+	"Support for the 'qXfer:threads:read' packet on future remote targets is set to \"off\"."
+    gdb_test \
+	"set remote multiprocess-feature-packet off" \
+	"Support for the 'multiprocess-feature' packet on future remote targets is set to \"off\"."
 
     set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport]
     if ![gdb_assert {$res == 0} "connect"] {
diff --git a/gdb/testsuite/gdb.server/stop-reply-no-thread.exp b/gdb/testsuite/gdb.server/stop-reply-no-thread.exp
index 488a5859961..1594a893eaa 100644
--- a/gdb/testsuite/gdb.server/stop-reply-no-thread.exp
+++ b/gdb/testsuite/gdb.server/stop-reply-no-thread.exp
@@ -59,8 +59,13 @@ proc run_test { disable_feature target_nonstop } {
     set gdbserver_gdbport [lindex $res 1]
 
     # Disable XML-based thread listing, and multi-process extensions.
-    gdb_test_no_output "set remote threads-packet off"
-    gdb_test_no_output "set remote multiprocess-feature-packet off"
+    gdb_test \
+	"set remote threads-packet off" \
+	"Support for the 'qXfer:threads:read' packet on future remote targets is set to \"off\"."
+
+    gdb_test \
+	"set remote multiprocess-feature-packet off" \
+	"Support for the 'multiprocess-feature' packet on future remote targets is set to \"off\"."
 
     # Set target-nonstop mode.
     gdb_test_no_output "maint set target-non-stop ${target_nonstop}"
diff --git a/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp b/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp
index 626143493c0..2e9b16e14a2 100644
--- a/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp
+++ b/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp
@@ -58,15 +58,18 @@ proc do_test { non_stop cond_bp_target } {
 	if {!$cond_bp_target} {
 	    # Leaving breakpoint evaluation to GDB exposes failures
 	    # similar to native debugging.
-	    gdb_test_no_output "set remote conditional-breakpoints-packet off"
+	    gdb_test \
+		"set remote conditional-breakpoints-packet off" \
+		"Support for the 'ConditionalBreakpoints' packet on the current remote target is set to \"off\"."
+
 	    set should_kfail 1
 	} else {
 	    set test "show remote conditional-breakpoints-packet"
 	    gdb_test_multiple $test $test {
-		-re "currently enabled\.\r\n$gdb_prompt $" {
+		-re "\, currently enabled.*\r\n$gdb_prompt $" {
 		    pass $test
 		}
-		-re "currently disabled\.\r\n$gdb_prompt $" {
+		-re "\, currently disabled.*\r\n$gdb_prompt $" {
 		    unsupported "no support for target-side conditional breakpoints"
 		    return
 		}
diff --git a/gdb/testsuite/gdb.trace/change-loc.exp b/gdb/testsuite/gdb.trace/change-loc.exp
index 4710b8d0952..7506a4e6f14 100644
--- a/gdb/testsuite/gdb.trace/change-loc.exp
+++ b/gdb/testsuite/gdb.trace/change-loc.exp
@@ -320,7 +320,9 @@ proc tracepoint_install_in_trace_disabled { trace_type } {
 	gdb_test_no_output "tstart"
 
 	# Force-disable the InstallInTrace RSP feature.
-	gdb_test_no_output "set remote install-in-trace-packet off"
+	gdb_test \
+	    "set remote install-in-trace-packet off" \
+	    "Support for the 'InstallInTrace' packet on the current remote target is set to \"off\"."
 
 	# Set a tracepoint while a trace experiment is ongoing.
 	gdb_test "${trace_type} set_tracepoint" \
diff --git a/gdb/testsuite/gdb.trace/qtro.exp b/gdb/testsuite/gdb.trace/qtro.exp
index 62f937f43ac..24da1128dba 100644
--- a/gdb/testsuite/gdb.trace/qtro.exp
+++ b/gdb/testsuite/gdb.trace/qtro.exp
@@ -79,7 +79,7 @@ prepare_for_trace_disassembly
 set traceframe_info_supported -1
 set test "probe for traceframe-info support"
 gdb_test_multiple "show remote traceframe-info-packet" $test {
-    -re ".*Support for .* is auto-detected, currently (\[a-z\]*).*$gdb_prompt $" {
+    -re ".*Support for .* is \"auto\", currently (\[a-z\]*).*$gdb_prompt $" {
 	set status $expect_out(1,string)
 
 	if { $status == "enabled" } {
@@ -110,7 +110,9 @@ foreach tfinfo { auto off } {
 
 	clean_restart $testfile
 	runto_main
-	gdb_test_no_output "set remote traceframe-info-packet $tfinfo"
+	gdb_test \
+	    "set remote traceframe-info-packet $tfinfo" \
+	    "Support for the 'qXfer:traceframe-info:read' packet on the current remote target is set to *.*$tfinfo*.*"
 
 	prepare_for_trace_disassembly
 
