[10/10] remote: one struct remote_state per struct remote_target

Message ID 20180516141830.16859-11-palves@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves May 16, 2018, 2:18 p.m. UTC
  'struct remote_state' today contains per-connection state, however
there's only a single global instance of that type.  In order to
support multiple connections, we must have one such object per
connection.

Thus this patch eliminates the 'remote_state' global in favor of
having a remote_state instance per remote_target instance.

The get_remote_state free function is eliminated as well, by making it
a remote_target method instead.

The patch then fixes the fallout by making all free functions that
refer to get_remote_state() directly or indirectly be methods of
remote_target too.

Likewise, remote-fileio.c and remote-notif.c routines are
parameterized with a remote_target pointer too, so they can call into
the right remote_target instance.

References to the global 'get_remote_state ()->remote_desc' to tell
whether the remote target is open (!= nullptr) must be replaced with
something else:

 - Command implementations use a new get_current_remote_target free
 function.

 - remote_target::open_1 checks the exception type instead.

Finally, remote_target and extended_remote_target are made
heap-allocated targets.  As with the earlier core target patches, it
still won't be possible to have more than one remote_target instance
in practice, but this puts us closer.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* remote-fileio.c (remote_fileio_reply, remote_fileio_ioerror)
	(remote_fileio_badfd, remote_fileio_return_errno)
	(remote_fileio_return_success, remote_fileio_func_open)
	(remote_fileio_func_open, remote_fileio_func_close)
	(remote_fileio_func_read, remote_fileio_func_write)
	(remote_fileio_func_lseek, remote_fileio_func_rename)
	(remote_fileio_func_unlink, remote_fileio_func_stat)
	(remote_fileio_func_fstat, remote_fileio_func_gettimeofday)
	(remote_fileio_func_isatty, remote_fileio_func_system): Add
	remote_target parameter.
	(remote_fio_func_map) <func>: Add remote_target parameter.
	(do_remote_fileio_request, remote_fileio_request):
	* remote-fileio.h (remote_fileio_request):
	* remote-notif.c (remote_notif_ack, remote_notif_parse, ): Add
	remote_target parameter.
	(remote_notif_process, handle_notification): Adjust to pass down
	the remote.
	(remote_notif_state_allocate): Add remote_target parameter.  Save
	it.
	* remote-notif.h (struct remote_target): Forward declare.
	(struct notif_client) <parse, ack, can_get_pending_events>: Add
	remote_target parameter.
	(struct remote_notif_state) <remote>: New field.
	(remote_notif_ack, remote_notif_parse): Add remote_target
	parameter.
	(remote_notif_state_allocate, remote_notif_state_allocate): Add
	remote_target parameter.
	* remote.c (OPAQUETHREADBYTES, threadref, gdb_ext_thread_info)
	(threads_listing_context, rmt_thread_action, protocol_feature)
	(packet_reg, stop_reply, stop_reply_p, enum packet_support)
	(packet_result, struct threads_listing_context, remote_state):
	Move definitions and declarations higher up.
	(remote_target) <~remote_target>: Declare.
	(remote_download_command_source, remote_file_put, remote_file_get)
	(remote_file_delete, remote_hostio_pread, remote_hostio_pwrite)
	(remote_hostio_pread_vFile, remote_hostio_send_command)
	(remote_hostio_set_filesystem, remote_hostio_open)
	(remote_hostio_close, remote_hostio_unlink, remote_state)
	(get_remote_state, get_remote_packet_size, get_memory_packet_size)
	(get_memory_write_packet_size, get_memory_read_packet_size)
	(append_pending_thread_resumptions, remote_detach_1)
	(append_resumption, remote_resume_with_vcont)
	(add_current_inferior_and_thread, wait_ns, wait_as)
	(process_stop_reply, remote_notice_new_inferior)
	(process_initial_stop_replies, remote_add_thread)
	(btrace_sync_conf, remote_btrace_maybe_reopen)
	(remove_new_fork_children, kill_new_fork_children)
	(discard_pending_stop_replies, stop_reply_queue_length)
	(check_pending_events_prevent_wildcard_vcont)
	(discard_pending_stop_replies_in_queue, stop_reply)
	(remote_notif_remove_queued_reply, stop_reply *queued_stop_reply)
	(peek_stop_reply, remote_parse_stop_reply, remote_stop_ns)
	(remote_interrupt_as, remote_interrupt_ns)
	(remote_get_noisy_reply, remote_query_attached)
	(remote_add_inferior, remote_current_thread, get_current_thread)
	(set_thread, set_general_thread, set_continue_thread)
	(set_general_process, write_ptid)
	(remote_unpack_thread_info_response, remote_get_threadinfo)
	(parse_threadlist_response, remote_get_threadlist)
	(remote_threadlist_iterator, remote_get_threads_with_ql)
	(remote_get_threads_with_qxfer)
	(remote_get_threads_with_qthreadinfo, extended_remote_restart)
	(get_offsets, remote_check_symbols, remote_supported_packet)
	(remote_query_supported, remote_packet_size)
	(remote_serial_quit_handler, remote_detach_pid)
	(remote_vcont_probe, remote_resume_with_hc)
	(send_interrupt_sequence, interrupt_query)
	(remote_notif_get_pending_events, fetch_register_using_p)
	(send_g_packet, process_g_packet, fetch_registers_using_g)
	(store_register_using_P, store_registers_using_G)
	(set_remote_traceframe, check_binary_download)
	(remote_write_bytes_aux, remote_write_bytes, remote_read_bytes_1)
	(remote_xfer_live_readonly_partial, remote_read_bytes)
	(remote_send_printf, remote_flash_write, readchar)
	(remote_serial_write, putpkt, putpkt_binary, skip_frame)
	(read_frame, getpkt, getpkt_or_notif_sane_1, getpkt_sane)
	(getpkt_or_notif_sane, remote_vkill, remote_kill_k)
	(extended_remote_disable_randomization, extended_remote_run)
	(send_environment_packet, extended_remote_environment_support)
	(extended_remote_set_inferior_cwd, remote_write_qxfer)
	(remote_read_qxfer, push_stop_reply, vcont_r_supported)
	(packet_command): Now methods of ...
	(remote_target): ... this class.
	(m_remote_state) <remote_target>: New field.
	(struct remote_state) <stop_reply_queue,
	remote_async_inferior_event_token, wait_forever_enabled_p>: New
	fields.
	(remote_state::remote_state): Allocate stop_reply_queue.
	(remote_state): Delete global.
	(get_remote_state_raw): Delete.
	(remote_target::get_remote_state): Allocate m_remote_state on
	demand.
	(get_current_remote_target): New.
	(wait_forever_enabled_p, remote_async_inferior_event_token):
	Delete, moved to struct remote_state.
	(remote_target::close): Delete self.  Destruction bits split to
	...
	(remote_target::~remote_target): ... this.
	(show_memory_packet_size): Adjust to use
	get_current_remote_target.
	(struct protocol_feature) <func>: Add remote_target parameter.
	All callers adjusted.
	(curr_quit_handler_target): New.
	(remote_serial_quit_handler): Reimplement.
	(remote_target::open_1): Adjust to use get_current_remote_target.
	Heap-allocate remote_target/extended_remote_target instances.
	(vcont_builder::vcont_builder): Add remote_target parameter, and
	save it in m_remote.  All callers adjusted.
	(vcont_builder::m_remote): New field.
	(vcont_builder::restart, vcont_builder::flush)
	(vcont_builder::push_action): Use it.
	(remote_target::commit_resume): Use it.
	(struct queue_iter_param) <remote>: New field.
	(remote_target::remove_new_fork_children): Fill in 'remote' field.
	(check_pending_event_prevents_wildcard_vcont_callback_data): New.
	(check_pending_event_prevents_wildcard_vcont_callback)
	(remote_target::check_pending_events_prevent_wildcard_vcont)
	(remote_target::discard_pending_stop_replies)
	(remote_target::discard_pending_stop_replies_in_queue)
	(remote_target::remote_notif_remove_queued_reply): Fill in
	'remote' field.
	(remote_notif_get_pending_events): New.
	(remote_target::readchar, remote_target::remote_serial_write):
	Save/restore curr_quit_handler_target.
	(putpkt): New.
	(kill_new_fork_children): Fill in 'remote' field.
	(packet_command): Use get_current_remote_target, defer to
	remote_target method of same name.
	(scoped_remote_fd::scoped_remote_fd): Add 'remote_target'
	parameter, and save it in m_remote.  All callers adjusted.
	(scoped_remote_fd::release): Use m_remote.
	(scoped_remote_fd::m_remote): New field.
	(remote_file_put, remote_file_get, remote_file_delete): Use
	get_current_remote_target, defer to remote_target method of same
	name.
	(remote_btrace_reset): Add remote_state paremeter.  Update all
	callers.
	(remote_async_inferior_event_handler). Pass down 'data'.
	(remote_new_objfile): Use get_current_remote_target.
	(remote_target::vcont_r_supported): New.
	(set_range_stepping): Use get_current_remote_target and
	remote_target::vcont_r_supported.
	(_initialize_remote): Don't allocate 'remote_state' and
	'stop_reply_queue' globals.
	* remote.h (struct remote_target): Forward declare.
	(getpkt, putpkt, remote_notif_get_pending_events): Add
	'remote_target' parameter.
---
 gdb/remote-fileio.c |  214 ++++----
 gdb/remote-fileio.h |    3 +-
 gdb/remote-notif.c  |   22 +-
 gdb/remote-notif.h  |   21 +-
 gdb/remote.c        | 1527 ++++++++++++++++++++++++++++++---------------------
 gdb/remote.h        |    9 +-
 6 files changed, 1058 insertions(+), 738 deletions(-)
  

Comments

Simon Marchi May 22, 2018, 3:37 a.m. UTC | #1
On 2018-05-16 10:18 AM, Pedro Alves wrote:
> 'struct remote_state' today contains per-connection state, however
> there's only a single global instance of that type.  In order to
> support multiple connections, we must have one such object per
> connection.
> 
> Thus this patch eliminates the 'remote_state' global in favor of
> having a remote_state instance per remote_target instance.
> 
> The get_remote_state free function is eliminated as well, by making it
> a remote_target method instead.
> 
> The patch then fixes the fallout by making all free functions that
> refer to get_remote_state() directly or indirectly be methods of
> remote_target too.
> 
> Likewise, remote-fileio.c and remote-notif.c routines are
> parameterized with a remote_target pointer too, so they can call into
> the right remote_target instance.
> 
> References to the global 'get_remote_state ()->remote_desc' to tell
> whether the remote target is open (!= nullptr) must be replaced with
> something else:
> 
>  - Command implementations use a new get_current_remote_target free
>  function.
> 
>  - remote_target::open_1 checks the exception type instead.
> 
> Finally, remote_target and extended_remote_target are made
> heap-allocated targets.  As with the earlier core target patches, it
> still won't be possible to have more than one remote_target instance
> in practice, but this puts us closer.

Hi Pedro,

I took a rather quick look, because a lot of the changes are mecanical,
once you have set the premises you pointed out in the commit message
(and I think they are fine).

Two nits:

Is there a reason not to make the remote_state object a simple field
of remote_target, does it have to be a pointer?  You would have to
shuffle things around a little bit more, but it seems to work fine.

> @@ -6287,7 +6512,7 @@ remote_target::commit_resume ()
>       we end up with too many actions for a single packet vcont_builder
>       flushes the current vCont packet to the remote side and starts a
>       new one.  */
> -  struct vcont_builder vcont_builder;
> +  struct vcont_builder vcont_builder (this);
>    vcont_builder.restart ();

That's more a comment for the previous patch, but: I find it strange to
have to call restart just after building the object. Couldn't the
constructor leave it in a ready to use state?

Simon
  
Pedro Alves May 22, 2018, 5:30 p.m. UTC | #2
On 05/22/2018 04:37 AM, Simon Marchi wrote:

> I took a rather quick look, because a lot of the changes are mecanical,
> once you have set the premises you pointed out in the commit message
> (and I think they are fine).
> 
> Two nits:
> 
> Is there a reason not to make the remote_state object a simple field
> of remote_target, does it have to be a pointer?  You would have to
> shuffle things around a little bit more, but it seems to work fine.

Yeah, no reason other than struct remote_state not being complete yet 
when the field is defined in struct remote_target.  I was thinking the
moving would be done as follow up, to avoid even more churn mixed in with
changes, very much like patch #4 started with a pointer and then patch #5
moved to objects.

> 
>> @@ -6287,7 +6512,7 @@ remote_target::commit_resume ()
>>       we end up with too many actions for a single packet vcont_builder
>>       flushes the current vCont packet to the remote side and starts a
>>       new one.  */
>> -  struct vcont_builder vcont_builder;
>> +  struct vcont_builder vcont_builder (this);
>>    vcont_builder.restart ();
> 
> That's more a comment for the previous patch, but: I find it strange to
> have to call restart just after building the object. Couldn't the
> constructor leave it in a ready to use state?

Yeah, I guess it could.  I've made that change.  I'll post it
in response to the previous patch.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index 4c648a9c83..313da642ea 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -313,7 +313,7 @@  remote_fileio_quit_handler (void)
 }
 
 static void
-remote_fileio_reply (int retcode, int error)
+remote_fileio_reply (remote_target *remote, int retcode, int error)
 {
   char buf[32];
   int ctrl_c = check_quit_flag ();
@@ -339,36 +339,36 @@  remote_fileio_reply (int retcode, int error)
         strcat (buf, ",C");
     }
   quit_handler = remote_fileio_o_quit_handler;
-  putpkt (buf);
+  putpkt (remote, buf);
 }
 
 static void
-remote_fileio_ioerror (void)
+remote_fileio_ioerror (remote_target *remote)
 {
-  remote_fileio_reply (-1, FILEIO_EIO);
+  remote_fileio_reply (remote, -1, FILEIO_EIO);
 }
 
 static void
-remote_fileio_badfd (void)
+remote_fileio_badfd (remote_target *remote)
 {
-  remote_fileio_reply (-1, FILEIO_EBADF);
+  remote_fileio_reply (remote, -1, FILEIO_EBADF);
 }
 
 static void
-remote_fileio_return_errno (int retcode)
+remote_fileio_return_errno (remote_target *remote, int retcode)
 {
-  remote_fileio_reply (retcode, retcode < 0
+  remote_fileio_reply (remote, retcode, retcode < 0
 		       ? host_to_fileio_error (errno) : 0);
 }
 
 static void
-remote_fileio_return_success (int retcode)
+remote_fileio_return_success (remote_target *remote, int retcode)
 {
-  remote_fileio_reply (retcode, 0);
+  remote_fileio_reply (remote, retcode, 0);
 }
 
 static void
-remote_fileio_func_open (char *buf)
+remote_fileio_func_open (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
   int length;
@@ -381,20 +381,20 @@  remote_fileio_func_open (char *buf)
   /* 1. Parameter: Ptr to pathname / length incl. trailing zero.  */
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   /* 2. Parameter: open flags */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   flags = remote_fileio_oflags_to_host (num);
   /* 3. Parameter: open mode */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   mode = remote_fileio_mode_to_host (num, 1);
@@ -403,7 +403,7 @@  remote_fileio_func_open (char *buf)
   pathname = (char *) alloca (length);
   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
@@ -414,13 +414,13 @@  remote_fileio_func_open (char *buf)
     {
       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
 	{
-	  remote_fileio_reply (-1, FILEIO_ENODEV);
+	  remote_fileio_reply (remote, -1, FILEIO_ENODEV);
 	  return;
 	}
       if (S_ISDIR (st.st_mode)
 	  && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
 	{
-	  remote_fileio_reply (-1, FILEIO_EISDIR);
+	  remote_fileio_reply (remote, -1, FILEIO_EISDIR);
 	  return;
 	}
     }
@@ -428,16 +428,16 @@  remote_fileio_func_open (char *buf)
   fd = gdb_open_cloexec (pathname, flags, mode);
   if (fd < 0)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
 
   fd = remote_fileio_fd_to_targetfd (fd);
-  remote_fileio_return_success (fd);
+  remote_fileio_return_success (remote, fd);
 }
 
 static void
-remote_fileio_func_close (char *buf)
+remote_fileio_func_close (remote_target *remote, char *buf)
 {
   long num;
   int fd;
@@ -445,24 +445,24 @@  remote_fileio_func_close (char *buf)
   /* Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) num);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
 
   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   remote_fileio_close_target_fd ((int) num);
-  remote_fileio_return_success (0);
+  remote_fileio_return_success (remote, 0);
 }
 
 static void
-remote_fileio_func_read (char *buf)
+remote_fileio_func_read (remote_target *remote, char *buf)
 {
   long target_fd, num;
   LONGEST lnum;
@@ -475,26 +475,26 @@  remote_fileio_func_read (char *buf)
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   /* 2. Parameter: buffer pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 3. Parameter: buffer length */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   length = (size_t) num;
@@ -502,7 +502,7 @@  remote_fileio_func_read (char *buf)
   switch (fd)
     {
       case FIO_FD_CONSOLE_OUT:
-	remote_fileio_badfd ();
+	remote_fileio_badfd (remote);
 	return;
       case FIO_FD_CONSOLE_IN:
 	{
@@ -580,15 +580,15 @@  remote_fileio_func_read (char *buf)
     }
 
   if (ret < 0)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 
   xfree (buffer);
 }
 
 static void
-remote_fileio_func_write (char *buf)
+remote_fileio_func_write (remote_target *remote, char *buf)
 {
   long target_fd, num;
   LONGEST lnum;
@@ -600,26 +600,26 @@  remote_fileio_func_write (char *buf)
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   /* 2. Parameter: buffer pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 3. Parameter: buffer length */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   length = (size_t) num;
@@ -628,14 +628,14 @@  remote_fileio_func_write (char *buf)
   if (target_read_memory (ptrval, buffer, length) != 0)
     {
       xfree (buffer);
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
   switch (fd)
     {
       case FIO_FD_CONSOLE_IN:
-	remote_fileio_badfd ();
+	remote_fileio_badfd (remote);
 	xfree (buffer);
 	return;
       case FIO_FD_CONSOLE_OUT:
@@ -653,15 +653,15 @@  remote_fileio_func_write (char *buf)
     }
 
   if (ret < 0)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 
   xfree (buffer);
 }
 
 static void
-remote_fileio_func_lseek (char *buf)
+remote_fileio_func_lseek (remote_target *remote, char *buf)
 {
   long num;
   LONGEST lnum;
@@ -671,50 +671,50 @@  remote_fileio_func_lseek (char *buf)
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) num);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
     {
-      remote_fileio_reply (-1, FILEIO_ESPIPE);
+      remote_fileio_reply (remote, -1, FILEIO_ESPIPE);
       return;
     }
 
   /* 2. Parameter: offset */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   offset = (off_t) lnum;
   /* 3. Parameter: flag */
   if (remote_fileio_extract_int (&buf, &num))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   if (remote_fileio_seek_flag_to_host (num, &flag))
     {
-      remote_fileio_reply (-1, FILEIO_EINVAL);
+      remote_fileio_reply (remote, -1, FILEIO_EINVAL);
       return;
     }
   
   ret = lseek (fd, offset, flag);
 
   if (ret == (off_t) -1)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_rename (char *buf)
+remote_fileio_func_rename (remote_target *remote, char *buf)
 {
   CORE_ADDR old_ptr, new_ptr;
   int old_len, new_len;
@@ -725,14 +725,14 @@  remote_fileio_func_rename (char *buf)
   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   
   /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   
@@ -740,7 +740,7 @@  remote_fileio_func_rename (char *buf)
   oldpath = (char *) alloca (old_len);
   if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   
@@ -748,7 +748,7 @@  remote_fileio_func_rename (char *buf)
   newpath = (char *) alloca (new_len);
   if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   
@@ -758,7 +758,7 @@  remote_fileio_func_rename (char *buf)
   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
     {
-      remote_fileio_reply (-1, FILEIO_EACCES);
+      remote_fileio_reply (remote, -1, FILEIO_EACCES);
       return;
     }
 
@@ -800,14 +800,14 @@  remote_fileio_func_rename (char *buf)
 	}
 #endif
 
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
     }
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_unlink (char *buf)
+remote_fileio_func_unlink (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
   int length;
@@ -818,14 +818,14 @@  remote_fileio_func_unlink (char *buf)
   /* Parameter: Ptr to pathname / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   /* Request pathname using 'm' packet */
   pathname = (char *) alloca (length);
   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
@@ -833,20 +833,20 @@  remote_fileio_func_unlink (char *buf)
      the correct return code).  */
   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
     {
-      remote_fileio_reply (-1, FILEIO_ENODEV);
+      remote_fileio_reply (remote, -1, FILEIO_ENODEV);
       return;
     }
 
   ret = unlink (pathname);
 
   if (ret == -1)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_stat (char *buf)
+remote_fileio_func_stat (remote_target *remote, char *buf)
 {
   CORE_ADDR statptr, nameptr;
   int ret, namelength;
@@ -858,14 +858,14 @@  remote_fileio_func_stat (char *buf)
   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
   /* 2. Parameter: Ptr to struct stat */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   statptr = (CORE_ADDR) lnum;
@@ -874,7 +874,7 @@  remote_fileio_func_stat (char *buf)
   pathname = (char *) alloca (namelength);
   if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
@@ -882,13 +882,13 @@  remote_fileio_func_stat (char *buf)
 
   if (ret == -1)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
   /* Only operate on regular files and directories.  */
   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
     {
-      remote_fileio_reply (-1, FILEIO_EACCES);
+      remote_fileio_reply (remote, -1, FILEIO_EACCES);
       return;
     }
   if (statptr)
@@ -899,15 +899,15 @@  remote_fileio_func_stat (char *buf)
       errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
       if (errno != 0)
 	{
-	  remote_fileio_return_errno (-1);
+	  remote_fileio_return_errno (remote, -1);
 	  return;
 	}
     }
-  remote_fileio_return_success (ret);
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_fstat (char *buf)
+remote_fileio_func_fstat (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
   int fd, ret;
@@ -920,19 +920,19 @@  remote_fileio_func_fstat (char *buf)
   /* 1. Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
   if (fd == FIO_FD_INVALID)
     {
-      remote_fileio_badfd ();
+      remote_fileio_badfd (remote);
       return;
     }
   /* 2. Parameter: Ptr to struct stat */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
@@ -966,7 +966,7 @@  remote_fileio_func_fstat (char *buf)
 
   if (ret == -1)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
   if (ptrval)
@@ -976,15 +976,15 @@  remote_fileio_func_fstat (char *buf)
       errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
       if (errno != 0)
 	{
-	  remote_fileio_return_errno (-1);
+	  remote_fileio_return_errno (remote, -1);
 	  return;
 	}
     }
-  remote_fileio_return_success (ret);
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_gettimeofday (char *buf)
+remote_fileio_func_gettimeofday (remote_target *remote, char *buf)
 {
   LONGEST lnum;
   CORE_ADDR ptrval;
@@ -995,20 +995,20 @@  remote_fileio_func_gettimeofday (char *buf)
   /* 1. Parameter: struct timeval pointer */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   ptrval = (CORE_ADDR) lnum;
   /* 2. Parameter: some pointer value...  */
   if (remote_fileio_extract_long (&buf, &lnum))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   /* ...which has to be NULL.  */
   if (lnum)
     {
-      remote_fileio_reply (-1, FILEIO_EINVAL);
+      remote_fileio_reply (remote, -1, FILEIO_EINVAL);
       return;
     }
 
@@ -1016,7 +1016,7 @@  remote_fileio_func_gettimeofday (char *buf)
 
   if (ret == -1)
     {
-      remote_fileio_return_errno (-1);
+      remote_fileio_return_errno (remote, -1);
       return;
     }
 
@@ -1027,15 +1027,15 @@  remote_fileio_func_gettimeofday (char *buf)
       errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
       if (errno != 0)
 	{
-	  remote_fileio_return_errno (-1);
+	  remote_fileio_return_errno (remote, -1);
 	  return;
 	}
     }
-  remote_fileio_return_success (ret);
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_isatty (char *buf)
+remote_fileio_func_isatty (remote_target *remote, char *buf)
 {
   long target_fd;
   int fd;
@@ -1043,16 +1043,16 @@  remote_fileio_func_isatty (char *buf)
   /* Parameter: file descriptor */
   if (remote_fileio_extract_int (&buf, &target_fd))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
   fd = remote_fileio_map_fd ((int) target_fd);
-  remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
-  				fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
+  int ret = fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT ? 1 : 0;
+  remote_fileio_return_success (remote, ret);
 }
 
 static void
-remote_fileio_func_system (char *buf)
+remote_fileio_func_system (remote_target *remote, char *buf)
 {
   CORE_ADDR ptrval;
   int ret, length;
@@ -1061,7 +1061,7 @@  remote_fileio_func_system (char *buf)
   /* Parameter: Ptr to commandline / length incl. trailing zero */
   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
     {
-      remote_fileio_ioerror ();
+      remote_fileio_ioerror (remote);
       return;
     }
 
@@ -1071,7 +1071,7 @@  remote_fileio_func_system (char *buf)
       cmdline = (char *) alloca (length);
       if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
 	{
-	  remote_fileio_ioerror ();
+	  remote_fileio_ioerror (remote);
 	  return;
 	}
     }
@@ -1083,25 +1083,25 @@  remote_fileio_func_system (char *buf)
   if (!remote_fio_system_call_allowed)
     {
       if (!length)
-	remote_fileio_return_success (0);
+	remote_fileio_return_success (remote, 0);
       else
-	remote_fileio_reply (-1, FILEIO_EPERM);
+	remote_fileio_reply (remote, -1, FILEIO_EPERM);
       return;
     }
 
   ret = system (cmdline);
 
   if (!length)
-    remote_fileio_return_success (ret);
+    remote_fileio_return_success (remote, ret);
   else if (ret == -1)
-    remote_fileio_return_errno (-1);
+    remote_fileio_return_errno (remote, -1);
   else
-    remote_fileio_return_success (WEXITSTATUS (ret));
+    remote_fileio_return_success (remote, WEXITSTATUS (ret));
 }
 
 static struct {
   const char *name;
-  void (*func)(char *);
+  void (*func)(remote_target *remote, char *);
 } remote_fio_func_map[] = {
   { "open", remote_fileio_func_open },
   { "close", remote_fileio_func_close },
@@ -1119,7 +1119,7 @@  static struct {
 };
 
 static void
-do_remote_fileio_request (char *buf)
+do_remote_fileio_request (remote_target *remote, char *buf)
 {
   char *c;
   int idx;
@@ -1135,9 +1135,9 @@  do_remote_fileio_request (char *buf)
     if (!strcmp (remote_fio_func_map[idx].name, buf))
       break;
   if (!remote_fio_func_map[idx].name)
-    remote_fileio_reply (-1, FILEIO_ENOSYS);
+    remote_fileio_reply (remote, -1, FILEIO_ENOSYS);
   else
-    remote_fio_func_map[idx].func (c);
+    remote_fio_func_map[idx].func (remote, c);
 }
 
 /* Close any open descriptors, and reinitialize the file mapping.  */
@@ -1167,7 +1167,7 @@  remote_fileio_reset (void)
    acknowledged the Ctrl-C sent asynchronously earlier.  */
 
 void
-remote_fileio_request (char *buf, int ctrlc_pending_p)
+remote_fileio_request (remote_target *remote, char *buf, int ctrlc_pending_p)
 {
   /* Save the previous quit handler, so we can restore it.  No need
      for a cleanup since we catch all exceptions below.  Note that the
@@ -1181,20 +1181,20 @@  remote_fileio_request (char *buf, int ctrlc_pending_p)
 	 asynchronously earlier, take this opportunity to send the
 	 Ctrl-C synchronously.  */
       set_quit_flag ();
-      remote_fileio_reply (-1, FILEIO_EINTR);
+      remote_fileio_reply (remote, -1, FILEIO_EINTR);
     }
   else
     {
       TRY
 	{
-	  do_remote_fileio_request (buf);
+	  do_remote_fileio_request (remote, buf);
 	}
       CATCH (ex, RETURN_MASK_ALL)
 	{
 	  if (ex.reason == RETURN_QUIT)
-	    remote_fileio_reply (-1, FILEIO_EINTR);
+	    remote_fileio_reply (remote, -1, FILEIO_EINTR);
 	  else
-	    remote_fileio_reply (-1, FILEIO_EIO);
+	    remote_fileio_reply (remote, -1, FILEIO_EIO);
 	}
       END_CATCH
     }
diff --git a/gdb/remote-fileio.h b/gdb/remote-fileio.h
index 9f7cd982c6..ed553a4468 100644
--- a/gdb/remote-fileio.h
+++ b/gdb/remote-fileio.h
@@ -28,7 +28,8 @@  struct cmd_list_element;
 
 /* Unified interface to remote fileio, called in remote.c from
    remote_wait () and remote_async_wait ().  */
-extern void remote_fileio_request (char *buf, int ctrlc_pending_p);
+extern void remote_fileio_request (remote_target *remote,
+				   char *buf, int ctrlc_pending_p);
 
 /* Cleanup any remote fileio state.  */
 extern void remote_fileio_reset (void);
diff --git a/gdb/remote-notif.c b/gdb/remote-notif.c
index 85612b1e39..7b889801ca 100644
--- a/gdb/remote-notif.c
+++ b/gdb/remote-notif.c
@@ -58,7 +58,8 @@  static void do_notif_event_xfree (void *arg);
    acknowledge.  */
 
 void
-remote_notif_ack (struct notif_client *nc, char *buf)
+remote_notif_ack (remote_target *remote,
+		  struct notif_client *nc, char *buf)
 {
   struct notif_event *event = nc->alloc_event ();
   struct cleanup *old_chain
@@ -68,8 +69,8 @@  remote_notif_ack (struct notif_client *nc, char *buf)
     fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n",
 			nc->ack_command);
 
-  nc->parse (nc, buf, event);
-  nc->ack (nc, buf, event);
+  nc->parse (remote, nc, buf, event);
+  nc->ack (remote, nc, buf, event);
 
   discard_cleanups (old_chain);
 }
@@ -77,7 +78,8 @@  remote_notif_ack (struct notif_client *nc, char *buf)
 /* Parse the BUF for the expected notification NC.  */
 
 struct notif_event *
-remote_notif_parse (struct notif_client *nc, char *buf)
+remote_notif_parse (remote_target *remote,
+		    struct notif_client *nc, char *buf)
 {
   struct notif_event *event = nc->alloc_event ();
   struct cleanup *old_chain
@@ -86,7 +88,7 @@  remote_notif_parse (struct notif_client *nc, char *buf)
   if (notif_debug)
     fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name);
 
-  nc->parse (nc, buf, event);
+  nc->parse (remote, nc, buf, event);
 
   discard_cleanups (old_chain);
   return event;
@@ -108,8 +110,8 @@  remote_notif_process (struct remote_notif_state *state,
 
       gdb_assert (nc != except);
 
-      if (nc->can_get_pending_events (nc))
-	remote_notif_get_pending_events (nc);
+      if (nc->can_get_pending_events (state->remote, nc))
+	remote_notif_get_pending_events (state->remote, nc);
     }
 }
 
@@ -157,7 +159,7 @@  handle_notification (struct remote_notif_state *state, char *buf)
   else
     {
       struct notif_event *event
-	= remote_notif_parse (nc, buf + strlen (nc->name) + 1);
+	= remote_notif_parse (state->remote, nc, buf + strlen (nc->name) + 1);
 
       /* Be careful to only set it after parsing, since an error
 	 may be thrown then.  */
@@ -236,10 +238,12 @@  do_notif_event_xfree (void *arg)
 /* Return an allocated remote_notif_state.  */
 
 struct remote_notif_state *
-remote_notif_state_allocate (void)
+remote_notif_state_allocate (remote_target *remote)
 {
   struct remote_notif_state *notif_state = XCNEW (struct remote_notif_state);
 
+  notif_state->remote = remote;
+
   notif_state->notif_queue = QUEUE_alloc (notif_client_p, NULL);
 
   /* Register async_event_handler for notification.  */
diff --git a/gdb/remote-notif.h b/gdb/remote-notif.h
index 98d7a30cab..dafa177817 100644
--- a/gdb/remote-notif.h
+++ b/gdb/remote-notif.h
@@ -39,6 +39,8 @@  enum REMOTE_NOTIF_ID
   REMOTE_NOTIF_LAST,
 };
 
+struct remote_target;
+
 /* A client to a sort of async remote notification.  */
 
 typedef struct notif_client
@@ -52,17 +54,20 @@  typedef struct notif_client
   /* Parse BUF to get the expected event and update EVENT.  This
      function may throw exception if contents in BUF is not the
      expected event.  */
-  void (*parse) (struct notif_client *self, char *buf,
+  void (*parse) (remote_target *remote,
+		 struct notif_client *self, char *buf,
 		 struct notif_event *event);
 
   /* Send field <ack_command> to remote, and do some checking.  If
      something wrong, throw an exception.  */
-  void (*ack) (struct notif_client *self, char *buf,
+  void (*ack) (remote_target *remote,
+	       struct notif_client *self, char *buf,
 	       struct notif_event *event);
 
   /* Check this notification client can get pending events in
      'remote_notif_process'.  */
-  int (*can_get_pending_events) (struct notif_client *self);
+  int (*can_get_pending_events) (remote_target *remote,
+				 struct notif_client *self);
 
   /* Allocate an event.  */
   struct notif_event *(*alloc_event) (void);
@@ -77,6 +82,9 @@  DECLARE_QUEUE_P (notif_client_p);
 
 struct remote_notif_state
 {
+  /* The remote target.  */
+  remote_target *remote;
+
   /* Notification queue.  */
 
   QUEUE(notif_client_p) *notif_queue;
@@ -98,8 +106,9 @@  struct remote_notif_state
   struct notif_event *pending_event[REMOTE_NOTIF_LAST];
 };
 
-void remote_notif_ack (struct notif_client *nc, char *buf);
-struct notif_event *remote_notif_parse (struct notif_client *nc,
+void remote_notif_ack (remote_target *remote, notif_client *nc, char *buf);
+struct notif_event *remote_notif_parse (remote_target *remote,
+					notif_client *nc,
 					char *buf);
 
 void notif_event_xfree (struct notif_event *event);
@@ -109,7 +118,7 @@  void handle_notification (struct remote_notif_state *notif_state,
 
 void remote_notif_process (struct remote_notif_state *state,
 			   struct notif_client *except);
-struct remote_notif_state *remote_notif_state_allocate (void);
+remote_notif_state *remote_notif_state_allocate (remote_target *remote);
 void remote_notif_state_xfree (struct remote_notif_state *state);
 
 extern struct notif_client notif_client_stop;
diff --git a/gdb/remote.c b/gdb/remote.c
index 4166598750..97c6e6e4fb 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -84,6 +84,47 @@  Use a remote computer via a serial line, using a gdb-specific protocol.\n\
 Specify the serial device it is connected to\n\
 (e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
 
+#define OPAQUETHREADBYTES 8
+
+/* a 64 bit opaque identifier */
+typedef unsigned char threadref[OPAQUETHREADBYTES];
+
+struct gdb_ext_thread_info;
+struct threads_listing_context;
+typedef int (*rmt_thread_action) (threadref *ref, void *context);
+struct protocol_feature;
+struct packet_reg;
+
+struct stop_reply;
+typedef struct stop_reply *stop_reply_p;
+
+DECLARE_QUEUE_P (stop_reply_p);
+DEFINE_QUEUE_P (stop_reply_p);
+
+/* Generic configuration support for packets the stub optionally
+   supports.  Allows the user to specify the use of the packet as well
+   as allowing GDB to auto-detect support in the remote stub.  */
+
+enum packet_support
+  {
+    PACKET_SUPPORT_UNKNOWN = 0,
+    PACKET_ENABLE,
+    PACKET_DISABLE
+  };
+
+/* Analyze a packet's return value and update the packet config
+   accordingly.  */
+
+enum packet_result
+{
+  PACKET_ERROR,
+  PACKET_OK,
+  PACKET_UNKNOWN
+};
+
+struct threads_listing_context;
+struct remote_state;
+
 static const target_info remote_target_info = {
   "remote",
   N_("Remote serial target in gdb-specific protocol"),
@@ -97,6 +138,7 @@  public:
   {
     to_stratum = process_stratum;
   }
+  ~remote_target () override;
 
   const target_info &info () const override
   { return remote_target_info; }
@@ -378,9 +420,258 @@  public:
   int remove_exec_catchpoint (int) override;
   enum exec_direction_kind execution_direction () override;
 
-protected:
+public: /* Remote specific methods.  */
+
+  void remote_download_command_source (int num, ULONGEST addr,
+				       struct command_line *cmds);
+
+  void remote_file_put (const char *local_file, const char *remote_file,
+			int from_tty);
+  void remote_file_get (const char *remote_file, const char *local_file,
+			int from_tty);
+  void remote_file_delete (const char *remote_file, int from_tty);
+
+  int remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
+			   ULONGEST offset, int *remote_errno);
+  int remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len,
+			    ULONGEST offset, int *remote_errno);
+  int remote_hostio_pread_vFile (int fd, gdb_byte *read_buf, int len,
+				 ULONGEST offset, int *remote_errno);
+
+  int remote_hostio_send_command (int command_bytes, int which_packet,
+				  int *remote_errno, char **attachment,
+				  int *attachment_len);
+  int remote_hostio_set_filesystem (struct inferior *inf,
+				    int *remote_errno);
+  /* We should get rid of this and use fileio_open directly.  */
+  int remote_hostio_open (struct inferior *inf, const char *filename,
+			  int flags, int mode, int warn_if_slow,
+			  int *remote_errno);
+  int remote_hostio_close (int fd, int *remote_errno);
+
+  int remote_hostio_unlink (inferior *inf, const char *filename,
+			    int *remote_errno);
+
+  struct remote_state *get_remote_state ();
+
+  long get_remote_packet_size (void);
+  long get_memory_packet_size (struct memory_packet_config *config);
+
+  long get_memory_write_packet_size ();
+  long get_memory_read_packet_size ();
+
+  char *append_pending_thread_resumptions (char *p, char *endp,
+					   ptid_t ptid);
   static void open_1 (const char *name, int from_tty, int extended_p);
   void start_remote (int from_tty, int extended_p);
+  void remote_detach_1 (int from_tty, struct inferior *inf);
+
+  char *append_resumption (char *p, char *endp,
+			   ptid_t ptid, int step, gdb_signal siggnal);
+  int remote_resume_with_vcont (ptid_t ptid, int step,
+				gdb_signal siggnal);
+
+  void add_current_inferior_and_thread (char *wait_status);
+
+  ptid_t wait_ns (ptid_t ptid, struct target_waitstatus *status,
+		  int options);
+  ptid_t wait_as (ptid_t ptid, target_waitstatus *status,
+		  int options);
+
+  ptid_t process_stop_reply (struct stop_reply *stop_reply,
+			     target_waitstatus *status);
+
+  void remote_notice_new_inferior (ptid_t currthread, int executing);
+
+  void process_initial_stop_replies (int from_tty);
+
+  void remote_add_thread (ptid_t ptid, bool running, bool executing);
+
+  void btrace_sync_conf (const btrace_config *conf);
+
+  void remote_btrace_maybe_reopen ();
+
+  void remove_new_fork_children (threads_listing_context *context);
+  void kill_new_fork_children (int pid);
+  void discard_pending_stop_replies (struct inferior *inf);
+  int stop_reply_queue_length ();
+
+  void check_pending_events_prevent_wildcard_vcont
+    (int *may_global_wildcard_vcont);
+
+  void discard_pending_stop_replies_in_queue ();
+  struct stop_reply *remote_notif_remove_queued_reply (ptid_t ptid);
+  struct stop_reply *queued_stop_reply (ptid_t ptid);
+  int peek_stop_reply (ptid_t ptid);
+  void remote_parse_stop_reply (char *buf, stop_reply *event);
+
+  void remote_stop_ns (ptid_t ptid);
+  void remote_interrupt_as ();
+  void remote_interrupt_ns ();
+
+  char *remote_get_noisy_reply ();
+  int remote_query_attached (int pid);
+  inferior *remote_add_inferior (int fake_pid_p, int pid, int attached,
+				 int try_open_exec);
+
+  ptid_t remote_current_thread (ptid_t oldpid);
+  ptid_t get_current_thread (char *wait_status);
+
+  void set_thread (ptid_t ptid, int gen);
+  void set_general_thread (ptid_t ptid);
+  void set_continue_thread (ptid_t ptid);
+  void set_general_process ();
+
+  char *write_ptid (char *buf, const char *endbuf, ptid_t ptid);
+
+  int remote_unpack_thread_info_response (char *pkt, threadref *expectedref,
+					  gdb_ext_thread_info *info);
+  int remote_get_threadinfo (threadref *threadid, int fieldset,
+			     gdb_ext_thread_info *info);
+
+  int parse_threadlist_response (char *pkt, int result_limit,
+				 threadref *original_echo,
+				 threadref *resultlist,
+				 int *doneflag);
+  int remote_get_threadlist (int startflag, threadref *nextthread,
+			     int result_limit, int *done, int *result_count,
+			     threadref *threadlist);
+
+  int remote_threadlist_iterator (rmt_thread_action stepfunction,
+				  void *context, int looplimit);
+
+  int remote_get_threads_with_ql (threads_listing_context *context);
+  int remote_get_threads_with_qxfer (threads_listing_context *context);
+  int remote_get_threads_with_qthreadinfo (threads_listing_context *context);
+
+  void extended_remote_restart ();
+
+  void get_offsets ();
+
+  void remote_check_symbols ();
+
+  void remote_supported_packet (const struct protocol_feature *feature,
+				enum packet_support support,
+				const char *argument);
+
+  void remote_query_supported ();
+
+  void remote_packet_size (const protocol_feature *feature,
+			   packet_support support, const char *value);
+
+  void remote_serial_quit_handler ();
+
+  void remote_detach_pid (int pid);
+
+  void remote_vcont_probe ();
+
+  void remote_resume_with_hc (ptid_t ptid, int step,
+			      gdb_signal siggnal);
+
+  void send_interrupt_sequence ();
+  void interrupt_query ();
+
+  void remote_notif_get_pending_events (notif_client *nc);
+
+  int fetch_register_using_p (struct regcache *regcache,
+			      packet_reg *reg);
+  int send_g_packet ();
+  void process_g_packet (struct regcache *regcache);
+  void fetch_registers_using_g (struct regcache *regcache);
+  int store_register_using_P (const struct regcache *regcache,
+			      packet_reg *reg);
+  void store_registers_using_G (const struct regcache *regcache);
+
+  void set_remote_traceframe ();
+
+  void check_binary_download (CORE_ADDR addr);
+
+  target_xfer_status remote_write_bytes_aux (const char *header,
+					     CORE_ADDR memaddr,
+					     const gdb_byte *myaddr,
+					     ULONGEST len_units,
+					     int unit_size,
+					     ULONGEST *xfered_len_units,
+					     char packet_format,
+					     int use_length);
+
+  target_xfer_status remote_write_bytes (CORE_ADDR memaddr,
+					 const gdb_byte *myaddr, ULONGEST len,
+					 int unit_size, ULONGEST *xfered_len);
+
+  target_xfer_status remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr,
+					  ULONGEST len_units,
+					  int unit_size, ULONGEST *xfered_len_units);
+
+  target_xfer_status remote_xfer_live_readonly_partial (gdb_byte *readbuf,
+							ULONGEST memaddr,
+							ULONGEST len,
+							int unit_size,
+							ULONGEST *xfered_len);
+
+  target_xfer_status remote_read_bytes (CORE_ADDR memaddr,
+					gdb_byte *myaddr, ULONGEST len,
+					int unit_size,
+					ULONGEST *xfered_len);
+
+  packet_result remote_send_printf (const char *format, ...)
+    ATTRIBUTE_PRINTF (2, 3);
+
+  target_xfer_status remote_flash_write (ULONGEST address,
+					 ULONGEST length, ULONGEST *xfered_len,
+					 const gdb_byte *data);
+
+  int readchar (int timeout);
+
+  void remote_serial_write (const char *str, int len);
+
+  int putpkt (const char *buf);
+  int putpkt_binary (const char *buf, int cnt);
+
+  void skip_frame ();
+  long read_frame (char **buf_p, long *sizeof_buf);
+  void getpkt (char **buf, long *sizeof_buf, int forever);
+  int getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
+			      int expecting_notif, int *is_notif);
+  int getpkt_sane (char **buf, long *sizeof_buf, int forever);
+  int getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
+			    int *is_notif);
+  int remote_vkill (int pid);
+  void remote_kill_k ();
+
+  void extended_remote_disable_randomization (int val);
+  int extended_remote_run (const std::string &args);
+
+  void send_environment_packet (const char *action,
+				const char *packet,
+				const char *value);
+
+  void extended_remote_environment_support ();
+  void extended_remote_set_inferior_cwd ();
+
+  target_xfer_status 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);
+
+  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);
+
+  void push_stop_reply (struct stop_reply *new_event);
+
+  bool vcont_r_supported ();
+
+  void packet_command (const char *args, int from_tty);
+
+private: /* data fields */
+
+  std::unique_ptr<struct remote_state> m_remote_state;
 };
 
 static const target_info extended_remote_target_info = {
@@ -436,30 +727,6 @@  static char *remote_exec_file_var;
 enum { REMOTE_ALIGN_WRITES = 16 };
 
 /* Prototypes for local functions.  */
-static int getpkt_sane (char **buf, long *sizeof_buf, int forever);
-static int getpkt_or_notif_sane (char **buf, long *sizeof_buf,
-				 int forever, int *is_notif);
-
-struct remote_state;
-
-static int remote_vkill (int pid, struct remote_state *rs);
-
-static void remote_kill_k (void);
-
-static int readchar (int timeout);
-
-static void remote_serial_write (const char *str, int len);
-
-static void interrupt_query (void);
-
-static void set_general_thread (ptid_t ptid);
-static void set_continue_thread (ptid_t ptid);
-
-static void get_offsets (void);
-
-static void skip_frame (void);
-
-static long read_frame (char **buf_p, long *sizeof_buf);
 
 static int hexnumlen (ULONGEST num);
 
@@ -475,12 +742,6 @@  static void print_packet (const char *);
 
 static int stub_unpack_int (char *buff, int fieldlength);
 
-static ptid_t remote_current_thread (ptid_t oldptid);
-
-static int putpkt_binary (const char *buf, int cnt);
-
-static void check_binary_download (CORE_ADDR addr);
-
 struct packet_config;
 
 static void show_packet_config_cmd (struct packet_config *config);
@@ -490,22 +751,10 @@  static void show_remote_protocol_packet_cmd (struct ui_file *file,
 					     struct cmd_list_element *c,
 					     const char *value);
 
-static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid);
 static ptid_t read_ptid (const char *buf, const char **obuf);
 
-static void remote_query_supported (void);
-
-static void remote_check_symbols (void);
-
 struct stop_reply;
 static void stop_reply_xfree (struct stop_reply *);
-static void remote_parse_stop_reply (char *, struct stop_reply *);
-static void push_stop_reply (struct stop_reply *);
-static void discard_pending_stop_replies_in_queue (struct remote_state *);
-static int peek_stop_reply (ptid_t ptid);
-
-struct threads_listing_context;
-static void remove_new_fork_children (struct threads_listing_context *);
 
 static void remote_async_inferior_event_handler (gdb_client_data);
 
@@ -513,16 +762,10 @@  static int remote_read_description_p (struct target_ops *target);
 
 static void remote_console_output (char *msg);
 
-static void remote_btrace_reset (void);
-
-static void remote_btrace_maybe_reopen (void);
-
-static int stop_reply_queue_length (void);
+static void remote_btrace_reset (remote_state *rs);
 
 static void remote_unpush_and_throw (void);
 
-static struct remote_state *get_remote_state (void);
-
 /* For "remote".  */
 
 static struct cmd_list_element *remote_cmdlist;
@@ -556,11 +799,6 @@  struct vCont_action_support
 
 static int use_range_stepping = 1;
 
-#define OPAQUETHREADBYTES 8
-
-/* a 64 bit opaque identifier */
-typedef unsigned char threadref[OPAQUETHREADBYTES];
-
 /* About this many threadisds fit in a packet.  */
 
 #define MAXTHREADLISTRESULTS 32
@@ -783,6 +1021,28 @@  public: /* data */
      file descriptor at a time.  */
   struct readahead_cache readahead_cache;
 
+  /* The list of already fetched and acknowledged stop events.  This
+     queue is used for notification Stop, and other notifications
+     don't need queue for their events, because the notification
+     events of Stop can't be consumed immediately, so that events
+     should be queued first, and be consumed by remote_wait_{ns,as}
+     one per time.  Other notifications can consume their events
+     immediately, so queue is not needed for them.  */
+  QUEUE (stop_reply_p) *stop_reply_queue;
+
+  /* Asynchronous signal handle registered as event loop source for
+     when we have pending events ready to be passed to the core.  */
+  struct async_event_handler *remote_async_inferior_event_token = nullptr;
+
+  /* FIXME: cagney/1999-09-23: Even though getpkt was called with
+     ``forever'' still use the normal timeout mechanism.  This is
+     currently used by the ASYNC code to guarentee that target reads
+     during the initial connect always time-out.  Once getpkt has been
+     modified to return a timeout indication and, in turn
+     remote_wait()/wait_for_inferior() have gained a timeout parameter
+     this can go away.  */
+  int wait_forever_enabled_p = 1;
+
 private:
   /* Mapping of remote protocol data for each gdbarch.  Usually there
      is only one entry here, though we may see more with stubs that
@@ -834,24 +1094,16 @@  remote_state::remote_state ()
      whenever a larger buffer is needed. */
   this->buf_size = 400;
   this->buf = (char *) xmalloc (this->buf_size);
+
+  this->stop_reply_queue = QUEUE_alloc (stop_reply_p, stop_reply_xfree);
 }
 
 remote_state::~remote_state ()
 {
   xfree (this->last_pass_packet);
   xfree (this->last_program_signals_packet);
-}
 
-/* This data could be associated with a target, but we do not always
-   have access to the current target when we need it, so for now it is
-   static.  This will be fine for as long as only one target is in use
-   at a time.  */
-static struct remote_state *remote_state;
-
-static struct remote_state *
-get_remote_state_raw (void)
-{
-  return remote_state;
+  QUEUE_free (stop_reply_p, this->stop_reply_queue);
 }
 
 /* Utility: generate error from an incoming stub packet.  */
@@ -875,8 +1127,8 @@  trace_error (char *buf)
 
 /* Utility: wait for reply from stub, while accepting "O" packets.  */
 
-static char *
-remote_get_noisy_reply ()
+char *
+remote_target::remote_get_noisy_reply ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -978,19 +1230,20 @@  remote_state::get_remote_arch_state (struct gdbarch *gdbarch)
 
 /* Fetch the global remote target state.  */
 
-static struct remote_state *
-get_remote_state (void)
+remote_state *
+remote_target::get_remote_state ()
 {
-  struct remote_state *rs = get_remote_state_raw ();
+  if (m_remote_state == nullptr)
+    m_remote_state.reset (new remote_state ());
 
   /* Make sure that the remote architecture state has been
      initialized, because doing so might reallocate rs->buf.  Any
      function which calls getpkt also needs to be mindful of changes
      to rs->buf, but this call limits the number of places which run
      into trouble.  */
-  rs->get_remote_arch_state (target_gdbarch ());
+  m_remote_state->get_remote_arch_state (target_gdbarch ());
 
-  return rs;
+  return m_remote_state.get ();
 }
 
 /* Cleanup routine for the remote module's pspace data.  */
@@ -1165,11 +1418,21 @@  remote_arch_state::remote_arch_state (struct gdbarch *gdbarch)
     this->remote_packet_size = (this->sizeof_g_packet * 2 + 32);
 }
 
+/* Get a pointer to the current remote target.  If not connected to a
+   remote target, return NULL.  */
+
+static remote_target *
+get_current_remote_target ()
+{
+  target_ops *proc_target = find_target_at (process_stratum);
+  return dynamic_cast<remote_target *> (proc_target);
+}
+
 /* Return the current allowed size of a remote packet.  This is
    inferred from the current architecture, and should be used to
    limit the length of outgoing packets.  */
-static long
-get_remote_packet_size (void)
+long
+remote_target::get_remote_packet_size ()
 {
   struct remote_state *rs = get_remote_state ();
   remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
@@ -1215,15 +1478,6 @@  static remote_target remote_ops;
 
 static extended_remote_target extended_remote_ops;
 
-/* FIXME: cagney/1999-09-23: Even though getpkt was called with
-   ``forever'' still use the normal timeout mechanism.  This is
-   currently used by the ASYNC code to guarentee that target reads
-   during the initial connect always time-out.  Once getpkt has been
-   modified to return a timeout indication and, in turn
-   remote_wait()/wait_for_inferior() have gained a timeout parameter
-   this can go away.  */
-static int wait_forever_enabled_p = 1;
-
 /* Allow the user to specify what sequence to send to the remote
    when he requests a program interruption: Although ^C is usually
    what remote systems expect (this is the default, here), it is
@@ -1349,8 +1603,8 @@  get_fixed_memory_packet_size (struct memory_packet_config *config)
 /* Compute the current size of a read/write packet.  Since this makes
    use of ``actual_register_packet_size'' the computation is dynamic.  */
 
-static long
-get_memory_packet_size (struct memory_packet_config *config)
+long
+remote_target::get_memory_packet_size (struct memory_packet_config *config)
 {
   struct remote_state *rs = get_remote_state ();
   remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
@@ -1443,11 +1697,11 @@  show_memory_packet_size (struct memory_packet_config *config)
 		     get_fixed_memory_packet_size (config));
   else
     {
-      struct remote_state *rs = get_remote_state ();
+      remote_target *remote = get_current_remote_target ();
 
-      if (rs->remote_desc != NULL)
+      if (remote != NULL)
 	printf_filtered (_("Packets are limited to %ld bytes.\n"),
-			 get_memory_packet_size (config));
+			 remote->get_memory_packet_size (config));
       else
 	puts_filtered ("The actual limit will be further reduced "
 		       "dependent on the target.\n");
@@ -1471,8 +1725,8 @@  show_memory_write_packet_size (const char *args, int from_tty)
   show_memory_packet_size (&memory_write_packet_config);
 }
 
-static long
-get_memory_write_packet_size (void)
+long
+remote_target::get_memory_write_packet_size ()
 {
   return get_memory_packet_size (&memory_write_packet_config);
 }
@@ -1494,8 +1748,8 @@  show_memory_read_packet_size (const char *args, int from_tty)
   show_memory_packet_size (&memory_read_packet_config);
 }
 
-static long
-get_memory_read_packet_size (void)
+long
+remote_target::get_memory_read_packet_size ()
 {
   long size = get_memory_packet_size (&memory_read_packet_config);
 
@@ -1508,16 +1762,6 @@  get_memory_read_packet_size (void)
 }
 
 
-/* Generic configuration support for packets the stub optionally
-   supports.  Allows the user to specify the use of the packet as well
-   as allowing GDB to auto-detect support in the remote stub.  */
-
-enum packet_support
-  {
-    PACKET_SUPPORT_UNKNOWN = 0,
-    PACKET_ENABLE,
-    PACKET_DISABLE
-  };
 
 struct packet_config
   {
@@ -1535,16 +1779,6 @@  struct packet_config
     enum packet_support support;
   };
 
-/* Analyze a packet's return value and update the packet config
-   accordingly.  */
-
-enum packet_result
-{
-  PACKET_ERROR,
-  PACKET_OK,
-  PACKET_UNKNOWN
-};
-
 static enum packet_support packet_config_support (struct packet_config *config);
 static enum packet_support packet_support (int packet);
 
@@ -2039,12 +2273,6 @@  remote_target::remove_exec_catchpoint (int pid)
 }
 
 
-/* Asynchronous signal handle registered as event loop source for
-   when we have pending events ready to be passed to the core.  */
-
-static struct async_event_handler *remote_async_inferior_event_token;
-
-
 
 static ptid_t magic_null_ptid;
 static ptid_t not_sent_ptid;
@@ -2053,8 +2281,8 @@  static ptid_t any_thread_ptid;
 /* Find out if the stub attached to PID (and hence GDB should offer to
    detach instead of killing it when bailing out).  */
 
-static int
-remote_query_attached (int pid)
+int
+remote_target::remote_query_attached (int pid)
 {
   struct remote_state *rs = get_remote_state ();
   size_t size = get_remote_packet_size ();
@@ -2098,9 +2326,9 @@  remote_query_attached (int pid)
    attempt to open this inferior's executable as the main executable
    if no main executable is open already.  */
 
-static struct inferior *
-remote_add_inferior (int fake_pid_p, int pid, int attached,
-		     int try_open_exec)
+inferior *
+remote_target::remote_add_inferior (int fake_pid_p, int pid, int attached,
+				    int try_open_exec)
 {
   struct inferior *inf;
 
@@ -2147,8 +2375,8 @@  static remote_thread_info *get_remote_thread_info (thread_info *thread);
 /* Add thread PTID to GDB's thread list.  Tag it as executing/running
    according to RUNNING.  */
 
-static void
-remote_add_thread (ptid_t ptid, int running, int executing)
+void
+remote_target::remote_add_thread (ptid_t ptid, bool running, bool executing)
 {
   struct remote_state *rs = get_remote_state ();
   struct thread_info *thread;
@@ -2176,8 +2404,8 @@  remote_add_thread (ptid_t ptid, int running, int executing)
    GDB's inferior list as well.  EXECUTING indicates whether the
    thread is (internally) executing or stopped.  */
 
-static void
-remote_notice_new_inferior (ptid_t currthread, int executing)
+void
+remote_target::remote_notice_new_inferior (ptid_t currthread, int executing)
 {
   /* In non-stop mode, we assume new found threads are (externally)
      running until proven otherwise with a stop reply.  In all-stop,
@@ -2473,8 +2701,8 @@  remote_target::program_signals (int numsigs, unsigned char *signals)
    MINUS_ONE_PTID, set the thread to -1, so the stub returns the
    thread.  If GEN is set, set the general thread, if not, then set
    the step/continue thread.  */
-static void
-set_thread (ptid_t ptid, int gen)
+void
+remote_target::set_thread (ptid_t ptid, int gen)
 {
   struct remote_state *rs = get_remote_state ();
   ptid_t state = gen ? rs->general_thread : rs->continue_thread;
@@ -2502,14 +2730,14 @@  set_thread (ptid_t ptid, int gen)
     rs->continue_thread = ptid;
 }
 
-static void
-set_general_thread (ptid_t ptid)
+void
+remote_target::set_general_thread (ptid_t ptid)
 {
   set_thread (ptid, 1);
 }
 
-static void
-set_continue_thread (ptid_t ptid)
+void
+remote_target::set_continue_thread (ptid_t ptid)
 {
   set_thread (ptid, 0);
 }
@@ -2523,8 +2751,8 @@  set_continue_thread (ptid_t ptid)
    general operations is the process the selected general thread
    belongs to.  */
 
-static void
-set_general_process (void)
+void
+remote_target::set_general_process ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -2666,38 +2894,10 @@  static int threadmatch (threadref *dest, threadref *src);
 static char *pack_threadinfo_request (char *pkt, int mode,
 				      threadref *id);
 
-static int remote_unpack_thread_info_response (char *pkt,
-					       threadref *expectedref,
-					       struct gdb_ext_thread_info
-					       *info);
-
-
-static int remote_get_threadinfo (threadref *threadid,
-				  int fieldset,	/*TAG mask */
-				  struct gdb_ext_thread_info *info);
-
 static char *pack_threadlist_request (char *pkt, int startflag,
 				      int threadcount,
 				      threadref *nextthread);
 
-static int parse_threadlist_response (char *pkt,
-				      int result_limit,
-				      threadref *original_echo,
-				      threadref *resultlist,
-				      int *doneflag);
-
-static int remote_get_threadlist (int startflag,
-				  threadref *nextthread,
-				  int result_limit,
-				  int *done,
-				  int *result_count,
-				  threadref *threadlist);
-
-typedef int (*rmt_thread_action) (threadref *ref, void *context);
-
-static int remote_threadlist_iterator (rmt_thread_action stepfunction,
-				       void *context, int looplimit);
-
 static int remote_newthread_step (threadref *ref, void *context);
 
 
@@ -2705,8 +2905,8 @@  static int remote_newthread_step (threadref *ref, void *context);
    buffer we're allowed to write to.  Returns
    BUF+CHARACTERS_WRITTEN.  */
 
-static char *
-write_ptid (char *buf, const char *endbuf, ptid_t ptid)
+char *
+remote_target::write_ptid (char *buf, const char *endbuf, ptid_t ptid)
 {
   int pid, tid;
   struct remote_state *rs = get_remote_state ();
@@ -3003,9 +3203,10 @@  pack_threadinfo_request (char *pkt, int mode, threadref *id)
 #define TAG_MOREDISPLAY 16	/* Whatever the kernel wants to say about
 				   the process.  */
 
-static int
-remote_unpack_thread_info_response (char *pkt, threadref *expectedref,
-				    struct gdb_ext_thread_info *info)
+int
+remote_target::remote_unpack_thread_info_response (char *pkt,
+						   threadref *expectedref,
+						   gdb_ext_thread_info *info)
 {
   struct remote_state *rs = get_remote_state ();
   int mask, length;
@@ -3096,9 +3297,10 @@  remote_unpack_thread_info_response (char *pkt, threadref *expectedref,
   return retval;
 }
 
-static int
-remote_get_threadinfo (threadref *threadid, int fieldset,	/* TAG mask */
-		       struct gdb_ext_thread_info *info)
+int
+remote_target::remote_get_threadinfo (threadref *threadid,
+				      int fieldset,
+				      gdb_ext_thread_info *info)
 {
   struct remote_state *rs = get_remote_state ();
   int result;
@@ -3132,10 +3334,11 @@  pack_threadlist_request (char *pkt, int startflag, int threadcount,
 
 /* Encoding:   'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
 
-static int
-parse_threadlist_response (char *pkt, int result_limit,
-			   threadref *original_echo, threadref *resultlist,
-			   int *doneflag)
+int
+remote_target::parse_threadlist_response (char *pkt, int result_limit,
+					  threadref *original_echo,
+					  threadref *resultlist,
+					  int *doneflag)
 {
   struct remote_state *rs = get_remote_state ();
   char *limit;
@@ -3163,9 +3366,10 @@  parse_threadlist_response (char *pkt, int result_limit,
 /* Fetch the next batch of threads from the remote.  Returns -1 if the
    qL packet is not supported, 0 on error and 1 on success.  */
 
-static int
-remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
-		       int *done, int *result_count, threadref *threadlist)
+int
+remote_target::remote_get_threadlist (int startflag, threadref *nextthread,
+				      int result_limit, int *done, int *result_count,
+				      threadref *threadlist)
 {
   struct remote_state *rs = get_remote_state ();
   int result = 1;
@@ -3225,9 +3429,9 @@  remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
    STEPFUNCTION returns false.  If the packet is not supported,
    returns -1.  */
 
-static int
-remote_threadlist_iterator (rmt_thread_action stepfunction, void *context,
-			    int looplimit)
+int
+remote_target::remote_threadlist_iterator (rmt_thread_action stepfunction,
+					   void *context, int looplimit)
 {
   struct remote_state *rs = get_remote_state ();
   int done, i, result_count;
@@ -3358,8 +3562,8 @@  remote_newthread_step (threadref *ref, void *data)
 
 #define CRAZY_MAX_THREADS 1000
 
-static ptid_t
-remote_current_thread (ptid_t oldpid)
+ptid_t
+remote_target::remote_current_thread (ptid_t oldpid)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -3383,9 +3587,8 @@  remote_current_thread (ptid_t oldpid)
 
 /* List remote threads using the deprecated qL packet.  */
 
-static int
-remote_get_threads_with_ql (struct target_ops *ops,
-			    struct threads_listing_context *context)
+int
+remote_target::remote_get_threads_with_ql (threads_listing_context *context)
 {
   if (remote_threadlist_iterator (remote_newthread_step, context,
 				  CRAZY_MAX_THREADS) >= 0)
@@ -3466,15 +3669,14 @@  const struct gdb_xml_element threads_elements[] = {
 
 /* List remote threads using qXfer:threads:read.  */
 
-static int
-remote_get_threads_with_qxfer (struct target_ops *ops,
-			       struct threads_listing_context *context)
+int
+remote_target::remote_get_threads_with_qxfer (threads_listing_context *context)
 {
 #if defined(HAVE_LIBEXPAT)
   if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
     {
       gdb::optional<gdb::char_vector> xml
-	= target_read_stralloc (ops, TARGET_OBJECT_THREADS, NULL);
+	= target_read_stralloc (this, TARGET_OBJECT_THREADS, NULL);
 
       if (xml && (*xml)[0] != '\0')
 	{
@@ -3491,9 +3693,8 @@  remote_get_threads_with_qxfer (struct target_ops *ops,
 
 /* List remote threads using qfThreadInfo/qsThreadInfo.  */
 
-static int
-remote_get_threads_with_qthreadinfo (struct target_ops *ops,
-				     struct threads_listing_context *context)
+int
+remote_target::remote_get_threads_with_qthreadinfo (threads_listing_context *context)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -3542,9 +3743,9 @@  remote_target::update_thread_list ()
   /* We have a few different mechanisms to fetch the thread list.  Try
      them all, starting with the most preferred one first, falling
      back to older methods.  */
-  if (remote_get_threads_with_qxfer (this, &context)
-      || remote_get_threads_with_qthreadinfo (this, &context)
-      || remote_get_threads_with_ql (this, &context))
+  if (remote_get_threads_with_qxfer (&context)
+      || remote_get_threads_with_qthreadinfo (&context)
+      || remote_get_threads_with_ql (&context))
     {
       struct thread_info *tp, *tmp;
 
@@ -3776,8 +3977,8 @@  remote_target::get_ada_task_ptid (long lwp, long thread)
 
 /* Restart the remote side; this is an extended protocol operation.  */
 
-static void
-extended_remote_restart (void)
+void
+remote_target::extended_remote_restart ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -3794,17 +3995,9 @@  extended_remote_restart (void)
 void
 remote_target::close ()
 {
-  struct remote_state *rs = get_remote_state ();
-
-  if (rs->remote_desc == NULL)
-    return; /* already closed */
-
   /* Make sure we leave stdin registered in the event loop.  */
   terminal_ours ();
 
-  serial_close (rs->remote_desc);
-  rs->remote_desc = NULL;
-
   /* We don't have a connection to the remote stub anymore.  Get rid
      of all the inferiors and their threads we were controlling.
      Reset inferior_ptid to null_ptid first, as otherwise has_stack_frame
@@ -3812,22 +4005,34 @@  remote_target::close ()
   inferior_ptid = null_ptid;
   discard_all_inferiors ();
 
-  /* We are closing the remote target, so we should discard
+  trace_reset_local_state ();
+
+  delete this;
+}
+
+remote_target::~remote_target ()
+{
+  struct remote_state *rs = get_remote_state ();
+
+  /* Check for NULL because we may get here with a partially
+     constructed target/connection.  */
+  if (rs->remote_desc != nullptr)
+    serial_close (rs->remote_desc);
+
+  /* We are destroying the remote target, so we should discard
      everything of this target.  */
-  discard_pending_stop_replies_in_queue (rs);
+  discard_pending_stop_replies_in_queue ();
 
-  if (remote_async_inferior_event_token)
-    delete_async_event_handler (&remote_async_inferior_event_token);
+  if (rs->remote_async_inferior_event_token)
+    delete_async_event_handler (&rs->remote_async_inferior_event_token);
 
   remote_notif_state_xfree (rs->notif_state);
-
-  trace_reset_local_state ();
 }
 
 /* Query the remote side for the text, data and bss offsets.  */
 
-static void
-get_offsets (void)
+void
+remote_target::get_offsets ()
 {
   struct remote_state *rs = get_remote_state ();
   char *buf;
@@ -3984,8 +4189,9 @@  get_offsets (void)
 }
 
 /* Send interrupt_sequence to remote target.  */
-static void
-send_interrupt_sequence (void)
+
+void
+remote_target::send_interrupt_sequence ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -4048,8 +4254,8 @@  stop_reply_extract_thread (char *stop_reply)
    ask the remote which is the current thread with qC.  The former
    method avoids a roundtrip.  */
 
-static ptid_t
-get_current_thread (char *wait_status)
+ptid_t
+remote_target::get_current_thread (char *wait_status)
 {
   ptid_t ptid = null_ptid;
 
@@ -4075,8 +4281,8 @@  get_current_thread (char *wait_status)
    qC query, we infer the current thread from that stop reply, passed
    in in WAIT_STATUS, which may be NULL.  */
 
-static void
-add_current_inferior_and_thread (char *wait_status)
+void
+remote_target::add_current_inferior_and_thread (char *wait_status)
 {
   struct remote_state *rs = get_remote_state ();
   int fake_pid_p = 0;
@@ -4139,8 +4345,8 @@  print_one_stopped_thread (struct thread_info *thread)
    on initial connection.  We mark these threads as stopped and print
    their current frame before giving the user the prompt.  */
 
-static void
-process_initial_stop_replies (int from_tty)
+void
+remote_target::process_initial_stop_replies (int from_tty)
 {
   int pending_stop_replies = stop_reply_queue_length ();
   struct inferior *inf;
@@ -4546,7 +4752,7 @@  remote_target::start_remote (int from_tty, int extended_p)
 	  /* remote_notif_get_pending_replies acks this one, and gets
 	     the rest out.  */
 	  rs->notif_state->pending_event[notif_client_stop.id]
-	    = remote_notif_parse (notif, rs->buf);
+	    = remote_notif_parse (this, notif, rs->buf);
 	  remote_notif_get_pending_events (notif);
 	}
 
@@ -4658,8 +4864,8 @@  init_all_packet_configs (void)
 
 /* Symbol look-up.  */
 
-static void
-remote_check_symbols (void)
+void
+remote_target::remote_check_symbols ()
 {
   char *msg, *reply, *tmp;
   int end;
@@ -4796,8 +5002,8 @@  struct protocol_feature
      not reported).  The third argument may be NULL; if not NULL, it
      is a NUL-terminated string taken from the packet following
      this feature's name and an equals sign.  */
-  void (*func) (const struct protocol_feature *, enum packet_support,
-		const char *);
+  void (*func) (remote_target *remote, const struct protocol_feature *,
+		enum packet_support, const char *);
 
   /* The corresponding packet for this feature.  Only used if
      FUNC is remote_supported_packet.  */
@@ -4805,7 +5011,8 @@  struct protocol_feature
 };
 
 static void
-remote_supported_packet (const struct protocol_feature *feature,
+remote_supported_packet (remote_target *remote,
+			 const struct protocol_feature *feature,
 			 enum packet_support support,
 			 const char *argument)
 {
@@ -4819,9 +5026,9 @@  remote_supported_packet (const struct protocol_feature *feature,
   remote_protocol_packets[feature->packet].support = support;
 }
 
-static void
-remote_packet_size (const struct protocol_feature *feature,
-		    enum packet_support support, const char *value)
+void
+remote_target::remote_packet_size (const protocol_feature *feature,
+				   enum packet_support support, const char *value)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -4851,6 +5058,13 @@  remote_packet_size (const struct protocol_feature *feature,
   rs->explicit_packet_size = packet_size;
 }
 
+void
+remote_packet_size (remote_target *remote, const protocol_feature *feature,
+		    enum packet_support support, const char *value)
+{
+  remote->remote_packet_size (feature, support, value);
+}
+
 static const struct protocol_feature remote_protocol_features[] = {
   { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
   { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
@@ -5002,8 +5216,8 @@  remote_query_supported_append (std::string *msg, const char *append)
   msg->append (append);
 }
 
-static void
-remote_query_supported (void)
+void
+remote_target::remote_query_supported ()
 {
   struct remote_state *rs = get_remote_state ();
   char *next;
@@ -5142,7 +5356,7 @@  remote_query_supported (void)
 
 	    seen[i] = 1;
 	    feature = &remote_protocol_features[i];
-	    feature->func (feature, is_supported, value);
+	    feature->func (this, feature, is_supported, value);
 	    break;
 	  }
     }
@@ -5164,7 +5378,7 @@  remote_query_supported (void)
 	const struct protocol_feature *feature;
 
 	feature = &remote_protocol_features[i];
-	feature->func (feature, feature->default_support, NULL);
+	feature->func (this, feature, feature->default_support, NULL);
       }
 }
 
@@ -5191,8 +5405,8 @@  remote_query_supported (void)
      is probably wedged --- offer to quit/disconnect.
 */
 
-static void
-remote_serial_quit_handler (void)
+void
+remote_target::remote_serial_quit_handler ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5220,6 +5434,16 @@  remote_serial_quit_handler (void)
     }
 }
 
+/* The remote_target that is current while the quit handler is
+   overridden with remote_serial_quit_handler.  */
+static remote_target *curr_quit_handler_target;
+
+static void
+remote_serial_quit_handler ()
+{
+  curr_quit_handler_target->remote_serial_quit_handler ();
+}
+
 /* Remove any of the remote.c targets from target stack.  Upper targets depend
    on it so remove them first.  */
 
@@ -5239,21 +5463,17 @@  remote_unpush_and_throw (void)
 void
 remote_target::open_1 (const char *name, int from_tty, int extended_p)
 {
-  struct remote_state *rs = get_remote_state ();
+  remote_target *curr_remote = get_current_remote_target ();
 
   if (name == 0)
     error (_("To open a remote debug connection, you need to specify what\n"
 	   "serial device is attached to the remote system\n"
 	   "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.)."));
 
-  /* See FIXME above.  */
-  if (!target_async_permitted)
-    wait_forever_enabled_p = 1;
-
   /* If we're connected to a running target, target_preopen will kill it.
      Ask this question first, before target_preopen has a chance to kill
      anything.  */
-  if (rs->remote_desc != NULL && !have_inferiors ())
+  if (curr_remote != NULL && !have_inferiors ())
     {
       if (from_tty
 	  && !query (_("Already connected to a remote target.  Disconnect? ")))
@@ -5263,19 +5483,20 @@  remote_target::open_1 (const char *name, int from_tty, int extended_p)
   /* Here the possibly existing remote target gets unpushed.  */
   target_preopen (from_tty);
 
-  /* Make sure we send the passed signals list the next time we resume.  */
-  xfree (rs->last_pass_packet);
-  rs->last_pass_packet = NULL;
-
-  /* Make sure we send the program signals list the next time we
-     resume.  */
-  xfree (rs->last_program_signals_packet);
-  rs->last_program_signals_packet = NULL;
-
   remote_fileio_reset ();
   reopen_exec_file ();
   reread_symbols ();
 
+  remote_target *remote
+    = (extended_p ? new extended_remote_target () : new remote_target ());
+  target_ops_up target_holder (remote);
+
+  remote_state *rs = remote->get_remote_state ();
+
+  /* See FIXME above.  */
+  if (!target_async_permitted)
+    rs->wait_forever_enabled_p = 1;
+
   rs->remote_desc = remote_serial_open (name);
   if (!rs->remote_desc)
     perror_with_name (name);
@@ -5308,15 +5529,16 @@  remote_target::open_1 (const char *name, int from_tty, int extended_p)
       puts_filtered ("\n");
     }
 
-  remote_target *target
-    = extended_p ? &extended_remote_ops : &remote_ops;
-  push_target (target);		/* Switch to using remote target now.  */
+  /* Switch to using the remote target now.  */
+  push_target (remote);
+  /* The target stack owns the target now.  */
+  target_holder.release ();
 
   /* Register extra event sources in the event loop.  */
-  remote_async_inferior_event_token
+  rs->remote_async_inferior_event_token
     = create_async_event_handler (remote_async_inferior_event_handler,
-				  NULL);
-  rs->notif_state = remote_notif_state_allocate ();
+				  remote);
+  rs->notif_state = remote_notif_state_allocate (remote);
 
   /* Reset the target state; these things will be queried either by
      remote_query_supported or as they are needed.  */
@@ -5350,7 +5572,7 @@  remote_target::open_1 (const char *name, int from_tty, int extended_p)
 	 around this.  Eventually a mechanism that allows
 	 wait_for_inferior() to expect/get timeouts will be
 	 implemented.  */
-      wait_forever_enabled_p = 0;
+      rs->wait_forever_enabled_p = 0;
     }
 
   /* First delete any symbols previously loaded from shared libraries.  */
@@ -5378,31 +5600,29 @@  remote_target::open_1 (const char *name, int from_tty, int extended_p)
 
     TRY
       {
-	target->start_remote (from_tty, extended_p);
+	remote->start_remote (from_tty, extended_p);
       }
     CATCH (ex, RETURN_MASK_ALL)
       {
 	/* Pop the partially set up target - unless something else did
 	   already before throwing the exception.  */
-	if (rs->remote_desc != NULL)
+	if (ex.error != TARGET_CLOSE_ERROR)
 	  remote_unpush_target ();
-	if (target_async_permitted)
-	  wait_forever_enabled_p = 1;
 	throw_exception (ex);
       }
     END_CATCH
   }
 
-  remote_btrace_reset ();
+  remote_btrace_reset (rs);
 
   if (target_async_permitted)
-    wait_forever_enabled_p = 1;
+    rs->wait_forever_enabled_p = 1;
 }
 
 /* Detach the specified process.  */
 
-static void
-remote_detach_pid (int pid)
+void
+remote_target::remote_detach_pid (int pid)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5428,8 +5648,8 @@  remote_detach_pid (int pid)
    any breakpoints in the target program or it'll die when it hits
    one.  */
 
-static void
-remote_detach_1 (int from_tty, inferior *inf)
+void
+remote_target::remote_detach_1 (int from_tty, inferior *inf)
 {
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
@@ -5659,7 +5879,7 @@  extended_remote_target::attach (const char *args, int from_tty)
       if (target_can_async_p ())
 	{
 	  struct notif_event *reply
-	    =  remote_notif_parse (&notif_client_stop, wait_status);
+	    =  remote_notif_parse (this, &notif_client_stop, wait_status);
 
 	  push_stop_reply ((struct stop_reply *) reply);
 
@@ -5697,9 +5917,10 @@  extended_remote_target::post_attach (int pid)
 /* Check for the availability of vCont.  This function should also check
    the response.  */
 
-static void
-remote_vcont_probe (struct remote_state *rs)
+void
+remote_target::remote_vcont_probe ()
 {
+  remote_state *rs = get_remote_state ();
   char *buf;
 
   strcpy (rs->buf, "vCont?");
@@ -5757,9 +5978,9 @@  remote_vcont_probe (struct remote_state *rs)
    the thread to be stepped and/or signalled is given in the global
    INFERIOR_PTID.  */
 
-static char *
-append_resumption (char *p, char *endp,
-		   ptid_t ptid, int step, enum gdb_signal siggnal)
+char *
+remote_target::append_resumption (char *p, char *endp,
+				  ptid_t ptid, int step, gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5844,8 +6065,9 @@  resume_clear_thread_private_info (struct thread_info *thread)
 /* Append a vCont continue-with-signal action for threads that have a
    non-zero stop signal.  */
 
-static char *
-append_pending_thread_resumptions (char *p, char *endp, ptid_t ptid)
+char *
+remote_target::append_pending_thread_resumptions (char *p, char *endp,
+						  ptid_t ptid)
 {
   struct thread_info *thread;
 
@@ -5866,9 +6088,9 @@  append_pending_thread_resumptions (char *p, char *endp, ptid_t ptid)
 /* Set the target running, using the packets that use Hc
    (c/s/C/S).  */
 
-static void
-remote_resume_with_hc (struct target_ops *ops,
-		       ptid_t ptid, int step, enum gdb_signal siggnal)
+void
+remote_target::remote_resume_with_hc (ptid_t ptid, int step,
+				      gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
   struct thread_info *thread;
@@ -5888,7 +6110,7 @@  remote_resume_with_hc (struct target_ops *ops,
     resume_clear_thread_private_info (thread);
 
   buf = rs->buf;
-  if (execution_direction == EXEC_REVERSE)
+  if (::execution_direction == EXEC_REVERSE)
     {
       /* We don't pass signals to the target in reverse exec mode.  */
       if (info_verbose && siggnal != GDB_SIGNAL_0)
@@ -5925,19 +6147,20 @@  remote_resume_with_hc (struct target_ops *ops,
    This function issues a strict subset of all possible vCont commands
    at the moment.  */
 
-static int
-remote_resume_with_vcont (ptid_t ptid, int step, enum gdb_signal siggnal)
+int
+remote_target::remote_resume_with_vcont (ptid_t ptid, int step,
+					 enum gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
   char *endp;
 
   /* No reverse execution actions defined for vCont.  */
-  if (execution_direction == EXEC_REVERSE)
+  if (::execution_direction == EXEC_REVERSE)
     return 0;
 
   if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-    remote_vcont_probe (rs);
+    remote_vcont_probe ();
 
   if (packet_support (PACKET_vCont) == PACKET_DISABLE)
     return 0;
@@ -6041,7 +6264,7 @@  remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
 
   /* Prefer vCont, and fallback to s/c/S/C, which use Hc.  */
   if (!remote_resume_with_vcont (ptid, step, siggnal))
-    remote_resume_with_hc (this, ptid, step, siggnal);
+    remote_resume_with_hc (ptid, step, siggnal);
 
   /* We are about to start executing the inferior, let's register it
      with the event loop.  NOTE: this is the one place where all the
@@ -6064,8 +6287,6 @@  remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
     rs->waiting_for_stop_reply = 1;
 }
 
-static void check_pending_events_prevent_wildcard_vcont
-  (int *may_global_wildcard_vcont);
 static int is_pending_fork_parent_thread (struct thread_info *thread);
 
 /* Private per-inferior info for target remote processes.  */
@@ -6094,7 +6315,8 @@  get_remote_inferior (inferior *inf)
 class vcont_builder
 {
 public:
-  vcont_builder ()
+  explicit vcont_builder (remote_target *remote)
+    : m_remote (remote)
   {}
 
   void restart ();
@@ -6102,6 +6324,9 @@  public:
   void push_action (ptid_t ptid, bool step, gdb_signal siggnal);
 
 private:
+  /* The remote target.  */
+  remote_target *m_remote;
+
   /* Pointer to the first action.  P points here if no action has been
      appended yet.  */
   char *m_first_action;
@@ -6118,10 +6343,10 @@  private:
 void
 vcont_builder::restart ()
 {
-  struct remote_state *rs = get_remote_state ();
+  struct remote_state *rs = m_remote->get_remote_state ();
 
   m_p = rs->buf;
-  m_endp = rs->buf + get_remote_packet_size ();
+  m_endp = rs->buf + m_remote->get_remote_packet_size ();
   m_p += xsnprintf (m_p, m_endp - m_p, "vCont");
   m_first_action = m_p;
 }
@@ -6137,9 +6362,9 @@  vcont_builder::flush ()
   if (m_p == m_first_action)
     return;
 
-  rs = get_remote_state ();
-  putpkt (rs->buf);
-  getpkt (&rs->buf, &rs->buf_size, 0);
+  rs = m_remote->get_remote_state ();
+  m_remote->putpkt (rs->buf);
+  m_remote->getpkt (&rs->buf, &rs->buf_size, 0);
   if (strcmp (rs->buf, "OK") != 0)
     error (_("Unexpected vCont reply in non-stop mode: %s"), rs->buf);
 }
@@ -6160,8 +6385,8 @@  vcont_builder::push_action (ptid_t ptid, bool step, gdb_signal siggnal)
 {
   char buf[MAX_ACTION_SIZE + 1];
 
-  char *endp = append_resumption (buf, buf + sizeof (buf),
-				  ptid, step, siggnal);
+  char *endp = m_remote->append_resumption (buf, buf + sizeof (buf),
+					    ptid, step, siggnal);
 
   /* Check whether this new action would fit in the vCont packet along
      with previous actions.  If not, send what we've got so far and
@@ -6287,7 +6512,7 @@  remote_target::commit_resume ()
      we end up with too many actions for a single packet vcont_builder
      flushes the current vCont packet to the remote side and starts a
      new one.  */
-  struct vcont_builder vcont_builder;
+  struct vcont_builder vcont_builder (this);
   vcont_builder.restart ();
 
   /* Threads first.  */
@@ -6361,15 +6586,15 @@  remote_target::commit_resume ()
    thread, all threads of a remote process, or all threads of all
    processes.  */
 
-static void
-remote_stop_ns (ptid_t ptid)
+void
+remote_target::remote_stop_ns (ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
   char *endp = rs->buf + get_remote_packet_size ();
 
   if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-    remote_vcont_probe (rs);
+    remote_vcont_probe ();
 
   if (!rs->supports_vCont.t)
     error (_("Remote server does not support stopping threads"));
@@ -6412,8 +6637,8 @@  remote_stop_ns (ptid_t ptid)
    interrupt the remote target.  It is undefined which thread of which
    process reports the interrupt.  */
 
-static void
-remote_interrupt_as (void)
+void
+remote_target::remote_interrupt_as ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -6434,8 +6659,8 @@  remote_interrupt_as (void)
    reports the interrupt.  Throws an error if the packet is not
    supported by the server.  */
 
-static void
-remote_interrupt_ns (void)
+void
+remote_target::remote_interrupt_ns ()
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -6514,8 +6739,8 @@  remote_target::pass_ctrlc ()
 
 /* Ask the user what to do when an interrupt is received.  */
 
-static void
-interrupt_query (void)
+void
+remote_target::interrupt_query ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -6603,17 +6828,6 @@  typedef struct stop_reply
   int core;
 } *stop_reply_p;
 
-DECLARE_QUEUE_P (stop_reply_p);
-DEFINE_QUEUE_P (stop_reply_p);
-/* The list of already fetched and acknowledged stop events.  This
-   queue is used for notification Stop, and other notifications
-   don't need queue for their events, because the notification events
-   of Stop can't be consumed immediately, so that events should be
-   queued first, and be consumed by remote_wait_{ns,as} one per
-   time.  Other notifications can consume their events immediately,
-   so queue is not needed for them.  */
-static QUEUE (stop_reply_p) *stop_reply_queue;
-
 static void
 stop_reply_xfree (struct stop_reply *r)
 {
@@ -6622,44 +6836,51 @@  stop_reply_xfree (struct stop_reply *r)
 
 /* Return the length of the stop reply queue.  */
 
-static int
-stop_reply_queue_length (void)
+int
+remote_target::stop_reply_queue_length ()
 {
-  return QUEUE_length (stop_reply_p, stop_reply_queue);
+  remote_state *rs = get_remote_state ();
+  return QUEUE_length (stop_reply_p, rs->stop_reply_queue);
 }
 
-static void
-remote_notif_stop_parse (struct notif_client *self, char *buf,
+void
+remote_notif_stop_parse (remote_target *remote,
+			 struct notif_client *self, char *buf,
 			 struct notif_event *event)
 {
-  remote_parse_stop_reply (buf, (struct stop_reply *) event);
+  remote->remote_parse_stop_reply (buf, (struct stop_reply *) event);
 }
 
 static void
-remote_notif_stop_ack (struct notif_client *self, char *buf,
+remote_notif_stop_ack (remote_target *remote,
+		       struct notif_client *self, char *buf,
 		       struct notif_event *event)
 {
   struct stop_reply *stop_reply = (struct stop_reply *) event;
 
   /* acknowledge */
-  putpkt (self->ack_command);
+  putpkt (remote, self->ack_command);
 
   if (stop_reply->ws.kind == TARGET_WAITKIND_IGNORE)
+    {
       /* We got an unknown stop reply.  */
       error (_("Unknown stop reply"));
+    }
 
-  push_stop_reply (stop_reply);
+  remote->push_stop_reply (stop_reply);
 }
 
 static int
-remote_notif_stop_can_get_pending_events (struct notif_client *self)
+remote_notif_stop_can_get_pending_events (remote_target *remote,
+					  struct notif_client *self)
 {
   /* We can't get pending events in remote_notif_process for
      notification stop, and we have to do this in remote_wait_ns
      instead.  If we fetch all queued events from stub, remote stub
      may exit and we have no chance to process them back in
      remote_wait_ns.  */
-  mark_async_event_handler (remote_async_inferior_event_token);
+  remote_state *rs = remote->get_remote_state ();
+  mark_async_event_handler (rs->remote_async_inferior_event_token);
   return 0;
 }
 
@@ -6706,6 +6927,7 @@  struct notif_client notif_client_stop =
 
 struct queue_iter_param
 {
+  remote_target *remote;
   void *input;
   struct stop_reply *output;
 };
@@ -6778,8 +7000,8 @@  remove_child_of_pending_fork (QUEUE (stop_reply_p) *q,
    and have not yet called follow_fork, which will set up the
    host-side data structures for the new process.  */
 
-static void
-remove_new_fork_children (struct threads_listing_context *context)
+void
+remote_target::remove_new_fork_children (threads_listing_context *context)
 {
   struct thread_info * thread;
   int pid = -1;
@@ -6800,12 +7022,24 @@  remove_new_fork_children (struct threads_listing_context *context)
      in process PID and remove those fork child threads from the
      CONTEXT list as well.  */
   remote_notif_get_pending_events (notif);
+  param.remote = this;
   param.input = context;
   param.output = NULL;
-  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+  QUEUE_iterate (stop_reply_p, get_remote_state ()->stop_reply_queue,
 		 remove_child_of_pending_fork, &param);
 }
 
+/* Callback data for
+   check_pending_event_prevents_wildcard_vcont_callback.  */
+struct check_pending_event_prevents_wildcard_vcont_callback_data
+{
+  /* The remote target.  */
+  remote_target *remote;
+
+  /* Whether we can do a global wildcard (vCont;c)  */
+  int *may_global_wildcard_vcont;
+};
+
 /* Check whether EVENT would prevent a global or process wildcard
    vCont action.  */
 
@@ -6817,7 +7051,7 @@  check_pending_event_prevents_wildcard_vcont_callback
    void *data)
 {
   struct inferior *inf;
-  int *may_global_wildcard_vcont = (int *) data;
+  auto *cb_data = (check_pending_event_prevents_wildcard_vcont_callback_data *) data;
 
   if (event->ws.kind == TARGET_WAITKIND_NO_RESUMED
       || event->ws.kind == TARGET_WAITKIND_NO_HISTORY)
@@ -6825,14 +7059,14 @@  check_pending_event_prevents_wildcard_vcont_callback
 
   if (event->ws.kind == TARGET_WAITKIND_FORKED
       || event->ws.kind == TARGET_WAITKIND_VFORKED)
-    *may_global_wildcard_vcont = 0;
+    *cb_data->may_global_wildcard_vcont = 0;
 
   inf = find_inferior_ptid (event->ptid);
 
   /* This may be the first time we heard about this process.
      Regardless, we must not do a global wildcard resume, otherwise
      we'd resume this process too.  */
-  *may_global_wildcard_vcont = 0;
+  *cb_data->may_global_wildcard_vcont = 0;
   if (inf != NULL)
     get_remote_inferior (inf)->may_wildcard_vcont = false;
 
@@ -6845,15 +7079,18 @@  check_pending_event_prevents_wildcard_vcont_callback
    and clear the event inferior's may_wildcard_vcont flag if we can't
    do a process-wide wildcard resume (vCont;c:pPID.-1).  */
 
-static void
-check_pending_events_prevent_wildcard_vcont (int *may_global_wildcard)
+void
+remote_target::check_pending_events_prevent_wildcard_vcont
+  (int *may_global_wildcard)
 {
   struct notif_client *notif = &notif_client_stop;
+  check_pending_event_prevents_wildcard_vcont_callback_data cb_data
+    {this, may_global_wildcard};
 
   remote_notif_get_pending_events (notif);
-  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+  QUEUE_iterate (stop_reply_p, get_remote_state ()->stop_reply_queue,
 		 check_pending_event_prevents_wildcard_vcont_callback,
-		 may_global_wildcard);
+		 &cb_data);
 }
 
 /* Remove stop replies in the queue if its pid is equal to the given
@@ -6879,8 +7116,8 @@  remove_stop_reply_for_inferior (QUEUE (stop_reply_p) *q,
 
 /* Discard all pending stop replies of inferior INF.  */
 
-static void
-discard_pending_stop_replies (struct inferior *inf)
+void
+remote_target::discard_pending_stop_replies (struct inferior *inf)
 {
   struct queue_iter_param param;
   struct stop_reply *reply;
@@ -6901,11 +7138,12 @@  discard_pending_stop_replies (struct inferior *inf)
       rns->pending_event[notif_client_stop.id] = NULL;
     }
 
+  param.remote = this;
   param.input = inf;
   param.output = NULL;
   /* Discard the stop replies we have already pulled with
      vStopped.  */
-  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+  QUEUE_iterate (stop_reply_p, rs->stop_reply_queue,
 		 remove_stop_reply_for_inferior, &param);
 }
 
@@ -6932,16 +7170,18 @@  remove_stop_reply_of_remote_state (QUEUE (stop_reply_p) *q,
 
 /* Discard the stop replies for RS in stop_reply_queue.  */
 
-static void
-discard_pending_stop_replies_in_queue (struct remote_state *rs)
+void
+remote_target::discard_pending_stop_replies_in_queue ()
 {
+  remote_state *rs = get_remote_state ();
   struct queue_iter_param param;
 
+  param.remote = this;
   param.input = rs;
   param.output = NULL;
   /* Discard the stop replies we have already pulled with
      vStopped.  */
-  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+  QUEUE_iterate (stop_reply_p, rs->stop_reply_queue,
 		 remove_stop_reply_of_remote_state, &param);
 }
 
@@ -6969,15 +7209,16 @@  remote_notif_remove_once_on_match (QUEUE (stop_reply_p) *q,
 /* Remove the first reply in 'stop_reply_queue' which matches
    PTID.  */
 
-static struct stop_reply *
-remote_notif_remove_queued_reply (ptid_t ptid)
+struct stop_reply *
+remote_target::remote_notif_remove_queued_reply (ptid_t ptid)
 {
   struct queue_iter_param param;
 
+  param.remote = this;
   param.input = &ptid;
   param.output = NULL;
 
-  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+  QUEUE_iterate (stop_reply_p, get_remote_state ()->stop_reply_queue,
 		 remote_notif_remove_once_on_match, &param);
   if (notif_debug)
     fprintf_unfiltered (gdb_stdlog,
@@ -6992,14 +7233,17 @@  remote_notif_remove_queued_reply (ptid_t ptid)
    found.  If there are still queued events left to process, tell the
    event loop to get back to target_wait soon.  */
 
-static struct stop_reply *
-queued_stop_reply (ptid_t ptid)
+struct stop_reply *
+remote_target::queued_stop_reply (ptid_t ptid)
 {
   struct stop_reply *r = remote_notif_remove_queued_reply (ptid);
 
-  if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue))
-    /* There's still at least an event left.  */
-    mark_async_event_handler (remote_async_inferior_event_token);
+  if (!QUEUE_is_empty (stop_reply_p, get_remote_state ()->stop_reply_queue))
+    {
+      remote_state *rs = get_remote_state ();
+      /* There's still at least an event left.  */
+      mark_async_event_handler (rs->remote_async_inferior_event_token);
+    }
 
   return r;
 }
@@ -7008,19 +7252,20 @@  queued_stop_reply (ptid_t ptid)
    know that we now have at least one queued event left to pass to the
    core side, tell the event loop to get back to target_wait soon.  */
 
-static void
-push_stop_reply (struct stop_reply *new_event)
+void
+remote_target::push_stop_reply (struct stop_reply *new_event)
 {
-  QUEUE_enque (stop_reply_p, stop_reply_queue, new_event);
+  remote_state *rs = get_remote_state ();
+  QUEUE_enque (stop_reply_p, rs->stop_reply_queue, new_event);
 
   if (notif_debug)
     fprintf_unfiltered (gdb_stdlog,
 			"notif: push 'Stop' %s to queue %d\n",
 			target_pid_to_str (new_event->ptid),
 			QUEUE_length (stop_reply_p,
-				      stop_reply_queue));
+				      rs->stop_reply_queue));
 
-  mark_async_event_handler (remote_async_inferior_event_token);
+  mark_async_event_handler (rs->remote_async_inferior_event_token);
 }
 
 static int
@@ -7037,10 +7282,11 @@  stop_reply_match_ptid_and_ws (QUEUE (stop_reply_p) *q,
 
 /* Returns true if we have a stop reply for PTID.  */
 
-static int
-peek_stop_reply (ptid_t ptid)
+int
+remote_target::peek_stop_reply (ptid_t ptid)
 {
-  return !QUEUE_iterate (stop_reply_p, stop_reply_queue,
+  remote_state *rs = get_remote_state ();
+  return !QUEUE_iterate (stop_reply_p, rs->stop_reply_queue,
 			 stop_reply_match_ptid_and_ws, &ptid);
 }
 
@@ -7059,8 +7305,8 @@  strprefix (const char *p, const char *pend, const char *prefix)
 /* Parse the stop reply in BUF.  Either the function succeeds, and the
    result is stored in EVENT, or throws an error.  */
 
-static void
-remote_parse_stop_reply (char *buf, struct stop_reply *event)
+void
+remote_target::remote_parse_stop_reply (char *buf, stop_reply *event)
 {
   remote_arch_state *rsa = NULL;
   ULONGEST addr;
@@ -7458,7 +7704,7 @@  Packet: '%s'\n"),
 */
 
 void
-remote_notif_get_pending_events (struct notif_client *nc)
+remote_target::remote_notif_get_pending_events (notif_client *nc)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -7470,7 +7716,7 @@  remote_notif_get_pending_events (struct notif_client *nc)
 			    nc->name);
 
       /* acknowledge */
-      nc->ack (nc, rs->buf, rs->notif_state->pending_event[nc->id]);
+      nc->ack (this, nc, rs->buf, rs->notif_state->pending_event[nc->id]);
       rs->notif_state->pending_event[nc->id] = NULL;
 
       while (1)
@@ -7479,7 +7725,7 @@  remote_notif_get_pending_events (struct notif_client *nc)
 	  if (strcmp (rs->buf, "OK") == 0)
 	    break;
 	  else
-	    remote_notif_ack (nc, rs->buf);
+	    remote_notif_ack (this, nc, rs->buf);
 	}
     }
   else
@@ -7491,13 +7737,22 @@  remote_notif_get_pending_events (struct notif_client *nc)
     }
 }
 
+/* Wrapper around remote_target::remote_notif_get_pending_events to
+   avoid having to export the whole remote_target class.  */
+
+void
+remote_notif_get_pending_events (remote_target *remote, notif_client *nc)
+{
+  remote->remote_notif_get_pending_events (nc);
+}
+
 /* Called when it is decided that STOP_REPLY holds the info of the
    event that is to be returned to the core.  This function always
    destroys STOP_REPLY.  */
 
-static ptid_t
-process_stop_reply (struct stop_reply *stop_reply,
-		    struct target_waitstatus *status)
+ptid_t
+remote_target::process_stop_reply (struct stop_reply *stop_reply,
+				   struct target_waitstatus *status)
 {
   ptid_t ptid;
 
@@ -7546,8 +7801,8 @@  process_stop_reply (struct stop_reply *stop_reply,
 
 /* The non-stop mode version of target_wait.  */
 
-static ptid_t
-remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct remote_state *rs = get_remote_state ();
   struct stop_reply *stop_reply;
@@ -7605,8 +7860,8 @@  remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
 /* Wait until the remote machine stops, then return, storing status in
    STATUS just as `wait' would.  */
 
-static ptid_t
-remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+remote_target::wait_as (ptid_t ptid, target_waitstatus *status, int options)
 {
   struct remote_state *rs = get_remote_state ();
   ptid_t event_ptid = null_ptid;
@@ -7630,7 +7885,7 @@  remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       int ret;
       int is_notif;
       int forever = ((options & TARGET_WNOHANG) == 0
-		     && wait_forever_enabled_p);
+		     && rs->wait_forever_enabled_p);
 
       if (!rs->waiting_for_stop_reply)
 	{
@@ -7678,7 +7933,7 @@  remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
 	 for a stop reply.  See the comments in putpkt_binary.  Set
 	 waiting_for_stop_reply to 0 temporarily.  */
       rs->waiting_for_stop_reply = 0;
-      remote_fileio_request (buf, rs->ctrlc_pending_p);
+      remote_fileio_request (this, buf, rs->ctrlc_pending_p);
       rs->ctrlc_pending_p = 0;
       /* GDB handled the File-I/O request, and the target is running
 	 again.  Keep waiting for events.  */
@@ -7692,7 +7947,8 @@  remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
 	rs->waiting_for_stop_reply = 0;
 
 	stop_reply
-	  = (struct stop_reply *) remote_notif_parse (&notif_client_stop,
+	  = (struct stop_reply *) remote_notif_parse (this,
+						      &notif_client_stop,
 						      rs->buf);
 
 	event_ptid = process_stop_reply (stop_reply, status);
@@ -7758,16 +8014,18 @@  remote_target::wait (ptid_t ptid, struct target_waitstatus *status, int options)
   ptid_t event_ptid;
 
   if (target_is_non_stop_p ())
-    event_ptid = remote_wait_ns (ptid, status, options);
+    event_ptid = wait_ns (ptid, status, options);
   else
-    event_ptid = remote_wait_as (ptid, status, options);
+    event_ptid = wait_as (ptid, status, options);
 
   if (target_is_async_p ())
     {
+      remote_state *rs = get_remote_state ();
+
       /* If there are are events left in the queue tell the event loop
 	 to return here.  */
-      if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue))
-	mark_async_event_handler (remote_async_inferior_event_token);
+      if (!QUEUE_is_empty (stop_reply_p, rs->stop_reply_queue))
+	mark_async_event_handler (rs->remote_async_inferior_event_token);
     }
 
   return event_ptid;
@@ -7775,8 +8033,9 @@  remote_target::wait (ptid_t ptid, struct target_waitstatus *status, int options)
 
 /* Fetch a single register using a 'p' packet.  */
 
-static int
-fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg)
+int
+remote_target::fetch_register_using_p (struct regcache *regcache,
+				       packet_reg *reg)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
@@ -7836,8 +8095,8 @@  fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg)
 
 /* Fetch the registers included in the target's 'g' packet.  */
 
-static int
-send_g_packet (void)
+int
+remote_target::send_g_packet ()
 {
   struct remote_state *rs = get_remote_state ();
   int buf_len;
@@ -7872,8 +8131,8 @@  send_g_packet (void)
   return buf_len / 2;
 }
 
-static void
-process_g_packet (struct regcache *regcache)
+void
+remote_target::process_g_packet (struct regcache *regcache)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
@@ -7977,8 +8236,8 @@  process_g_packet (struct regcache *regcache)
     }
 }
 
-static void
-fetch_registers_using_g (struct regcache *regcache)
+void
+remote_target::fetch_registers_using_g (struct regcache *regcache)
 {
   send_g_packet ();
   process_g_packet (regcache);
@@ -7987,8 +8246,8 @@  fetch_registers_using_g (struct regcache *regcache)
 /* Make the remote selected traceframe match GDB's selected
    traceframe.  */
 
-static void
-set_remote_traceframe (void)
+void
+remote_target::set_remote_traceframe ()
 {
   int newnum;
   struct remote_state *rs = get_remote_state ();
@@ -8084,9 +8343,9 @@  remote_target::prepare_to_store (struct regcache *regcache)
 /* Helper: Attempt to store REGNUM using the P packet.  Return fail IFF
    packet was not recognized.  */
 
-static int
-store_register_using_P (const struct regcache *regcache, 
-			struct packet_reg *reg)
+int
+remote_target::store_register_using_P (const struct regcache *regcache,
+				       packet_reg *reg)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
@@ -8125,8 +8384,8 @@  store_register_using_P (const struct regcache *regcache,
 /* Store register REGNUM, or all registers if REGNUM == -1, from the
    contents of the register cache buffer.  FIXME: ignores errors.  */
 
-static void
-store_registers_using_G (const struct regcache *regcache)
+void
+remote_target::store_registers_using_G (const struct regcache *regcache)
 {
   struct remote_state *rs = get_remote_state ();
   remote_arch_state *rsa = rs->get_remote_arch_state (regcache->arch ());
@@ -8286,8 +8545,8 @@  remote_address_masked (CORE_ADDR addr)
    clean.  In cases like this, the user should clear "remote
    X-packet".  */
 
-static void
-check_binary_download (CORE_ADDR addr)
+void
+remote_target::check_binary_download (CORE_ADDR addr)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -8377,11 +8636,13 @@  align_for_efficient_write (int todo, CORE_ADDR memaddr)
    -> $m1000,4#??
    <- eeeeffffeeeedddd  */
 
-static enum target_xfer_status
-remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
-			const gdb_byte *myaddr, ULONGEST len_units,
-			int unit_size, ULONGEST *xfered_len_units,
-			char packet_format, int use_length)
+target_xfer_status
+remote_target::remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
+				       const gdb_byte *myaddr,
+				       ULONGEST len_units,
+				       int unit_size,
+				       ULONGEST *xfered_len_units,
+				       char packet_format, int use_length)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
@@ -8540,9 +8801,10 @@  remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
    'enum target_xfer_status' value).  Save the number of bytes
    transferred in *XFERED_LEN.  Only transfer a single packet.  */
 
-static enum target_xfer_status
-remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len,
-		    int unit_size, ULONGEST *xfered_len)
+target_xfer_status
+remote_target::remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr,
+				   ULONGEST len, int unit_size,
+				   ULONGEST *xfered_len)
 {
   const char *packet_format = NULL;
 
@@ -8583,9 +8845,10 @@  remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len,
    See the comment of remote_write_bytes_aux for an example of
    memory read/write exchange between gdb and the stub.  */
 
-static enum target_xfer_status
-remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len_units,
-		     int unit_size, ULONGEST *xfered_len_units)
+target_xfer_status
+remote_target::remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr,
+				    ULONGEST len_units,
+				    int unit_size, ULONGEST *xfered_len_units)
 {
   struct remote_state *rs = get_remote_state ();
   int buf_size_bytes;		/* Max size of packet output buffer.  */
@@ -8630,15 +8893,17 @@  remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len_units,
    For interface/parameters/return description see target.h,
    to_xfer_partial.  */
 
-static enum target_xfer_status
-remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
-				   ULONGEST memaddr, ULONGEST len,
-				   int unit_size, ULONGEST *xfered_len)
+target_xfer_status
+remote_target::remote_xfer_live_readonly_partial (gdb_byte *readbuf,
+						  ULONGEST memaddr,
+						  ULONGEST len,
+						  int unit_size,
+						  ULONGEST *xfered_len)
 {
   struct target_section *secp;
   struct target_section_table *table;
 
-  secp = target_section_by_addr (ops, memaddr);
+  secp = target_section_by_addr (this, memaddr);
   if (secp != NULL
       && (bfd_get_section_flags (secp->the_bfd_section->owner,
 				 secp->the_bfd_section)
@@ -8647,7 +8912,7 @@  remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
       struct target_section *p;
       ULONGEST memend = memaddr + len;
 
-      table = target_get_section_table (ops);
+      table = target_get_section_table (this);
 
       for (p = table->sections; p < table->sections_end; p++)
 	{
@@ -8682,10 +8947,10 @@  remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
    first if the requested memory is unavailable in traceframe.
    Otherwise, fall back to remote_read_bytes_1.  */
 
-static enum target_xfer_status
-remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
-		   gdb_byte *myaddr, ULONGEST len, int unit_size,
-		   ULONGEST *xfered_len)
+target_xfer_status
+remote_target::remote_read_bytes (CORE_ADDR memaddr,
+				  gdb_byte *myaddr, ULONGEST len, int unit_size,
+				  ULONGEST *xfered_len)
 {
   if (len == 0)
     return TARGET_XFER_EOF;
@@ -8715,7 +8980,7 @@  remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
 		}
 
 	      /* This goes through the topmost target again.  */
-	      res = remote_xfer_live_readonly_partial (ops, myaddr, memaddr,
+	      res = remote_xfer_live_readonly_partial (myaddr, memaddr,
 						       len, unit_size, xfered_len);
 	      if (res == TARGET_XFER_OK)
 		return TARGET_XFER_OK;
@@ -8746,11 +9011,8 @@  remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
    FORMAT and the remaining arguments, then gets the reply.  Returns
    whether the packet was a success, a failure, or unknown.  */
 
-static enum packet_result remote_send_printf (const char *format, ...)
-  ATTRIBUTE_PRINTF (1, 2);
-
-static enum packet_result
-remote_send_printf (const char *format, ...)
+packet_result
+remote_target::remote_send_printf (const char *format, ...)
 {
   struct remote_state *rs = get_remote_state ();
   int max_size = get_remote_packet_size ();
@@ -8798,10 +9060,10 @@  remote_target::flash_erase (ULONGEST address, LONGEST length)
     }
 }
 
-static enum target_xfer_status
-remote_flash_write (struct target_ops *ops, ULONGEST address,
-		    ULONGEST length, ULONGEST *xfered_len,
-		    const gdb_byte *data)
+target_xfer_status
+remote_target::remote_flash_write (ULONGEST address,
+				   ULONGEST length, ULONGEST *xfered_len,
+				   const gdb_byte *data)
 {
   scoped_restore restore_timeout
     = make_scoped_restore (&remote_timeout, remote_flash_timeout);
@@ -8860,15 +9122,17 @@  unpush_and_perror (const char *string)
    sequence, as that would break communication with the remote server.
    See remote_serial_quit_handler for more detail.  */
 
-static int
-readchar (int timeout)
+int
+remote_target::readchar (int timeout)
 {
   int ch;
   struct remote_state *rs = get_remote_state ();
 
   {
+    scoped_restore restore_quit_target
+      = make_scoped_restore (&curr_quit_handler_target, this);
     scoped_restore restore_quit
-      = make_scoped_restore (&quit_handler, remote_serial_quit_handler);
+      = make_scoped_restore (&quit_handler, ::remote_serial_quit_handler);
 
     rs->got_ctrlc_during_io = 0;
 
@@ -8903,13 +9167,15 @@  readchar (int timeout)
    communication with the remote server.  See
    remote_serial_quit_handler for more detail.  */
 
-static void
-remote_serial_write (const char *str, int len)
+void
+remote_target::remote_serial_write (const char *str, int len)
 {
   struct remote_state *rs = get_remote_state ();
 
+  scoped_restore restore_quit_target
+    = make_scoped_restore (&curr_quit_handler_target, this);
   scoped_restore restore_quit
-    = make_scoped_restore (&quit_handler, remote_serial_quit_handler);
+    = make_scoped_restore (&quit_handler, ::remote_serial_quit_handler);
 
   rs->got_ctrlc_during_io = 0;
 
@@ -8947,19 +9213,28 @@  print_packet (const char *buf)
 }
 
 int
-putpkt (const char *buf)
+remote_target::putpkt (const char *buf)
 {
   return putpkt_binary (buf, strlen (buf));
 }
 
+/* Wrapper around remote_target::putpkt to avoid exporting
+   remote_target.  */
+
+int
+putpkt (remote_target *remote, const char *buf)
+{
+  return remote->putpkt (buf);
+}
+
 /* Send a packet to the remote machine, with error checking.  The data
    of the packet is in BUF.  The string in BUF can be at most
    get_remote_packet_size () - 5 to account for the $, # and checksum,
    and for a possible /0 if we are debugging (remote_debug) and want
    to print the sent packet as a string.  */
 
-static int
-putpkt_binary (const char *buf, int cnt)
+int
+remote_target::putpkt_binary (const char *buf, int cnt)
 {
   struct remote_state *rs = get_remote_state ();
   int i;
@@ -9164,8 +9439,8 @@  putpkt_binary (const char *buf, int cnt)
 /* Come here after finding the start of a frame when we expected an
    ack.  Do our best to discard the rest of this packet.  */
 
-static void
-skip_frame (void)
+void
+remote_target::skip_frame ()
 {
   int c;
 
@@ -9206,9 +9481,8 @@  skip_frame (void)
    trailing NULL) on success. (could be extended to return one of the
    SERIAL status indications).  */
 
-static long
-read_frame (char **buf_p,
-	    long *sizeof_buf)
+long
+remote_target::read_frame (char **buf_p, long *sizeof_buf)
 {
   unsigned char csum;
   long bc;
@@ -9338,10 +9612,9 @@  read_frame (char **buf_p,
    don't have to change all the calls to getpkt to deal with the
    return value, because at the moment I don't know what the right
    thing to do it for those.  */
+
 void
-getpkt (char **buf,
-	long *sizeof_buf,
-	int forever)
+remote_target::getpkt (char **buf, long *sizeof_buf, int forever)
 {
   getpkt_sane (buf, sizeof_buf, forever);
 }
@@ -9359,9 +9632,10 @@  getpkt (char **buf,
    boolean that indicates whether *BUF holds a notification or not
    (a regular packet).  */
 
-static int
-getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
-			int expecting_notif, int *is_notif)
+int
+remote_target::getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf,
+				       int forever, int expecting_notif,
+				       int *is_notif)
 {
   struct remote_state *rs = get_remote_state ();
   int c;
@@ -9500,15 +9774,15 @@  getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
     }
 }
 
-static int
-getpkt_sane (char **buf, long *sizeof_buf, int forever)
+int
+remote_target::getpkt_sane (char **buf, long *sizeof_buf, int forever)
 {
   return getpkt_or_notif_sane_1 (buf, sizeof_buf, forever, 0, NULL);
 }
 
-static int
-getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
-		      int *is_notif)
+int
+remote_target::getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
+				     int *is_notif)
 {
   return getpkt_or_notif_sane_1 (buf, sizeof_buf, forever, 1,
 				 is_notif);
@@ -9517,22 +9791,22 @@  getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
 /* Check whether EVENT is a fork event for the process specified
    by the pid passed in DATA, and if it is, kill the fork child.  */
 
-static int
-kill_child_of_pending_fork (QUEUE (stop_reply_p) *q,
-			    QUEUE_ITER (stop_reply_p) *iter,
-			    stop_reply_p event,
-			    void *data)
+int
+remote_kill_child_of_pending_fork (QUEUE (stop_reply_p) *q,
+				   QUEUE_ITER (stop_reply_p) *iter,
+				   stop_reply_p event,
+				   void *data)
 {
   struct queue_iter_param *param = (struct queue_iter_param *) data;
   int parent_pid = *(int *) param->input;
 
   if (is_pending_fork_parent (&event->ws, parent_pid, event->ptid))
     {
-      struct remote_state *rs = get_remote_state ();
+      remote_target *remote = param->remote;
       int child_pid = ptid_get_pid (event->ws.value.related_pid);
       int res;
 
-      res = remote_vkill (child_pid, rs);
+      res = remote->remote_vkill (child_pid);
       if (res != 0)
 	error (_("Can't kill fork child process %d"), child_pid);
     }
@@ -9543,9 +9817,10 @@  kill_child_of_pending_fork (QUEUE (stop_reply_p) *q,
 /* Kill any new fork children of process PID that haven't been
    processed by follow_fork.  */
 
-static void
-kill_new_fork_children (int pid, struct remote_state *rs)
+void
+remote_target::kill_new_fork_children (int pid)
 {
+  remote_state *rs = get_remote_state ();
   struct thread_info *thread;
   struct notif_client *notif = &notif_client_stop;
   struct queue_iter_param param;
@@ -9558,11 +9833,10 @@  kill_new_fork_children (int pid, struct remote_state *rs)
 
       if (is_pending_fork_parent (ws, pid, thread->ptid))
 	{
-	  struct remote_state *rs = get_remote_state ();
 	  int child_pid = ptid_get_pid (ws->value.related_pid);
 	  int res;
 
-	  res = remote_vkill (child_pid, rs);
+	  res = remote_vkill (child_pid);
 	  if (res != 0)
 	    error (_("Can't kill fork child process %d"), child_pid);
 	}
@@ -9571,10 +9845,11 @@  kill_new_fork_children (int pid, struct remote_state *rs)
   /* Check for any pending fork events (not reported or processed yet)
      in process PID and kill those fork child threads as well.  */
   remote_notif_get_pending_events (notif);
+  param.remote = this;
   param.input = &pid;
   param.output = NULL;
-  QUEUE_iterate (stop_reply_p, stop_reply_queue,
-		 kill_child_of_pending_fork, &param);
+  QUEUE_iterate (stop_reply_p, rs->stop_reply_queue,
+		 remote_kill_child_of_pending_fork, &param);
 }
 
 
@@ -9593,9 +9868,9 @@  remote_target::kill ()
 	 kill the child task.  We need to do this before killing the
 	 parent task because if this is a vfork then the parent will
 	 be sleeping.  */
-      kill_new_fork_children (pid, rs);
+      kill_new_fork_children (pid);
 
-      res = remote_vkill (pid, rs);
+      res = remote_vkill (pid);
       if (res == 0)
 	{
 	  target_mourn_inferior (inferior_ptid);
@@ -9625,12 +9900,14 @@  remote_target::kill ()
 
 /* Send a kill request to the target using the 'vKill' packet.  */
 
-static int
-remote_vkill (int pid, struct remote_state *rs)
+int
+remote_target::remote_vkill (int pid)
 {
   if (packet_support (PACKET_vKill) == PACKET_DISABLE)
     return -1;
 
+  remote_state *rs = get_remote_state ();
+
   /* Tell the remote target to detach.  */
   xsnprintf (rs->buf, get_remote_packet_size (), "vKill;%x", pid);
   putpkt (rs->buf);
@@ -9652,8 +9929,8 @@  remote_vkill (int pid, struct remote_state *rs)
 
 /* Send a kill request to the target using the 'k' packet.  */
 
-static void
-remote_kill_k (void)
+void
+remote_target::remote_kill_k ()
 {
   /* Catch errors so the user can quit from gdb even when we
      aren't on speaking terms with the remote system.  */
@@ -9760,8 +10037,8 @@  extended_remote_target::supports_disable_randomization ()
   return packet_support (PACKET_QDisableRandomization) == PACKET_ENABLE;
 }
 
-static void
-extended_remote_disable_randomization (int val)
+void
+remote_target::extended_remote_disable_randomization (int val)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -9776,8 +10053,8 @@  extended_remote_disable_randomization (int val)
     error (_("Bogus QDisableRandomization reply from target: %s"), reply);
 }
 
-static int
-extended_remote_run (const std::string &args)
+int
+remote_target::extended_remote_run (const std::string &args)
 {
   struct remote_state *rs = get_remote_state ();
   int len;
@@ -9840,12 +10117,13 @@  extended_remote_run (const std::string &args)
    or "QEnvironmentUnsetVariable".  VALUE is the variable to be
    sent.  */
 
-static void
-send_environment_packet (struct remote_state *rs,
-			 const char *action,
-			 const char *packet,
-			 const char *value)
+void
+remote_target::send_environment_packet (const char *action,
+					const char *packet,
+					const char *value)
 {
+  remote_state *rs = get_remote_state ();
+
   /* Convert the environment variable to an hex string, which
      is the best format to be transmitted over the wire.  */
   std::string encoded_value = bin2hex ((const gdb_byte *) value,
@@ -9863,9 +10141,11 @@  send_environment_packet (struct remote_state *rs,
 
 /* Helper function to handle the QEnvironment* packets.  */
 
-static void
-extended_remote_environment_support (struct remote_state *rs)
+void
+remote_target::extended_remote_environment_support ()
 {
+  remote_state *rs = get_remote_state ();
+
   if (packet_support (PACKET_QEnvironmentReset) != PACKET_DISABLE)
     {
       putpkt ("QEnvironmentReset");
@@ -9878,23 +10158,24 @@  extended_remote_environment_support (struct remote_state *rs)
 
   if (packet_support (PACKET_QEnvironmentHexEncoded) != PACKET_DISABLE)
     for (const std::string &el : e->user_set_env ())
-      send_environment_packet (rs, "set", "QEnvironmentHexEncoded",
+      send_environment_packet ("set", "QEnvironmentHexEncoded",
 			       el.c_str ());
 
   if (packet_support (PACKET_QEnvironmentUnset) != PACKET_DISABLE)
     for (const std::string &el : e->user_unset_env ())
-      send_environment_packet (rs, "unset", "QEnvironmentUnset", el.c_str ());
+      send_environment_packet ("unset", "QEnvironmentUnset", el.c_str ());
 }
 
 /* Helper function to set the current working directory for the
    inferior in the remote target.  */
 
-static void
-extended_remote_set_inferior_cwd (struct remote_state *rs)
+void
+remote_target::extended_remote_set_inferior_cwd ()
 {
   if (packet_support (PACKET_QSetWorkingDir) != PACKET_DISABLE)
     {
       const char *inferior_cwd = get_inferior_cwd ();
+      remote_state *rs = get_remote_state ();
 
       if (inferior_cwd != NULL)
 	{
@@ -9964,9 +10245,9 @@  Remote replied unexpectedly while setting startup-with-shell: %s"),
 	       rs->buf);
     }
 
-  extended_remote_environment_support (rs);
+  extended_remote_environment_support ();
 
-  extended_remote_set_inferior_cwd (rs);
+  extended_remote_set_inferior_cwd ();
 
   /* Now restart the remote server.  */
   run_worked = extended_remote_run (args) != -1;
@@ -10593,11 +10874,12 @@  the loaded file\n"));
    into remote target.  The number of bytes written to the remote
    target is returned, or -1 for error.  */
 
-static enum target_xfer_status
-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)
+target_xfer_status
+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)
 {
   int i, buf_len;
   ULONGEST n;
@@ -10636,12 +10918,13 @@  remote_write_qxfer (const char *object_name,
    EOF.  PACKET is checked and updated to indicate whether the remote
    target supports this object.  */
 
-static enum 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)
+target_xfer_status
+remote_target::remote_read_qxfer (const char *object_name,
+				  const char *annex,
+				  gdb_byte *readbuf, ULONGEST offset,
+				  LONGEST len,
+				  ULONGEST *xfered_len,
+				  struct packet_config *packet)
 {
   struct remote_state *rs = get_remote_state ();
   LONGEST i, n, packet_len;
@@ -10747,7 +11030,7 @@  remote_target::xfer_partial (enum target_object object,
 	return remote_write_bytes (offset, writebuf, len, unit_size,
 				   xfered_len);
       else
-	return remote_read_bytes (this, offset, readbuf, len, unit_size,
+	return remote_read_bytes (offset, readbuf, len, unit_size,
 				  xfered_len);
     }
 
@@ -10795,7 +11078,7 @@  remote_target::xfer_partial (enum target_object object,
       switch (object)
 	{
 	case TARGET_OBJECT_FLASH:
-	  return remote_flash_write (this, offset, len, xfered_len,
+	  return remote_flash_write (offset, len, xfered_len,
 				     writebuf);
 
 	default:
@@ -11114,11 +11397,17 @@  remote_target::memory_map ()
 static void
 packet_command (const char *args, int from_tty)
 {
-  struct remote_state *rs = get_remote_state ();
+  remote_target *remote = get_current_remote_target ();
 
-  if (!rs->remote_desc)
+  if (remote == nullptr)
     error (_("command can only be used with remote target"));
 
+  remote->packet_command (args, from_tty);
+}
+
+void
+remote_target::packet_command (const char *args, int from_tty)
+{
   if (!args)
     error (_("remote-packet command requires packet text as argument"));
 
@@ -11127,6 +11416,8 @@  packet_command (const char *args, int from_tty)
   puts_filtered ("\n");
   putpkt (args);
 
+  remote_state *rs = get_remote_state ();
+
   getpkt (&rs->buf, &rs->buf_size, 0);
   puts_filtered ("received: ");
   print_packet (rs->buf);
@@ -11653,10 +11944,10 @@  remote_hostio_parse_result (char *buffer, int *retcode,
    the packet buffer and *ATTACHMENT_LEN will be set to the
    attachment's length.  */
 
-static int
-remote_hostio_send_command (int command_bytes, int which_packet,
-			    int *remote_errno, char **attachment,
-			    int *attachment_len)
+int
+remote_target::remote_hostio_send_command (int command_bytes, int which_packet,
+					   int *remote_errno, char **attachment,
+					   int *attachment_len)
 {
   struct remote_state *rs = get_remote_state ();
   int ret, bytes_read;
@@ -11738,8 +12029,9 @@  readahead_cache::invalidate_fd (int fd)
    arguments will use.  Return 0 on success, or -1 if an error
    occurs (and set *REMOTE_ERRNO).  */
 
-static int
-remote_hostio_set_filesystem (struct inferior *inf, int *remote_errno)
+int
+remote_target::remote_hostio_set_filesystem (struct inferior *inf,
+					     int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   int required_pid = (inf == NULL || inf->fake_pid_p) ? 0 : inf->pid;
@@ -11773,11 +12065,10 @@  remote_hostio_set_filesystem (struct inferior *inf, int *remote_errno)
 
 /* Implementation of to_fileio_open.  */
 
-static int
-remote_hostio_open (struct target_ops *self,
-		    struct inferior *inf, const char *filename,
-		    int flags, int mode, int warn_if_slow,
-		    int *remote_errno)
+int
+remote_target::remote_hostio_open (inferior *inf, const char *filename,
+				   int flags, int mode, int warn_if_slow,
+				   int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -11822,16 +12113,15 @@  remote_target::fileio_open (struct inferior *inf, const char *filename,
 			    int flags, int mode, int warn_if_slow,
 			    int *remote_errno)
 {
-  return remote_hostio_open (this, inf, filename, flags, mode, warn_if_slow,
+  return remote_hostio_open (inf, filename, flags, mode, warn_if_slow,
 			     remote_errno);
 }
 
 /* Implementation of to_fileio_pwrite.  */
 
-static int
-remote_hostio_pwrite (struct target_ops *self,
-		      int fd, const gdb_byte *write_buf, int len,
-		      ULONGEST offset, int *remote_errno)
+int
+remote_target::remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len,
+				     ULONGEST offset, int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -11859,16 +12149,15 @@  int
 remote_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
 			      ULONGEST offset, int *remote_errno)
 {
-  return remote_hostio_pwrite (this, fd, write_buf, len, offset, remote_errno);
+  return remote_hostio_pwrite (fd, write_buf, len, offset, remote_errno);
 }
 
 /* Helper for the implementation of to_fileio_pread.  Read the file
    from the remote side with vFile:pread.  */
 
-static int
-remote_hostio_pread_vFile (struct target_ops *self,
-			   int fd, gdb_byte *read_buf, int len,
-			   ULONGEST offset, int *remote_errno)
+int
+remote_target::remote_hostio_pread_vFile (int fd, gdb_byte *read_buf, int len,
+					  ULONGEST offset, int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -11926,10 +12215,9 @@  readahead_cache::pread (int fd, gdb_byte *read_buf, size_t len,
 
 /* Implementation of to_fileio_pread.  */
 
-static int
-remote_hostio_pread (struct target_ops *self,
-		     int fd, gdb_byte *read_buf, int len,
-		     ULONGEST offset, int *remote_errno)
+int
+remote_target::remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
+				    ULONGEST offset, int *remote_errno)
 {
   int ret;
   struct remote_state *rs = get_remote_state ();
@@ -11956,7 +12244,7 @@  remote_hostio_pread (struct target_ops *self,
   cache->bufsize = get_remote_packet_size ();
   cache->buf = (gdb_byte *) xrealloc (cache->buf, cache->bufsize);
 
-  ret = remote_hostio_pread_vFile (self, cache->fd, cache->buf, cache->bufsize,
+  ret = remote_hostio_pread_vFile (cache->fd, cache->buf, cache->bufsize,
 				   cache->offset, remote_errno);
   if (ret <= 0)
     {
@@ -11972,13 +12260,13 @@  int
 remote_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
 			     ULONGEST offset, int *remote_errno)
 {
-  return remote_hostio_pread (this, fd, read_buf, len, offset, remote_errno);
+  return remote_hostio_pread (fd, read_buf, len, offset, remote_errno);
 }
 
 /* Implementation of to_fileio_close.  */
 
-static int
-remote_hostio_close (struct target_ops *self, int fd, int *remote_errno)
+int
+remote_target::remote_hostio_close (int fd, int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -11997,15 +12285,14 @@  remote_hostio_close (struct target_ops *self, int fd, int *remote_errno)
 int
 remote_target::fileio_close (int fd, int *remote_errno)
 {
-  return remote_hostio_close (this, fd, remote_errno);
+  return remote_hostio_close (fd, remote_errno);
 }
 
 /* Implementation of to_fileio_unlink.  */
 
-static int
-remote_hostio_unlink (struct target_ops *self,
-		      struct inferior *inf, const char *filename,
-		      int *remote_errno)
+int
+remote_target::remote_hostio_unlink (inferior *inf, const char *filename,
+				     int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -12027,7 +12314,7 @@  int
 remote_target::fileio_unlink (struct inferior *inf, const char *filename,
 			      int *remote_errno)
 {
-  return remote_hostio_unlink (this, inf, filename, remote_errno);
+  return remote_hostio_unlink (inf, filename, remote_errno);
 }
 
 /* Implementation of to_fileio_readlink.  */
@@ -12148,12 +12435,12 @@  remote_target::filesystem_is_local ()
 	  /* Try opening a file to probe support.  The supplied
 	     filename is irrelevant, we only care about whether
 	     the stub recognizes the packet or not.  */
-	  fd = remote_hostio_open (this, NULL, "just probing",
+	  fd = remote_hostio_open (NULL, "just probing",
 				   FILEIO_O_RDONLY, 0700, 0,
 				   &remote_errno);
 
 	  if (fd >= 0)
-	    remote_hostio_close (this, fd, &remote_errno);
+	    remote_hostio_close (fd, &remote_errno);
 
 	  ps = packet_support (PACKET_vFile_open);
 	}
@@ -12244,8 +12531,8 @@  remote_hostio_error (int errnum)
 class scoped_remote_fd
 {
 public:
-  explicit scoped_remote_fd (int fd)
-    : m_fd (fd)
+  scoped_remote_fd (remote_target *remote, int fd)
+    : m_remote (remote), m_fd (fd)
   {
   }
 
@@ -12254,8 +12541,7 @@  public:
     if (m_fd != -1)
       {
 	int remote_errno;
-	remote_hostio_close (find_target_at (process_stratum),
-			     m_fd, &remote_errno);
+	m_remote->remote_hostio_close (m_fd, &remote_errno);
       }
   }
 
@@ -12276,12 +12562,27 @@  public:
   }
 
 private:
+  /* The remote target.  */
+  remote_target *m_remote;
+
   /* The owned remote I/O file descriptor.  */
   int m_fd;
 };
 
 void
 remote_file_put (const char *local_file, const char *remote_file, int from_tty)
+{
+  remote_target *remote = get_current_remote_target ();
+
+  if (remote == nullptr)
+    error (_("command can only be used with remote target"));
+
+  remote->remote_file_put (local_file, remote_file, from_tty);
+}
+
+void
+remote_target::remote_file_put (const char *local_file, const char *remote_file,
+				int from_tty)
 {
   struct cleanup *back_to;
   int retcode, remote_errno, bytes, io_size;
@@ -12289,20 +12590,16 @@  remote_file_put (const char *local_file, const char *remote_file, int from_tty)
   int bytes_in_buffer;
   int saw_eof;
   ULONGEST offset;
-  struct remote_state *rs = get_remote_state ();
-
-  if (!rs->remote_desc)
-    error (_("command can only be used with remote target"));
 
   gdb_file_up file = gdb_fopen_cloexec (local_file, "rb");
   if (file == NULL)
     perror_with_name (local_file);
 
   scoped_remote_fd fd
-    (remote_hostio_open (find_target_at (process_stratum), NULL,
-			 remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
-				       | FILEIO_O_TRUNC),
-			 0700, 0, &remote_errno));
+    (this, remote_hostio_open (NULL,
+			       remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
+					     | FILEIO_O_TRUNC),
+			       0700, 0, &remote_errno));
   if (fd.get () == -1)
     remote_hostio_error (remote_errno);
 
@@ -12342,8 +12639,7 @@  remote_file_put (const char *local_file, const char *remote_file, int from_tty)
       bytes += bytes_in_buffer;
       bytes_in_buffer = 0;
 
-      retcode = remote_hostio_pwrite (find_target_at (process_stratum),
-				      fd.get (), buffer, bytes,
+      retcode = remote_hostio_pwrite (fd.get (), buffer, bytes,
 				      offset, &remote_errno);
 
       if (retcode < 0)
@@ -12361,8 +12657,7 @@  remote_file_put (const char *local_file, const char *remote_file, int from_tty)
       offset += retcode;
     }
 
-  if (remote_hostio_close (find_target_at (process_stratum),
-			   fd.release (), &remote_errno))
+  if (remote_hostio_close (fd.release (), &remote_errno))
     remote_hostio_error (remote_errno);
 
   if (from_tty)
@@ -12372,20 +12667,28 @@  remote_file_put (const char *local_file, const char *remote_file, int from_tty)
 
 void
 remote_file_get (const char *remote_file, const char *local_file, int from_tty)
+{
+  remote_target *remote = get_current_remote_target ();
+
+  if (remote == nullptr)
+    error (_("command can only be used with remote target"));
+
+  remote->remote_file_get (remote_file, local_file, from_tty);
+}
+
+void
+remote_target::remote_file_get (const char *remote_file, const char *local_file,
+				int from_tty)
 {
   struct cleanup *back_to;
   int remote_errno, bytes, io_size;
   gdb_byte *buffer;
   ULONGEST offset;
-  struct remote_state *rs = get_remote_state ();
-
-  if (!rs->remote_desc)
-    error (_("command can only be used with remote target"));
 
   scoped_remote_fd fd
-    (remote_hostio_open (find_target_at (process_stratum), NULL,
-			 remote_file, FILEIO_O_RDONLY, 0, 0,
-			 &remote_errno));
+    (this, remote_hostio_open (NULL,
+			       remote_file, FILEIO_O_RDONLY, 0, 0,
+			       &remote_errno));
   if (fd.get () == -1)
     remote_hostio_error (remote_errno);
 
@@ -12402,8 +12705,7 @@  remote_file_get (const char *remote_file, const char *local_file, int from_tty)
   offset = 0;
   while (1)
     {
-      bytes = remote_hostio_pread (find_target_at (process_stratum),
-				   fd.get (), buffer, io_size, offset,
+      bytes = remote_hostio_pread (fd.get (), buffer, io_size, offset,
 				   &remote_errno);
       if (bytes == 0)
 	/* Success, but no bytes, means end-of-file.  */
@@ -12418,8 +12720,7 @@  remote_file_get (const char *remote_file, const char *local_file, int from_tty)
 	perror_with_name (local_file);
     }
 
-  if (remote_hostio_close (find_target_at (process_stratum),
-			   fd.release (), &remote_errno))
+  if (remote_hostio_close (fd.release (), &remote_errno))
     remote_hostio_error (remote_errno);
 
   if (from_tty)
@@ -12430,14 +12731,20 @@  remote_file_get (const char *remote_file, const char *local_file, int from_tty)
 void
 remote_file_delete (const char *remote_file, int from_tty)
 {
-  int retcode, remote_errno;
-  struct remote_state *rs = get_remote_state ();
+  remote_target *remote = get_current_remote_target ();
 
-  if (!rs->remote_desc)
+  if (remote == nullptr)
     error (_("command can only be used with remote target"));
 
-  retcode = remote_hostio_unlink (find_target_at (process_stratum),
-				  NULL, remote_file, &remote_errno);
+  remote->remote_file_delete (remote_file, from_tty);
+}
+
+void
+remote_target::remote_file_delete (const char *remote_file, int from_tty)
+{
+  int retcode, remote_errno;
+
+  retcode = remote_hostio_unlink (NULL, remote_file, &remote_errno);
   if (retcode == -1)
     remote_hostio_error (remote_errno);
 
@@ -12584,9 +12891,9 @@  remote_target::trace_init ()
 /* Recursive routine to walk through command list including loops, and
    download packets for each command.  */
 
-static void
-remote_download_command_source (int num, ULONGEST addr,
-				struct command_line *cmds)
+void
+remote_target::remote_download_command_source (int num, ULONGEST addr,
+					       struct command_line *cmds)
 {
   struct remote_state *rs = get_remote_state ();
   struct command_line *cmd;
@@ -13426,17 +13733,15 @@  struct btrace_target_info
 /* Reset our idea of our target's btrace configuration.  */
 
 static void
-remote_btrace_reset (void)
+remote_btrace_reset (remote_state *rs)
 {
-  struct remote_state *rs = get_remote_state ();
-
   memset (&rs->btrace_config, 0, sizeof (rs->btrace_config));
 }
 
 /* Synchronize the configuration with the target.  */
 
-static void
-btrace_sync_conf (const struct btrace_config *conf)
+void
+remote_target::btrace_sync_conf (const btrace_config *conf)
 {
   struct packet_config *packet;
   struct remote_state *rs;
@@ -13505,8 +13810,8 @@  btrace_read_config (struct btrace_config *conf)
 
 /* Maybe reopen target btrace.  */
 
-static void
-remote_btrace_maybe_reopen (void)
+void
+remote_target::remote_btrace_maybe_reopen ()
 {
   struct remote_state *rs = get_remote_state ();
   struct thread_info *tp;
@@ -13772,7 +14077,7 @@  remote_target::can_do_single_step ()
       struct remote_state *rs = get_remote_state ();
 
       if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-	remote_vcont_probe (rs);
+	remote_vcont_probe ();
 
       return rs->supports_vCont.s && rs->supports_vCont.S;
     }
@@ -13863,7 +14168,7 @@  remote_async_serial_handler (struct serial *scb, void *context)
 static void
 remote_async_inferior_event_handler (gdb_client_data data)
 {
-  inferior_event_handler (INF_REG_EVENT, NULL);
+  inferior_event_handler (INF_REG_EVENT, data);
 }
 
 void
@@ -13877,8 +14182,8 @@  remote_target::async (int enable)
 
       /* If there are pending events in the stop reply queue tell the
 	 event loop to process them.  */
-      if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue))
-	mark_async_event_handler (remote_async_inferior_event_token);
+      if (!QUEUE_is_empty (stop_reply_p, rs->stop_reply_queue))
+	mark_async_event_handler (rs->remote_async_inferior_event_token);
       /* For simplicity, below we clear the pending events token
 	 without remembering whether it is marked, so here we always
 	 mark it.  If there's actually no pending notification to
@@ -13893,7 +14198,7 @@  remote_target::async (int enable)
       /* If the core is disabling async, it doesn't want to be
 	 disturbed with target events.  Clear all async event sources
 	 too.  */
-      clear_async_event_handler (remote_async_inferior_event_token);
+      clear_async_event_handler (rs->remote_async_inferior_event_token);
       if (target_is_non_stop_p ())
 	clear_async_event_handler (rs->notif_state->get_pending_events_token);
     }
@@ -13969,10 +14274,10 @@  show_remote_cmd (const char *args, int from_tty)
 static void
 remote_new_objfile (struct objfile *objfile)
 {
-  struct remote_state *rs = get_remote_state ();
+  remote_target *remote = get_current_remote_target ();
 
-  if (rs->remote_desc != 0)		/* Have a remote connection.  */
-    remote_check_symbols ();
+  if (remote != NULL)			/* Have a remote connection.  */
+    remote->remote_check_symbols ();
 }
 
 /* Pull all the tracepoints defined on the target and create local
@@ -14034,29 +14339,33 @@  show_range_stepping (struct ui_file *file, int from_tty,
 		      "is %s.\n"), value);
 }
 
+/* Return true if the vCont;r action is supported by the remote
+   stub.  */
+
+bool
+remote_target::vcont_r_supported ()
+{
+  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
+    remote_vcont_probe ();
+
+  return (packet_support (PACKET_vCont) == PACKET_ENABLE
+	  && get_remote_state ()->supports_vCont.r);
+}
+
 /* The "set/show range-stepping" set hook.  */
 
 static void
 set_range_stepping (const char *ignore_args, int from_tty,
 		    struct cmd_list_element *c)
 {
-  struct remote_state *rs = get_remote_state ();
-
-  /* Whene enabling, check whether range stepping is actually
-     supported by the target, and warn if not.  */
+  /* When enabling, check whether range stepping is actually supported
+     by the target, and warn if not.  */
   if (use_range_stepping)
     {
-      if (rs->remote_desc != NULL)
-	{
-	  if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
-	    remote_vcont_probe (rs);
-
-	  if (packet_support (PACKET_vCont) == PACKET_ENABLE
-	      && rs->supports_vCont.r)
-	    return;
-	}
-
-      warning (_("Range stepping is not supported by the current target"));
+      remote_target *remote = get_current_remote_target ();
+      if (remote == NULL
+	  || !remote->vcont_r_supported ())
+	warning (_("Range stepping is not supported by the current target"));
     }
 }
 
@@ -14074,11 +14383,6 @@  _initialize_remote (void)
     = register_program_space_data_with_cleanup (NULL,
 						remote_pspace_data_cleanup);
 
-  /* Initialize the per-target state.  At the moment there is only one
-     of these, not one per target.  Only one target is active at a
-     time.  */
-  remote_state = new struct remote_state ();
-
   add_target (remote_target_info, remote_target::open);
   add_target (extended_remote_target_info, extended_remote_target::open);
 
@@ -14089,7 +14393,6 @@  _initialize_remote (void)
   init_remote_threadtests ();
 #endif
 
-  stop_reply_queue = QUEUE_alloc (stop_reply_p, stop_reply_xfree);
   /* set/show remote ...  */
 
   add_prefix_cmd ("remote", class_maintenance, set_remote_cmd, _("\
diff --git a/gdb/remote.h b/gdb/remote.h
index 85721986db..82c3736f37 100644
--- a/gdb/remote.h
+++ b/gdb/remote.h
@@ -22,6 +22,7 @@ 
 #include "remote-notif.h"
 
 struct target_desc;
+struct remote_target;
 
 /* Read a packet from the remote machine, with error checking, and
    store it in *BUF.  Resize *BUF using xrealloc if necessary to hold
@@ -29,7 +30,8 @@  struct target_desc;
    rather than timing out; this is used (in synchronous mode) to wait
    for a target that is is executing user code to stop.  */
 
-extern void getpkt (char **buf, long *sizeof_buf, int forever);
+extern void getpkt (remote_target *remote,
+		    char **buf, long *sizeof_buf, int forever);
 
 /* Send a packet to the remote machine, with error checking.  The data
    of the packet is in BUF.  The string in BUF can be at most PBUFSIZ
@@ -37,7 +39,7 @@  extern void getpkt (char **buf, long *sizeof_buf, int forever);
    we are debugging (remote_debug) and want to print the sent packet
    as a string.  */
 
-extern int putpkt (const char *buf);
+extern int putpkt (remote_target *remote, const char *buf);
 
 void register_remote_g_packet_guess (struct gdbarch *gdbarch, int bytes,
 				     const struct target_desc *tdesc);
@@ -53,5 +55,6 @@  extern int remote_register_number_and_offset (struct gdbarch *gdbarch,
 					      int regnum, int *pnum,
 					      int *poffset);
 
-extern void remote_notif_get_pending_events (struct notif_client *np);
+extern void remote_notif_get_pending_events (remote_target *remote,
+					     struct notif_client *np);
 #endif