[RFC] Consolidate gdbserver global variables

Message ID 44875dda-adc6-d9a4-940c-0c27aeac574b@redhat.com
State New, archived
Headers

Commit Message

Stan Cox Jan. 31, 2018, 3:41 a.m. UTC
  > consolidating the global variables in gdbserver into one of two
 > structures: client_state and server_state.  Client_state are those items
 > that have, or potentially could have, per client values, whereas
 > server_state are those items that have a per process value, i.e. will
 > have the same value for all clients.  This patch, although large,
 > primarily moves global data into one of the two structures
This is the same patch but with one major difference.  No use is made of 
access macros; instead the actual accesses are used.  For example, 
instead of a macro
  #define current_thread    (get_client_state()->ss->current_thread_)
through which all current_thread accesses are made
instead:
    client_state *cs = get_client_state();
    ...
    cs->ss->current_thread
(Another possibility to make the patch smaller would be an additional
  struct thread_info *current_thread = cs->ss->current_thread;
  ... )
Distribution of global variables with more than 10 accesses:
program_name 11
last_ptid 11
program_args 14
remote_debug 22
non_stop 23
general_thread 23
last_status 47
own_buf 106
current_thread 248

The patch below is present in the branch:
  ssh://sourceware.org/git/archer.git::scox/gdbserver-multi-client
(it is large, sorry about that, but much of it is mechanical)
  

Comments

Pedro Alves April 23, 2018, 5:58 p.m. UTC | #1
Hi Stan,

On 01/31/2018 03:41 AM, Stan Cox wrote:
>> consolidating the global variables in gdbserver into one of two
>> structures: client_state and server_state.  Client_state are those items
>> that have, or potentially could have, per client values, whereas
>> server_state are those items that have a per process value, i.e. will
>> have the same value for all clients.  

I've tried to take another fresh look at this today.
Sorry for the delay...

I'm afraid I am still confused about the client vs server states.
Why do we need server_state, if the value is the same for
all clients?

The structures in the code itself should have leading describing
comments, explaining their relations.

+/* Description of the remote protocol state for the currently
+   connected target.  This is per-target state, and independent of the
+   selected architecture. */
+
+struct server_state
+{

What is a "connected target" in this context?

I did not see description for client_state in the code.

I think the parts about multiple client states and the fd mapping
should be split to a separate patch.  The first patch would
only move the globals to structures, and start with a single
global instance of such structures.  Uses of map/set and other
data structure changes would be another patch.  Code to support
multiple connections would likely be another patch, etc.

 +enum packet_types { other_packet, vContc, vConts, vContt, vRun, vAttach, Hg, g_or_m, vStopped };
 +typedef enum packet_types packet_types;
 +
 +enum exit_types { no_exit, have_exit, sent_exit };
 +typedef enum exit_types exit_types;

These look like things that are not used yet and thus
should be split to a separate patch.

This patch, although large,
>> primarily moves global data into one of the two structures
> This is the same patch but with one major difference.  No use is made of access macros; instead the actual accesses are used.  For example, instead of a macro
>  #define current_thread    (get_client_state()->ss->current_thread_)
> through which all current_thread accesses are made
> instead:
>    client_state *cs = get_client_state();
>    ...
>    cs->ss->current_thread

Thanks.  I like the over-avoidance of macros.

I'm not super thrilled about the long "cs->ss->" chains though.

There is _always_ a client_state, right?  I.e., get_client_state()
never returns NULL?  If so, sounds like get_client_state()
could return a reference instead of a pointer?

> (Another possibility to make the patch smaller would be an additional
>  struct thread_info *current_thread = cs->ss->current_thread;

Yeah.  Since that would just be decomposing expressions, we could
make use of "auto &&" too, like:

   auto &&current_thread = client_state ()->ss->current_thread;
   auto &&all_threads = client_state ()->ss->all_threads;

Another option would be to add some convenient wrapper functions
for the most common cases.  Like

thread_info *current_thread ()
{
  return client_state ()->ss->current_thread;
}

>  ... )
> Distribution of global variables with more than 10 accesses:
> program_name 11
> last_ptid 11
> program_args 14
> remote_debug 22
> non_stop 23
> general_thread 23
> last_status 47
> own_buf 106
> current_thread 248



> 
> The patch below is present in the branch:
>  ssh://sourceware.org/git/archer.git::scox/gdbserver-multi-client
> (it is large, sorry about that, but much of it is mechanical)
> 
> diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
> index eec0bcf3af6..382d9b3efa7 100644
> --- a/gdb/gdbserver/event-loop.c
> +++ b/gdb/gdbserver/event-loop.c
> @@ -385,6 +385,9 @@ delete_file_handler (gdb_fildes_t fd)
>      ;
>        prev_ptr->next_file = file_ptr->next_file;
>      }
> +
> +  struct multi_client_states *client_states = get_client_states();
> +  client_states->delete_client_state (fd);
>    free (file_ptr);

Formatting nit: there should be a space before "(" in 
"get_client_states()" (and all function calls).

Note the patch has clear signs of global sed'ing. :-)
E.g., obviously this is incorrect:

 @@ -628,7 +628,7 @@ Could not convert the expanded inferior cwd to wide-char."));
     process with the process list.  */
  static int
  win32_create_inferior (const char *program,
 -                      const std::vector<char *> &program_args)
 +                      const std::vector<char *> &cs->program_args)
  {
 
Here too:

 --- a/gdb/gnulib/import/error.c
 +++ b/gdb/gnulib/import/error.c
 @@ -65,7 +65,7 @@ unsigned int error_message_count;
  #ifdef _LIBC
  /* In the GNU C library, there is a predefined variable for this.  */
  
 -# define program_name program_invocation_name
 +# define cs->program_name program_invocation_name
  # include <errno.h>
  # include <limits.h>
  # include <libio/libioP.h>
 @@ -115,7 +115,7 @@ int strerror_r ();
  #  endif
  # endif
  
 -#define program_name getprogname ()
 +#define cs->program_name getprogname ()

The patch should not be changing anything under gnulib/ at all.

There may be more cases.



> +  client_state () {};

Spurious ;.  

What is initializing all the fields in the structure?
Can we use in-class initialization?

> +  client_state (gdb_fildes_t, client_state*);
> +};

This needs a comment/description.  What is this ctor for?

> 
> 
> struct multi_client_states
> {
> public:
>   std::map<gdb_fildes_t,client_state*> cs;
>   client_state *current_cs;
> 
>   client_state* get_client_state (void) { return current_cs; }
>   void set_current_client (client_state* p_cs) { current_cs = p_cs; }
> 
>   client_state * set_client_state (gdb_fildes_t);
>   void free_client_state (client_state *cs);
>   void delete_client_state (gdb_fildes_t fd);
> };

Should this structure be part of this patch?
free_client_state does not look to be defined anywhere,
for instance.

>  }
> 
> diff --git a/gdb/gdbserver/fork-child.c b/gdb/gdbserver/fork-child.c
> index 831e7e13100..74fa5e424c7 100644
> --- a/gdb/gdbserver/fork-child.c
> +++ b/gdb/gdbserver/fork-child.c
> @@ -44,6 +44,8 @@ restore_old_foreground_pgrp (void)
>  void
>  prefork_hook (const char *args)
>  {
> +  client_state *cs = get_client_state();
> +
>    if (debug_threads)
>      {
>        debug_printf ("args: %s\n", args);
> @@ -57,7 +59,7 @@ prefork_hook (const char *args)
> 
>    /* Clear this so the backend doesn't get confused, thinking
>       CONT_THREAD died, and it needs to resume all threads.  */
> -  cont_thread = null_ptid;
> +  cs->ss->cont_thread = null_ptid;
>  }
> 
>  /* See nat/fork-inferior.h.  */
> @@ -97,6 +99,7 @@ void
>  post_fork_inferior (int pid, const char *program)
>  {
>  #ifdef SIGTTOU
> +  client_state *cs = get_client_state();
>    signal (SIGTTOU, SIG_IGN);
>    signal (SIGTTIN, SIG_IGN);
>    terminal_fd = fileno (stderr);
> @@ -106,10 +109,10 @@ post_fork_inferior (int pid, const char *program)
>  #endif
> 
>    startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED,
> -            &last_status, &last_ptid);
> -  current_thread->last_resume_kind = resume_stop;
> -  current_thread->last_status = last_status;
> -  signal_pid = pid;
> +            &cs->ss->last_status, &cs->ss->last_ptid);
> +  cs->ss->current_thread->last_resume_kind = resume_stop;
> +  cs->ss->current_thread->last_status = cs->ss->last_status;
> +  cs->ss->signal_pid = pid;
>    target_post_create_inferior ();
>    fprintf (stderr, "Process %s created; pid = %d\n", program, pid);
>    fflush (stderr);
> diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
> index 9a8c72e780e..c5bd1175f22 100644
> --- a/gdb/gdbserver/gdbthread.h
> +++ b/gdb/gdbserver/gdbthread.h
> @@ -73,8 +73,6 @@ struct thread_info
>    struct btrace_target_info *btrace;
>  };
> 
> -extern std::list<thread_info *> all_threads;
> -
>  void remove_thread (struct thread_info *thread);
>  struct thread_info *add_thread (ptid_t ptid, void *target_data);
> 
> @@ -95,9 +93,9 @@ template <typename Func>
>  static thread_info *
>  find_thread (Func func)
>  {
> -  std::list<thread_info *>::iterator next, cur = all_threads.begin ();
> +  std::list<thread_info *>::iterator next, cur = get_client_state()->ss->all_threads.begin ();

Please watch out for too-long lines.  The hard limit is 80 cols.

This would be case where doing instead:

 auto &&all_threads = get_client_state()->ss->all_threads;

would avoid the formatting issues, as well as ...

> 
> -  while (cur != all_threads.end ())
> +  while (cur != get_client_state()->ss->all_threads.end ())

... all this indirection for each iteration.

>      {
>        next = cur;
>        next++;
> @@ -141,9 +139,9 @@ template <typename Func>
>  static void
>  for_each_thread (Func func)
>  {
> -  std::list<thread_info *>::iterator next, cur = all_threads.begin ();
> +  std::list<thread_info *>::iterator next, cur = get_client_state()->ss->all_threads.begin ();
> 
> -  while (cur != all_threads.end ())
> +  while (cur != get_client_state()->ss->all_threads.end ())

Ditto.  Etc.

> +int
> +get_remote_desc (void)
> +{
> +  return remote_desc;
> +}

Is "remote_desc" a global?  If so, why do we need the wrapper function?

> @@ -1474,45 +1484,45 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
>       while it figures out the address of the symbol.  */
>    while (1)
>      {
> -      if (own_buf[0] == 'm')
> +      if (cs->own_buf[0] == 'm')
>      {
>        CORE_ADDR mem_addr;
> -      unsigned char *mem_buf;
> +      unsigned char *mem_buffer;

Renames that were necessary because of the macros
conflicts can/should be reverted.



> diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
> index 5970431d8ed..8e1459f74e2 100644
> --- a/gdb/gdbserver/server.h
> +++ b/gdb/gdbserver/server.h
> @@ -60,52 +60,19 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap);
>  #include "gdb_signals.h"
>  #include "target.h"
>  #include "mem-break.h"
> -#include "gdbthread.h"
> -#include "inferiors.h"
>  #include "environ.h"
> +#include <list>
> +#include <map>
> 
>  /* Target-specific functions */
> 
>  void initialize_low ();
> 
> -/* Public variables in server.c */
> -
> -extern ptid_t cont_thread;
> -extern ptid_t general_thread;
> -
> -extern int server_waiting;
> -extern int pass_signals[];
> -extern int program_signals[];
> -extern int program_signals_p;
> -
>  extern int disable_packet_vCont;
>  extern int disable_packet_Tthread;
>  extern int disable_packet_qC;
>  extern int disable_packet_qfThreadInfo;
> 
> -extern char *own_buf;
> -
> -extern int run_once;
> -extern int multi_process;
> -extern int report_fork_events;
> -extern int report_vfork_events;
> -extern int report_exec_events;
> -extern int report_thread_events;
> -extern int non_stop;
> -
> -/* True if the "swbreak+" feature is active.  In that case, GDB wants
> -   us to report whether a trap is explained by a software breakpoint
> -   and for the server to handle PC adjustment if necessary on this
> -   target.  Only enabled if the target supports it.  */
> -extern int swbreak_feature;
> -
> -/* True if the "hwbreak+" feature is active.  In that case, GDB wants
> -   us to report whether a trap is explained by a hardware breakpoint.
> -   Only enabled if the target supports it.  */
> -extern int hwbreak_feature;
> -
> -extern int disable_randomization;
> -
>  #if USE_WIN32API
>  #include <winsock2.h>
>  typedef SOCKET gdb_fildes_t;
> @@ -158,8 +125,161 @@ extern void post_fork_inferior (int pid, const char *program);
>  /* Get the gdb_environ being used in the current session.  */
>  extern gdb_environ *get_environ ();
> 
> -extern target_waitstatus last_status;
> -extern ptid_t last_ptid;
> -extern unsigned long signal_pid;
> +// extern ptid_t cs->ss->last_ptid;
> +// extern unsigned long cs->ss->signal_pid;
> 
>  #endif /* SERVER_H */
> +
> +/* Description of the remote protocol state for the currently
> +   connected target.  This is per-target state, and independent of the
> +   selected architecture. */
> +
> +struct server_state
> +{
> +  int attach_count;

This looks like not used in this patch yet.

> +  /* From server.c */
> +  /* The thread set with an `Hc' packet.  `Hc' is deprecated in favor of
> +     `vCont'.  Note the multi-process extensions made `vCont' a
> +     requirement, so `Hc pPID.TID' is pretty much undefined.  So
> +     CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for
> +     resuming all threads of the process (again, `Hc' isn't used for
> +     multi-process), or a specific thread ptid_t.  */
> +  ptid_t cont_thread;
> +  /* The thread set with an `Hg' packet.  */
> +  ptid_t general_thread;
> +  /* The PID of the originally created or attached inferior.  Used to
> +     send signals to the process when GDB sends us an asynchronous interrupt
> +     (user hitting Control-C in the client), and to wait for the child to exit
> +     when no longer debugging it.  */
> +
> +  unsigned long signal_pid;
> +  /* Last status reported to GDB.  */
> +  struct target_waitstatus last_status;
> +  /* Was last status an exit status? (sticky if yes) */
> +  int last_status_exited;

Ditto.

> +  ptid_t last_ptid;
> +  unsigned char *mem_buf;
> +
> +  /* from remote-utils.c */
> +  /* Internal buffer used by readchar.
> +     These are global to readchar because reschedule_remote needs to be
> +     able to tell whether the buffer is empty.  */
> +  unsigned char readchar_buf[BUFSIZ];
> +  int readchar_bufcnt;
> +  unsigned char *readchar_bufp;
> +  /* from inferiors.c */
> +  std::list<process_info *> all_processes;
> +  std::list<thread_info *> all_threads;
> +
> +  struct thread_info *current_thread;
> +};

But as I asked before, do we need this structure if
there is only ever one server?

> +
> +typedef struct server_state server_state;
> +
> +
> +enum packet_types { other_packet, vContc, vConts, vContt, vRun, vAttach, Hg, g_or_m, vStopped };
> +typedef enum packet_types packet_types;
> +
> +enum exit_types { no_exit, have_exit, sent_exit };
> +typedef enum exit_types exit_types;
> +
> +
> +struct client_state
> +{
> +  gdb_fildes_t file_desc;
> +  int attached_to_client;

More things not used in this patch.  There could be
more.

> +  int packet_type;
> +  int last_packet_type;
> +  int pending;
> +  int nonstop_pending;
> +  int catch_syscalls;
> +  ptid_t last_cont_ptid;
> +  ptid_t new_general_thread;
> +
> +  /* From server.c */
> +  int server_waiting;
> +
> +  int extended_protocol;
> +  int response_needed;
> +  int exit_requested;
> +
> +  /* --once: Exit after the first connection has closed.  */
> +  int run_once;

Is this one really per client?

> +
> +  int multi_process;
> +  int report_fork_events;
> +  int report_vfork_events;
> +  int report_exec_events;
> +  int report_thread_events;
> +  /* Whether to report TARGET_WAITKING_NO_RESUMED events.  */
> +  int report_no_resumed;
> +  int non_stop;

So what will happen if one client is in non-stop mode, and another
is in all-stop mode?  There are checks for cs->non_stop in the target
backend (linux-low.c).  I suspect that will not work correctly.  In
such cases, I wonder why make the global be per-client?

> +  /* True if the "swbreak+" feature is active.  In that case, GDB wants
> +     us to report whether a trap is explained by a software breakpoint
> +     and for the server to handle PC adjustment if necessary on this
> +     target.  Only enabled if the target supports it.  */
> +  int swbreak_feature;
> +  /* True if the "hwbreak+" feature is active.  In that case, GDB wants
> +     us to report whether a trap is explained by a hardware breakpoint.
> +     Only enabled if the target supports it.  */
> +  int hwbreak_feature;
> +
> +  /* True if the "vContSupported" feature is active.  In that case, GDB
> +     wants us to report whether single step is supported in the reply to
> +     "vCont?" packet.  */
> +  int vCont_supported;
> +
> +  /* Whether we should attempt to disable the operating system's address
> +     space randomization feature before starting an inferior.  */
> +  int disable_randomization;
> +
> +  char *program_name = NULL;
> +  std::vector<char *> program_args;
> +  std::string wrapper_argv;
> +
> +  int packet_length;
> +
> +  int pass_signals[GDB_SIGNAL_LAST];
> +  int program_signals[GDB_SIGNAL_LAST];
> +  int program_signals_p;
> +
> +  char *notify_buffer;
> +  /* Renamed from own_buf to avoid macro name conflict with a common local variable name */
> +  char *own_buf;

As mentioned, such renames can be reverted.

> +
> +  /* from remote-utils.c */
> +  int remote_debug;
> +  /* If true, then GDB has requested noack mode.  */
> +  int noack_mode;
> +  /* If true, then we tell GDB to use noack mode by default.  */
> +  int transport_is_reliable;
> +
> +  server_state *ss;
> +
> +  client_state () {};
> +  client_state (gdb_fildes_t, client_state*);
> +};
> +
> +typedef struct client_state client_state;
> +

> diff --git a/gdb/nat/linux-personality.h b/gdb/nat/linux-personality.h
> index 229cc3ef1c9..3f2e0724c49 100644
> --- a/gdb/nat/linux-personality.h
> +++ b/gdb/nat/linux-personality.h
> @@ -27,7 +27,7 @@ public:
>    /* Disable the inferior's address space randomization if
>       DISABLE_RANDOMIZATION is not zero and if we have
>       <sys/personality.h>. */
> -  maybe_disable_address_space_randomization (int disable_randomization);
> +  maybe_disable_address_space_randomization (int p_disable_randomization);

This looks like a spurious change.

On your next update, please make sure to wrap the text in the
proposed commit log to 74-columns, so that it's easier to read
in "git show", "git log", etc.

Please address the comments above, squash the patches together,
rebased on current master, and repost a new self-contained
version (including updated proposed git commit log) with
"PATCH v2" in the subject line.  That should make it easier
to iterate on, and see if someone else has further
comments, too.

Thanks for the patience,
Pedro Alves
  

Patch

diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
index eec0bcf3af6..382d9b3efa7 100644
--- a/gdb/gdbserver/event-loop.c
+++ b/gdb/gdbserver/event-loop.c
@@ -385,6 +385,9 @@  delete_file_handler (gdb_fildes_t fd)
  	;
        prev_ptr->next_file = file_ptr->next_file;
      }
+
+  struct multi_client_states *client_states = get_client_states();
+  client_states->delete_client_state (fd);
    free (file_ptr);
  }

diff --git a/gdb/gdbserver/fork-child.c b/gdb/gdbserver/fork-child.c
index 831e7e13100..74fa5e424c7 100644
--- a/gdb/gdbserver/fork-child.c
+++ b/gdb/gdbserver/fork-child.c
@@ -44,6 +44,8 @@  restore_old_foreground_pgrp (void)
  void
  prefork_hook (const char *args)
  {
+  client_state *cs = get_client_state();
+
    if (debug_threads)
      {
        debug_printf ("args: %s\n", args);
@@ -57,7 +59,7 @@  prefork_hook (const char *args)

    /* Clear this so the backend doesn't get confused, thinking
       CONT_THREAD died, and it needs to resume all threads.  */
-  cont_thread = null_ptid;
+  cs->ss->cont_thread = null_ptid;
  }

  /* See nat/fork-inferior.h.  */
@@ -97,6 +99,7 @@  void
  post_fork_inferior (int pid, const char *program)
  {
  #ifdef SIGTTOU
+  client_state *cs = get_client_state();
    signal (SIGTTOU, SIG_IGN);
    signal (SIGTTIN, SIG_IGN);
    terminal_fd = fileno (stderr);
@@ -106,10 +109,10 @@  post_fork_inferior (int pid, const char *program)
  #endif

    startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED,
-		    &last_status, &last_ptid);
-  current_thread->last_resume_kind = resume_stop;
-  current_thread->last_status = last_status;
-  signal_pid = pid;
+		    &cs->ss->last_status, &cs->ss->last_ptid);
+  cs->ss->current_thread->last_resume_kind = resume_stop;
+  cs->ss->current_thread->last_status = cs->ss->last_status;
+  cs->ss->signal_pid = pid;
    target_post_create_inferior ();
    fprintf (stderr, "Process %s created; pid = %d\n", program, pid);
    fflush (stderr);
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index 9a8c72e780e..c5bd1175f22 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -73,8 +73,6 @@  struct thread_info
    struct btrace_target_info *btrace;
  };

-extern std::list<thread_info *> all_threads;
-
  void remove_thread (struct thread_info *thread);
  struct thread_info *add_thread (ptid_t ptid, void *target_data);

@@ -95,9 +93,9 @@  template <typename Func>
  static thread_info *
  find_thread (Func func)
  {
-  std::list<thread_info *>::iterator next, cur = all_threads.begin ();
+  std::list<thread_info *>::iterator next, cur = 
get_client_state()->ss->all_threads.begin ();

-  while (cur != all_threads.end ())
+  while (cur != get_client_state()->ss->all_threads.end ())
      {
        next = cur;
        next++;
@@ -141,9 +139,9 @@  template <typename Func>
  static void
  for_each_thread (Func func)
  {
-  std::list<thread_info *>::iterator next, cur = all_threads.begin ();
+  std::list<thread_info *>::iterator next, cur = 
get_client_state()->ss->all_threads.begin ();

-  while (cur != all_threads.end ())
+  while (cur != get_client_state()->ss->all_threads.end ())
      {
        next = cur;
        next++;
@@ -198,7 +196,7 @@  find_thread_in_random (Func func)
  }

  /* Get current thread ID (Linux task ID).  */
-#define current_ptid (current_thread->id)
+#define current_ptid (get_client_state()->ss->current_thread->id)

  /* Get the ptid of THREAD.  */

diff --git a/gdb/gdbserver/hostio.c b/gdb/gdbserver/hostio.c
index d2b5a71bade..4e388a85dc8 100644
--- a/gdb/gdbserver/hostio.c
+++ b/gdb/gdbserver/hostio.c
@@ -29,8 +29,6 @@ 
  #include <sys/stat.h>
  #include "fileio.h"

-extern int remote_debug;
-
  struct fd_list
  {
    int fd;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 600bf201bff..c63f2026d08 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -22,10 +22,6 @@ 
  #include "gdbthread.h"
  #include "dll.h"

-std::list<process_info *> all_processes;
-std::list<thread_info *> all_threads;
-
-struct thread_info *current_thread;

  /* The current working directory used to start the inferior.  */
  static const char *current_inferior_cwd = NULL;
@@ -33,16 +29,17 @@  static const char *current_inferior_cwd = NULL;
  struct thread_info *
  add_thread (ptid_t thread_id, void *target_data)
  {
+  client_state *cs = get_client_state();
    struct thread_info *new_thread = XCNEW (struct thread_info);

    new_thread->id = thread_id;
    new_thread->last_resume_kind = resume_continue;
    new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;

-  all_threads.push_back (new_thread);
+  cs->ss->all_threads.push_back (new_thread);

-  if (current_thread == NULL)
-    current_thread = new_thread;
+  if (cs->ss->current_thread == NULL)
+    cs->ss->current_thread = new_thread;

    new_thread->target_data = target_data;

@@ -54,8 +51,10 @@  add_thread (ptid_t thread_id, void *target_data)
  struct thread_info *
  get_first_thread (void)
  {
-  if (!all_threads.empty ())
-    return all_threads.front ();
+  client_state *cs = get_client_state();
+
+  if (!cs->ss->all_threads.empty ())
+    return cs->ss->all_threads.front ();
    else
      return NULL;
  }
@@ -97,14 +96,16 @@  free_one_thread (thread_info *thread)
  void
  remove_thread (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
+
    if (thread->btrace != NULL)
      target_disable_btrace (thread->btrace);

    discard_queued_stop_replies (ptid_of (thread));
-  all_threads.remove (thread);
+  cs->ss->all_threads.remove (thread);
    free_one_thread (thread);
-  if (current_thread == thread)
-    current_thread = NULL;
+  if (cs->ss->current_thread == thread)
+    cs->ss->current_thread = NULL;
  }

  void *
@@ -128,20 +129,24 @@  set_thread_regcache_data (struct thread_info 
*thread, struct regcache *data)
  void
  clear_inferiors (void)
  {
+  client_state *cs = get_client_state();
+
    for_each_thread (free_one_thread);
-  all_threads.clear ();
+  cs->ss->all_threads.clear ();

    clear_dlls ();

-  current_thread = NULL;
+  cs->ss->current_thread = NULL;
  }

  struct process_info *
  add_process (int pid, int attached)
  {
+  client_state *cs = get_client_state();
+
    process_info *process = new process_info (pid, attached);

-  all_processes.push_back (process);
+  cs->ss->all_processes.push_back (process);

    return process;
  }
@@ -153,10 +158,12 @@  add_process (int pid, int attached)
  void
  remove_process (struct process_info *process)
  {
+  client_state *cs = get_client_state();
+
    clear_symbol_cache (&process->symbol_cache);
    free_all_breakpoints (process);
    gdb_assert (find_thread_process (process) == NULL);
-  all_processes.remove (process);
+  cs->ss->all_processes.remove (process);
    delete process;
  }

@@ -173,8 +180,10 @@  find_process_pid (int pid)
  process_info *
  get_first_process (void)
  {
-  if (!all_processes.empty ())
-    return all_processes.front ();
+  client_state *cs = get_client_state();
+
+  if (!cs->ss->all_processes.empty ())
+    return cs->ss->all_processes.front ();
    else
      return NULL;
  }
@@ -209,20 +218,26 @@  get_thread_process (const struct thread_info *thread)
  struct process_info *
  current_process (void)
  {
-  gdb_assert (current_thread != NULL);
-  return get_thread_process (current_thread);
+  client_state *cs = get_client_state();
+
+  gdb_assert (cs->ss->current_thread != NULL);
+  return get_thread_process (cs->ss->current_thread);
  }

  static void
  do_restore_current_thread_cleanup (void *arg)
  {
-  current_thread = (struct thread_info *) arg;
+  client_state *cs = get_client_state();
+
+  cs->ss->current_thread = (struct thread_info *) arg;
  }

  struct cleanup *
  make_cleanup_restore_current_thread (void)
  {
-  return make_cleanup (do_restore_current_thread_cleanup, current_thread);
+  client_state *cs = get_client_state();
+
+  return make_cleanup (do_restore_current_thread_cleanup, 
cs->ss->current_thread);
  }

  /* See common/common-gdbthread.h.  */
@@ -230,8 +245,10 @@  make_cleanup_restore_current_thread (void)
  void
  switch_to_thread (ptid_t ptid)
  {
+  client_state *cs = get_client_state();
+
    gdb_assert (ptid != minus_one_ptid);
-  current_thread = find_thread_ptid (ptid);
+  cs->ss->current_thread = find_thread_ptid (ptid);
  }

  /* See common/common-inferior.h.  */
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index ccd42df9da4..7f149f53a48 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -85,17 +85,15 @@  pid_of (const process_info *proc)
  struct process_info *current_process (void);
  struct process_info *get_thread_process (const struct thread_info *);

-extern std::list<process_info *> all_processes;
-
  /* Invoke FUNC for each process.  */

  template <typename Func>
  static void
  for_each_process (Func func)
  {
-  std::list<process_info *>::iterator next, cur = all_processes.begin ();
+  std::list<process_info *>::iterator next, cur = 
get_client_state()->ss->all_processes.begin ();

-  while (cur != all_processes.end ())
+  while (cur != get_client_state()->ss->all_processes.end ())
      {
        next = cur;
        next++;
@@ -111,9 +109,9 @@  template <typename Func>
  static process_info *
  find_process (Func func)
  {
-  std::list<process_info *>::iterator next, cur = all_processes.begin ();
+  std::list<process_info *>::iterator next, cur = 
get_client_state()->ss->all_processes.begin ();

-  while (cur != all_processes.end ())
+  while (cur != get_client_state()->ss->all_processes.end ())
      {
        next = cur;
        next++;
@@ -127,8 +125,6 @@  find_process (Func func)
    return NULL;
  }

-extern struct thread_info *current_thread;
-
  /* Return the first process in the processes list.  */
  struct process_info *get_first_process (void);

diff --git a/gdb/gdbserver/linux-aarch32-low.c 
b/gdb/gdbserver/linux-aarch32-low.c
index 12c11a4252b..85b2d0d63b4 100644
--- a/gdb/gdbserver/linux-aarch32-low.c
+++ b/gdb/gdbserver/linux-aarch32-low.c
@@ -171,7 +171,7 @@  struct regs_info regs_info_aarch32 =
  int
  arm_is_thumb_mode (void)
  {
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 1);
    unsigned long cpsr;

    collect_register_by_name (regcache, "cpsr", &cpsr);
diff --git a/gdb/gdbserver/linux-aarch64-low.c 
b/gdb/gdbserver/linux-aarch64-low.c
index eccac4da138..b382f4e97d1 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -67,7 +67,7 @@  struct arch_process_info
  static int
  is_64bit_tdesc (void)
  {
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);

    return register_size (regcache->tdesc, 0) == 8;
  }
@@ -253,7 +253,7 @@  aarch64_insert_point (enum raw_bkpt_type type, 
CORE_ADDR addr,
    int ret;
    enum target_hw_bp_type targ_type;
    struct aarch64_debug_reg_state *state
-    = aarch64_get_debug_reg_state (pid_of (current_thread));
+    = aarch64_get_debug_reg_state (pid_of (cs->ss->current_thread));

    if (show_debug_regs)
      fprintf (stderr, "insert_point on entry (addr=0x%08lx, len=%d)\n",
@@ -302,7 +302,7 @@  aarch64_remove_point (enum raw_bkpt_type type, 
CORE_ADDR addr,
    int ret;
    enum target_hw_bp_type targ_type;
    struct aarch64_debug_reg_state *state
-    = aarch64_get_debug_reg_state (pid_of (current_thread));
+    = aarch64_get_debug_reg_state (pid_of (cs->ss->current_thread));

    if (show_debug_regs)
      fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
@@ -345,7 +345,7 @@  aarch64_stopped_data_address (void)
    int pid, i;
    struct aarch64_debug_reg_state *state;

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);

    /* Get the siginfo.  */
    if (ptrace (PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0)
@@ -357,7 +357,7 @@  aarch64_stopped_data_address (void)
      return (CORE_ADDR) 0;

    /* Check if the address matches any watched address.  */
-  state = aarch64_get_debug_reg_state (pid_of (current_thread));
+  state = aarch64_get_debug_reg_state (pid_of (cs->ss->current_thread));
    for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
      {
        const unsigned int len = aarch64_watchpoint_length 
(state->dr_ctrl_wp[i]);
@@ -473,7 +473,7 @@  aarch64_arch_setup (void)
    int is_elf64;
    int tid;

-  tid = lwpid_of (current_thread);
+  tid = lwpid_of (cs->ss->current_thread);

    is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);

@@ -482,7 +482,7 @@  aarch64_arch_setup (void)
    else
      current_process ()->tdesc = tdesc_arm_with_neon;

-  aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread));
+  aarch64_linux_get_debug_reg_capacity (lwpid_of (cs->ss->current_thread));
  }

  static struct regset_info aarch64_regsets[] =
@@ -527,7 +527,7 @@  aarch64_regs_info (void)
  static int
  aarch64_supports_tracepoints (void)
  {
-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      return 1;
    else
      {
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index 6c2dcead03d..2bf687b773b 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -528,7 +528,7 @@  arm_insert_point (enum raw_bkpt_type type, CORE_ADDR 
addr,
  	pts[i] = p;

  	/* Only update the threads of the current process.  */
-	for_each_thread (current_thread->id.pid (), [&] (thread_info *thread)
+	for_each_thread (cs->ss->current_thread->id.pid (), [&] (thread_info 
*thread)
  	  {
  	    update_registers_callback (thread, watch, i);
  	  });
@@ -573,7 +573,7 @@  arm_remove_point (enum raw_bkpt_type type, CORE_ADDR 
addr,
  	pts[i].control = arm_hwbp_control_disable (pts[i].control);

  	/* Only update the threads of the current process.  */
-	for_each_thread (current_thread->id.pid (), [&] (thread_info *thread)
+	for_each_thread (cs->ss->current_thread->id.pid (), [&] (thread_info 
*thread)
  	  {
  	    update_registers_callback (thread, watch, i);
  	  });
@@ -589,7 +589,7 @@  arm_remove_point (enum raw_bkpt_type type, CORE_ADDR 
addr,
  static int
  arm_stopped_by_watchpoint (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);
    siginfo_t siginfo;

    /* We must be able to set hardware watchpoints.  */
@@ -598,7 +598,7 @@  arm_stopped_by_watchpoint (void)

    /* Retrieve siginfo.  */
    errno = 0;
-  ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread), 0, &siginfo);
+  ptrace (PTRACE_GETSIGINFO, lwpid_of (cs->ss->current_thread), 0, 
&siginfo);
    if (errno != 0)
      return 0;

@@ -624,7 +624,7 @@  arm_stopped_by_watchpoint (void)
  static CORE_ADDR
  arm_stopped_data_address (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);
    return lwp->arch_private->stopped_data_address;
  }

@@ -872,7 +872,7 @@  arm_get_hwcap (unsigned long *valp)
  static const struct target_desc *
  arm_read_description (void)
  {
-  int pid = lwpid_of (current_thread);
+  int pid = lwpid_of (cs->ss->current_thread);
    unsigned long arm_hwcap = 0;

    /* Query hardware watchpoint/breakpoint capabilities.  */
@@ -919,7 +919,7 @@  arm_read_description (void)
  static void
  arm_arch_setup (void)
  {
-  int tid = lwpid_of (current_thread);
+  int tid = lwpid_of (cs->ss->current_thread);
    int gpregs[18];
    struct iovec iov;

diff --git a/gdb/gdbserver/linux-crisv32-low.c 
b/gdb/gdbserver/linux-crisv32-low.c
index 6eb82175bce..415826072fc 100644
--- a/gdb/gdbserver/linux-crisv32-low.c
+++ b/gdb/gdbserver/linux-crisv32-low.c
@@ -139,7 +139,7 @@  cris_insert_point (enum raw_bkpt_type type, 
CORE_ADDR addr,
    unsigned long ccs;
    struct regcache *regcache;

-  regcache = get_thread_regcache (current_thread, 1);
+  regcache = get_thread_regcache (cs->ss->current_thread, 1);

    /* Read watchpoints are set as access watchpoints, because of GDB's
       inability to deal with pure read watchpoints.  */
@@ -212,7 +212,7 @@  cris_remove_point (enum raw_bkpt_type type, 
CORE_ADDR addr, int len,
    struct regcache *regcache;
    unsigned long bp_d_regs[12];

-  regcache = get_thread_regcache (current_thread, 1);
+  regcache = get_thread_regcache (cs->ss->current_thread, 1);

    /* Read watchpoints are set as access watchpoints, because of GDB's
       inability to deal with pure read watchpoints.  */
@@ -289,7 +289,7 @@  static int
  cris_stopped_by_watchpoint (void)
  {
    unsigned long exs;
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 1);

    collect_register_by_name (regcache, "exs", &exs);

@@ -300,7 +300,7 @@  static CORE_ADDR
  cris_stopped_data_address (void)
  {
    unsigned long eda;
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 1);

    collect_register_by_name (regcache, "eda", &eda);

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 38142bba03d..3359ce7136f 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -455,14 +455,15 @@  linux_arch_setup (void)
  static void
  linux_arch_setup_thread (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct thread_info *saved_thread;

-  saved_thread = current_thread;
-  current_thread = thread;
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = thread;

    linux_arch_setup ();

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
  }

  /* Handle a GNU/Linux extended wait response.  If we see a clone,
@@ -474,6 +475,7 @@  linux_arch_setup_thread (struct thread_info *thread)
  static int
  handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
  {
+  client_state *cs = get_client_state();
    struct lwp_info *event_lwp = *orig_event_lwp;
    int event = linux_ptrace_get_extended_event (wstat);
    struct thread_info *event_thr = get_lwp_thread (event_lwp);
@@ -654,7 +656,7 @@  handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
  	  new_lwp->status_pending_p = 1;
  	  new_lwp->status_pending = status;
  	}
-      else if (report_thread_events)
+      else if (cs->report_thread_events)
  	{
  	  new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
  	  new_lwp->status_pending_p = 1;
@@ -682,7 +684,7 @@  handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
        /* Report the event.  */
        return 0;
      }
-  else if (event == PTRACE_EVENT_EXEC && report_exec_events)
+  else if (event == PTRACE_EVENT_EXEC && cs->report_exec_events)
      {
        struct process_info *proc;
        std::vector<int> syscalls_to_catch;
@@ -705,13 +707,13 @@  handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)

        /* Delete the execing process and all its threads.  */
        linux_mourn (proc);
-      current_thread = NULL;
+      cs->ss->current_thread = NULL;

        /* Create a new process/lwp/thread.  */
        proc = linux_add_process (event_pid, 0);
        event_lwp = add_lwp (event_ptid);
        event_thr = get_lwp_thread (event_lwp);
-      gdb_assert (current_thread == event_thr);
+      gdb_assert (cs->ss->current_thread == event_thr);
        linux_arch_setup_thread (event_thr);

        /* Set the event status.  */
@@ -748,6 +750,7 @@  handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
  static CORE_ADDR
  get_pc (struct lwp_info *lwp)
  {
+  client_state *cs = get_client_state();
    struct thread_info *saved_thread;
    struct regcache *regcache;
    CORE_ADDR pc;
@@ -755,16 +758,16 @@  get_pc (struct lwp_info *lwp)
    if (the_low_target.get_pc == NULL)
      return 0;

-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = get_lwp_thread (lwp);

-  regcache = get_thread_regcache (current_thread, 1);
+  regcache = get_thread_regcache (cs->ss->current_thread, 1);
    pc = (*the_low_target.get_pc) (regcache);

    if (debug_threads)
      debug_printf ("pc is 0x%lx\n", (long) pc);

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
    return pc;
  }

@@ -774,6 +777,7 @@  get_pc (struct lwp_info *lwp)
  static void
  get_syscall_trapinfo (struct lwp_info *lwp, int *sysno)
  {
+  client_state *cs = get_client_state();
    struct thread_info *saved_thread;
    struct regcache *regcache;

@@ -785,16 +789,16 @@  get_syscall_trapinfo (struct lwp_info *lwp, int 
*sysno)
        return;
      }

-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = get_lwp_thread (lwp);

-  regcache = get_thread_regcache (current_thread, 1);
+  regcache = get_thread_regcache (cs->ss->current_thread, 1);
    (*the_low_target.get_syscall_trapinfo) (regcache, sysno);

    if (debug_threads)
      debug_printf ("get_syscall_trapinfo sysno %d\n", *sysno);

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
  }

  static int check_stopped_by_watchpoint (struct lwp_info *child);
@@ -808,6 +812,7 @@  static int check_stopped_by_watchpoint (struct 
lwp_info *child);
  static int
  save_stop_reason (struct lwp_info *lwp)
  {
+  client_state *cs = get_client_state();
    CORE_ADDR pc;
    CORE_ADDR sw_breakpoint_pc;
    struct thread_info *saved_thread;
@@ -822,11 +827,11 @@  save_stop_reason (struct lwp_info *lwp)
    sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break;

    /* breakpoint_at reads from the current thread.  */
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = get_lwp_thread (lwp);

  #if USE_SIGTRAP_SIGINFO
-  if (ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
+  if (ptrace (PTRACE_GETSIGINFO, lwpid_of (cs->ss->current_thread),
  	      (PTRACE_TYPE_ARG3) 0, &siginfo) == 0)
      {
        if (siginfo.si_signo == SIGTRAP)
@@ -897,7 +902,7 @@  save_stop_reason (struct lwp_info *lwp)
        if (pc != sw_breakpoint_pc)
  	{
  	  struct regcache *regcache
-	    = get_thread_regcache (current_thread, 1);
+	    = get_thread_regcache (cs->ss->current_thread, 1);
  	  (*the_low_target.set_pc) (regcache, sw_breakpoint_pc);
  	}

@@ -936,7 +941,7 @@  save_stop_reason (struct lwp_info *lwp)
      }

    lwp->stop_pc = pc;
-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
    return 1;
  }

@@ -997,13 +1002,14 @@  static int
  linux_create_inferior (const char *program,
  		       const std::vector<char *> &program_args)
  {
+  client_state *cs = get_client_state();
    struct lwp_info *new_lwp;
    int pid;
    ptid_t ptid;

    {
      maybe_disable_address_space_randomization restore_personality
-      (disable_randomization);
+      (cs->disable_randomization);
      std::string str_program_args = stringify_argv (program_args);

      pid = fork_inferior (program,
@@ -1028,7 +1034,8 @@  linux_create_inferior (const char *program,
  static void
  linux_post_create_inferior (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  client_state *cs = get_client_state();
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);

    linux_arch_setup ();

@@ -1037,7 +1044,7 @@  linux_post_create_inferior (void)
        struct process_info *proc = current_process ();
        int options = linux_low_ptrace_options (proc->attached);

-      linux_enable_event_reporting (lwpid_of (current_thread), options);
+      linux_enable_event_reporting (lwpid_of (cs->ss->current_thread), 
options);
        lwp->must_set_ptrace_flags = 0;
      }
  }
@@ -1180,6 +1187,7 @@  static void async_file_mark (void);
  static int
  linux_attach (unsigned long pid)
  {
+  client_state *cs = get_client_state();
    struct process_info *proc;
    struct thread_info *initial_thread;
    ptid_t ptid = ptid_build (pid, pid, 0);
@@ -1219,7 +1227,7 @@  linux_attach (unsigned long pid)
       the thread group reports its initial PTRACE_ATTACH SIGSTOP.  Do
       that now, otherwise, if GDB is fast enough, it could read the
       target description _before_ that initial stop.  */
-  if (non_stop)
+  if (cs->non_stop)
      {
        struct lwp_info *lwp;
        int wstat, lwpid;
@@ -1428,6 +1436,7 @@  linux_kill (int pid)
  static int
  get_detach_signal (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    enum gdb_signal signo = GDB_SIGNAL_0;
    int status;
    struct lwp_info *lp = get_thread_lwp (thread);
@@ -1468,7 +1477,7 @@  get_detach_signal (struct thread_info *thread)

    signo = gdb_signal_from_host (WSTOPSIG (status));

-  if (program_signals_p && !program_signals[signo])
+  if (cs->program_signals_p && !cs->program_signals[signo])
      {
        if (debug_threads)
  	debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
@@ -1476,7 +1485,7 @@  get_detach_signal (struct thread_info *thread)
  		      gdb_signal_to_string (signo));
        return 0;
      }
-  else if (!program_signals_p
+  else if (!cs->program_signals_p
  	   /* If we have no way to know which signals GDB does not
  	      want to have passed to the program, assume
  	      SIGTRAP/SIGINT, which is GDB's default.  */
@@ -1709,6 +1718,7 @@  linux_thread_alive (ptid_t ptid)
  static int
  thread_still_has_status_pending_p (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct lwp_info *lp = get_thread_lwp (thread);

    if (!lp->status_pending_p)
@@ -1726,8 +1736,8 @@  thread_still_has_status_pending_p (struct 
thread_info *thread)

        pc = get_pc (lp);

-      saved_thread = current_thread;
-      current_thread = thread;
+      saved_thread = cs->ss->current_thread;
+      cs->ss->current_thread = thread;

        if (pc != lp->stop_pc)
  	{
@@ -1756,7 +1766,7 @@  thread_still_has_status_pending_p (struct 
thread_info *thread)
  	}
  #endif

-      current_thread = saved_thread;
+      cs->ss->current_thread = saved_thread;

        if (discard)
  	{
@@ -2054,10 +2064,11 @@  linux_fast_tracepoint_collecting (struct 
lwp_info *lwp,
  static int
  maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
  {
+  client_state *cs = get_client_state();
    struct thread_info *saved_thread;

-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = get_lwp_thread (lwp);

    if ((wstat == NULL
         || (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
@@ -2069,7 +2080,7 @@  maybe_move_out_of_jump_pad (struct lwp_info *lwp, 
int *wstat)
        if (debug_threads)
  	debug_printf ("Checking whether LWP %ld needs to move out of the "
  		      "jump pad.\n",
-		      lwpid_of (current_thread));
+		      lwpid_of (cs->ss->current_thread));

        fast_tpoint_collect_result r
  	= linux_fast_tracepoint_collecting (lwp, &status);
@@ -2097,8 +2108,8 @@  maybe_move_out_of_jump_pad (struct lwp_info *lwp, 
int *wstat)
  	      if (debug_threads)
  		debug_printf ("Checking whether LWP %ld needs to move out of "
  			      "the jump pad...it does\n",
-			      lwpid_of (current_thread));
-	      current_thread = saved_thread;
+			      lwpid_of (cs->ss->current_thread));
+	      cs->ss->current_thread = saved_thread;

  	      return 1;
  	    }
@@ -2128,18 +2139,18 @@  maybe_move_out_of_jump_pad (struct lwp_info 
*lwp, int *wstat)
  		   || WSTOPSIG (*wstat) == SIGFPE
  		   || WSTOPSIG (*wstat) == SIGBUS
  		   || WSTOPSIG (*wstat) == SIGSEGV)
-		  && ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
+		  && ptrace (PTRACE_GETSIGINFO, lwpid_of (cs->ss->current_thread),
  			     (PTRACE_TYPE_ARG3) 0, &info) == 0
  		  /* Final check just to make sure we don't clobber
  		     the siginfo of non-kernel-sent signals.  */
  		  && (uintptr_t) info.si_addr == lwp->stop_pc)
  		{
  		  info.si_addr = (void *) (uintptr_t) status.tpoint_addr;
-		  ptrace (PTRACE_SETSIGINFO, lwpid_of (current_thread),
+		  ptrace (PTRACE_SETSIGINFO, lwpid_of (cs->ss->current_thread),
  			  (PTRACE_TYPE_ARG3) 0, &info);
  		}

-	      regcache = get_thread_regcache (current_thread, 1);
+	      regcache = get_thread_regcache (cs->ss->current_thread, 1);
  	      (*the_low_target.set_pc) (regcache, status.tpoint_addr);
  	      lwp->stop_pc = status.tpoint_addr;

@@ -2169,9 +2180,9 @@  maybe_move_out_of_jump_pad (struct lwp_info *lwp, 
int *wstat)
    if (debug_threads)
      debug_printf ("Checking whether LWP %ld needs to move out of the "
  		  "jump pad...no\n",
-		  lwpid_of (current_thread));
+		  lwpid_of (cs->ss->current_thread));

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
    return 0;
  }

@@ -2298,12 +2309,14 @@  dequeue_one_deferred_signal (struct lwp_info 
*lwp, int *wstat)
  static int
  check_stopped_by_watchpoint (struct lwp_info *child)
  {
+  client_state *cs = get_client_state();
+
    if (the_low_target.stopped_by_watchpoint != NULL)
      {
        struct thread_info *saved_thread;

-      saved_thread = current_thread;
-      current_thread = get_lwp_thread (child);
+      saved_thread = cs->ss->current_thread;
+      cs->ss->current_thread = get_lwp_thread (child);

        if (the_low_target.stopped_by_watchpoint ())
  	{
@@ -2316,7 +2329,7 @@  check_stopped_by_watchpoint (struct lwp_info *child)
  	    child->stopped_data_address = 0;
  	}

-      current_thread = saved_thread;
+      cs->ss->current_thread = saved_thread;
      }

    return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
@@ -2327,18 +2340,19 @@  check_stopped_by_watchpoint (struct lwp_info *child)
  static int
  linux_low_ptrace_options (int attached)
  {
+  client_state *cs = get_client_state();
    int options = 0;

    if (!attached)
      options |= PTRACE_O_EXITKILL;

-  if (report_fork_events)
+  if (cs->report_fork_events)
      options |= PTRACE_O_TRACEFORK;

-  if (report_vfork_events)
+  if (cs->report_vfork_events)
      options |= (PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE);

-  if (report_exec_events)
+  if (cs->report_exec_events)
      options |= PTRACE_O_TRACEEXEC;

    options |= PTRACE_O_TRACESYSGOOD;
@@ -2353,6 +2367,7 @@  linux_low_ptrace_options (int attached)
  static struct lwp_info *
  linux_low_filter_event (int lwpid, int wstat)
  {
+  client_state *cs = get_client_state();
    struct lwp_info *child;
    struct thread_info *thread;
    int have_stop_pc = 0;
@@ -2388,7 +2403,7 @@  linux_low_filter_event (int lwpid, int wstat)
        child_ptid = ptid_build (lwpid, lwpid, 0);
        child = add_lwp (child_ptid);
        child->stopped = 1;
-      current_thread = child->thread;
+      cs->ss->current_thread = child->thread;
      }

    /* If we didn't find a process, one of two things presumably happened:
@@ -2424,7 +2439,7 @@  linux_low_filter_event (int lwpid, int wstat)
        /* If there is at least one more LWP, then the exit signal was
  	 not the end of the debugged application and should be
  	 ignored, unless GDB wants to hear about thread exits.  */
-      if (report_thread_events
+      if (cs->report_thread_events
  	  || last_thread_of_process_p (pid_of (thread)))
  	{
  	  /* Since events are serialized to GDB core, and we can't
@@ -2616,6 +2631,7 @@  static int
  linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
  			       int *wstatp, int options)
  {
+  client_state *cs = get_client_state();
    struct thread_info *event_thread;
    struct lwp_info *event_child, *requested_child;
    sigset_t block_mask, prev_mask;
@@ -2680,7 +2696,7 @@  linux_wait_for_event_filtered (ptid_t wait_ptid, 
ptid_t filter_ptid,
        *wstatp = event_child->status_pending;
        event_child->status_pending_p = 0;
        event_child->status_pending = 0;
-      current_thread = event_thread;
+      cs->ss->current_thread = event_thread;
        return lwpid_of (event_thread);
      }

@@ -2805,7 +2821,7 @@  linux_wait_for_event_filtered (ptid_t wait_ptid, 
ptid_t filter_ptid,

    sigprocmask (SIG_SETMASK, &prev_mask, NULL);

-  current_thread = event_thread;
+  cs->ss->current_thread = event_thread;

    return lwpid_of (event_thread);
  }
@@ -2829,6 +2845,7 @@  linux_wait_for_event (ptid_t ptid, int *wstatp, 
int options)
  static void
  select_event_lwp (struct lwp_info **orig_lp)
  {
+  client_state *cs = get_client_state();
    int random_selector;
    struct thread_info *event_thread = NULL;

@@ -2840,7 +2857,7 @@  select_event_lwp (struct lwp_info **orig_lp)
       report the pending SIGTRAP, and the core, not having stepped the
       thread, wouldn't understand what the trap was for, and therefore
       would report it to the user as a random signal.  */
-  if (!non_stop)
+  if (!cs->non_stop)
      {
        event_thread = find_thread ([] (thread_info *thread)
  	{
@@ -2963,6 +2980,8 @@  static ptid_t linux_wait_1 (ptid_t ptid,
  static void
  linux_stabilize_threads (void)
  {
+  client_state *cs = get_client_state();
+
    thread_info *thread_stuck = find_thread (stuck_in_jump_pad_callback);

    if (thread_stuck != NULL)
@@ -2973,7 +2992,7 @@  linux_stabilize_threads (void)
        return;
      }

-  thread_info *saved_thread = current_thread;
+  thread_info *saved_thread = cs->ss->current_thread;

    stabilizing_threads = 1;

@@ -2994,13 +3013,13 @@  linux_stabilize_threads (void)

        if (ourstatus.kind == TARGET_WAITKIND_STOPPED)
  	{
-	  lwp = get_thread_lwp (current_thread);
+	  lwp = get_thread_lwp (cs->ss->current_thread);

  	  /* Lock it.  */
  	  lwp_suspended_inc (lwp);

  	  if (ourstatus.value.sig != GDB_SIGNAL_0
-	      || current_thread->last_resume_kind == resume_stop)
+	      || cs->ss->current_thread->last_resume_kind == resume_stop)
  	    {
  	      wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.value.sig));
  	      enqueue_one_deferred_signal (lwp, &wstat);
@@ -3012,7 +3031,7 @@  linux_stabilize_threads (void)

    stabilizing_threads = 0;

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;

    if (debug_threads)
      {
@@ -3048,12 +3067,13 @@  static ptid_t
  filter_exit_event (struct lwp_info *event_child,
  		   struct target_waitstatus *ourstatus)
  {
+  client_state *cs = get_client_state();
    struct thread_info *thread = get_lwp_thread (event_child);
    ptid_t ptid = ptid_of (thread);

    if (!last_thread_of_process_p (pid_of (thread)))
      {
-      if (report_thread_events)
+      if (cs->report_thread_events)
  	ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
        else
  	ourstatus->kind = TARGET_WAITKIND_IGNORE;
@@ -3105,6 +3125,7 @@  static ptid_t
  linux_wait_1 (ptid_t ptid,
  	      struct target_waitstatus *ourstatus, int target_options)
  {
+  client_state *cs = get_client_state();
    int w;
    struct lwp_info *event_child;
    int options;
@@ -3188,7 +3209,7 @@  linux_wait_1 (ptid_t ptid,
        return null_ptid;
      }

-  event_child = get_thread_lwp (current_thread);
+  event_child = get_thread_lwp (cs->ss->current_thread);

    /* linux_wait_for_event only returns an exit status for the last
       child of a process.  Report it.  */
@@ -3203,7 +3224,7 @@  linux_wait_1 (ptid_t ptid,
  	    {
  	      debug_printf ("linux_wait_1 ret = %s, exited with "
  			    "retcode %d\n",
-			    target_pid_to_str (ptid_of (current_thread)),
+			    target_pid_to_str (ptid_of (cs->ss->current_thread)),
  			    WEXITSTATUS (w));
  	      debug_exit ();
  	    }
@@ -3217,7 +3238,7 @@  linux_wait_1 (ptid_t ptid,
  	    {
  	      debug_printf ("linux_wait_1 ret = %s, terminated with "
  			    "signal %d\n",
-			    target_pid_to_str (ptid_of (current_thread)),
+			    target_pid_to_str (ptid_of (cs->ss->current_thread)),
  			    WTERMSIG (w));
  	      debug_exit ();
  	    }
@@ -3226,7 +3247,7 @@  linux_wait_1 (ptid_t ptid,
        if (ourstatus->kind == TARGET_WAITKIND_EXITED)
  	return filter_exit_event (event_child, ourstatus);

-      return ptid_of (current_thread);
+      return ptid_of (cs->ss->current_thread);
      }

    /* If step-over executes a breakpoint instruction, in the case of a
@@ -3256,13 +3277,13 @@  linux_wait_1 (ptid_t ptid,
        if (debug_threads)
  	{
  	  debug_printf ("step-over for %s executed software breakpoint\n",
-			target_pid_to_str (ptid_of (current_thread)));
+			target_pid_to_str (ptid_of (cs->ss->current_thread)));
  	}

        if (increment_pc != 0)
  	{
  	  struct regcache *regcache
-	    = get_thread_regcache (current_thread, 1);
+	    = get_thread_regcache (cs->ss->current_thread, 1);

  	  event_child->stop_pc += increment_pc;
  	  (*the_low_target.set_pc) (regcache, event_child->stop_pc);
@@ -3337,17 +3358,17 @@  linux_wait_1 (ptid_t ptid,
        if (debug_threads)
  	debug_printf ("Got signal %d for LWP %ld.  Check if we need "
  		      "to defer or adjust it.\n",
-		      WSTOPSIG (w), lwpid_of (current_thread));
+		      WSTOPSIG (w), lwpid_of (cs->ss->current_thread));

        /* Allow debugging the jump pad itself.  */
-      if (current_thread->last_resume_kind != resume_step
+      if (cs->ss->current_thread->last_resume_kind != resume_step
  	  && maybe_move_out_of_jump_pad (event_child, &w))
  	{
  	  enqueue_one_deferred_signal (event_child, &w);

  	  if (debug_threads)
  	    debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
-			  WSTOPSIG (w), lwpid_of (current_thread));
+			  WSTOPSIG (w), lwpid_of (cs->ss->current_thread));

  	  linux_resume_one_lwp (event_child, 0, 0, NULL);

@@ -3363,7 +3384,7 @@  linux_wait_1 (ptid_t ptid,
        if (debug_threads)
  	debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
  		      "Check if we're already there.\n",
-		      lwpid_of (current_thread),
+		      lwpid_of (cs->ss->current_thread),
  		      (int) event_child->collecting_fast_tracepoint);

        trace_event = 1;
@@ -3426,11 +3447,11 @@  linux_wait_1 (ptid_t ptid,
  		    {
  		      debug_printf ("linux_wait_1 ret = %s, stopped "
  				    "while stabilizing threads\n",
-				    target_pid_to_str (ptid_of (current_thread)));
+				    target_pid_to_str (ptid_of (cs->ss->current_thread)));
  		      debug_exit ();
  		    }

-		  return ptid_of (current_thread);
+		  return ptid_of (cs->ss->current_thread);
  		}
  	    }
  	}
@@ -3446,7 +3467,7 @@  linux_wait_1 (ptid_t ptid,
        if (debug_threads)
  	{
  	  debug_printf ("Ignored syscall for LWP %ld.\n",
-			lwpid_of (current_thread));
+			lwpid_of (cs->ss->current_thread));
  	}

        linux_resume_one_lwp (event_child, event_child->stepping,
@@ -3466,7 +3487,7 @@  linux_wait_1 (ptid_t ptid,
       handler. Also never ignore signals that could be caused by a
       breakpoint.  */
    if (WIFSTOPPED (w)
-      && current_thread->last_resume_kind != resume_step
+      && cs->ss->current_thread->last_resume_kind != resume_step
        && (
  #if defined (USE_THREAD_DB) && !defined (__ANDROID__)
  	  (current_process ()->priv->thread_db != NULL
@@ -3474,18 +3495,18 @@  linux_wait_1 (ptid_t ptid,
  	       || WSTOPSIG (w) == __SIGRTMIN + 1))
  	  ||
  #endif
-	  (pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
+	  (cs->pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
  	   && !(WSTOPSIG (w) == SIGSTOP
-		&& current_thread->last_resume_kind == resume_stop)
+		&& cs->ss->current_thread->last_resume_kind == resume_stop)
  	   && !linux_wstatus_maybe_breakpoint (w))))
      {
        siginfo_t info, *info_p;

        if (debug_threads)
  	debug_printf ("Ignored signal %d for LWP %ld.\n",
-		      WSTOPSIG (w), lwpid_of (current_thread));
+		      WSTOPSIG (w), lwpid_of (cs->ss->current_thread));

-      if (ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
+      if (ptrace (PTRACE_GETSIGINFO, lwpid_of (cs->ss->current_thread),
  		  (PTRACE_TYPE_ARG3) 0, &info) == 0)
  	info_p = &info;
        else
@@ -3534,14 +3555,14 @@  linux_wait_1 (ptid_t ptid,
       left the single-step pending -- see
       complete_ongoing_step_over.  */
    report_to_gdb = (!maybe_internal_trap
-		   || (current_thread->last_resume_kind == resume_step
+		   || (cs->ss->current_thread->last_resume_kind == resume_step
  		       && !in_step_range)
  		   || event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT
  		   || (!in_step_range
  		       && !bp_explains_trap
  		       && !trace_event
  		       && !step_over_finished
-		       && !(current_thread->last_resume_kind == resume_continue
+		       && !(cs->ss->current_thread->last_resume_kind == resume_continue
  			    && event_child->stop_reason == TARGET_STOPPED_BY_SINGLE_STEP))
  		   || (gdb_breakpoint_here (event_child->stop_pc)
  		       && gdb_condition_true_at_breakpoint (event_child->stop_pc)
@@ -3577,7 +3598,7 @@  linux_wait_1 (ptid_t ptid,
        if (the_low_target.set_pc != NULL)
  	{
  	  struct regcache *regcache
-	    = get_thread_regcache (current_thread, 1);
+	    = get_thread_regcache (cs->ss->current_thread, 1);
  	  (*the_low_target.set_pc) (regcache, event_child->stop_pc);
  	}

@@ -3596,10 +3617,10 @@  linux_wait_1 (ptid_t ptid,
  	     there isn't single-step breakpoint if we finished stepping
  	     over.  */
  	  if (can_software_single_step ()
-	      && has_single_step_breakpoints (current_thread))
+	      && has_single_step_breakpoints (cs->ss->current_thread))
  	    {
  	      stop_all_lwps (0, event_child);
-	      delete_single_step_breakpoints (current_thread);
+	      delete_single_step_breakpoints (cs->ss->current_thread);
  	      unstop_all_lwps (0, event_child);
  	    }
  	}
@@ -3624,7 +3645,7 @@  linux_wait_1 (ptid_t ptid,
  	  debug_printf ("LWP %ld: extended event with waitstatus %s\n",
  			lwpid_of (get_lwp_thread (event_child)), str.c_str ());
  	}
-      if (current_thread->last_resume_kind == resume_step)
+      if (cs->ss->current_thread->last_resume_kind == resume_step)
  	{
  	  if (event_child->step_range_start == event_child->step_range_end)
  	    debug_printf ("GDB wanted to single-step, reporting event.\n");
@@ -3649,10 +3670,10 @@  linux_wait_1 (ptid_t ptid,
  	 staled memory.  */
        int remove_single_step_breakpoints_p = 0;

-      if (non_stop)
+      if (cs->non_stop)
  	{
  	  remove_single_step_breakpoints_p
-	    = has_single_step_breakpoints (current_thread);
+	    = has_single_step_breakpoints (cs->ss->current_thread);
  	}
        else
  	{
@@ -3677,10 +3698,10 @@  linux_wait_1 (ptid_t ptid,
  	     memory.  */
  	  stop_all_lwps (0, event_child);

-	  if (non_stop)
+	  if (cs->non_stop)
  	    {
-	      gdb_assert (has_single_step_breakpoints (current_thread));
-	      delete_single_step_breakpoints (current_thread);
+	      gdb_assert (has_single_step_breakpoints (cs->ss->current_thread));
+	      delete_single_step_breakpoints (cs->ss->current_thread);
  	    }
  	  else
  	    {
@@ -3697,12 +3718,12 @@  linux_wait_1 (ptid_t ptid,
    if (!stabilizing_threads)
      {
        /* In all-stop, stop all threads.  */
-      if (!non_stop)
+      if (!cs->non_stop)
  	stop_all_lwps (0, NULL);

        if (step_over_finished)
  	{
-	  if (!non_stop)
+	  if (!cs->non_stop)
  	    {
  	      /* If we were doing a step-over, all other threads but
  		 the stepping one had been paused in start_step_over,
@@ -3736,7 +3757,7 @@  linux_wait_1 (ptid_t ptid,
  	  select_event_lwp (&event_child);

  	  /* current_thread and event_child must stay in sync.  */
-	  current_thread = get_lwp_thread (event_child);
+	  cs->ss->current_thread = get_lwp_thread (event_child);

  	  event_child->status_pending_p = 0;
  	  w = event_child->status_pending;
@@ -3744,7 +3765,7 @@  linux_wait_1 (ptid_t ptid,


        /* Stabilize threads (move out of jump pads).  */
-      if (!non_stop)
+      if (!cs->non_stop)
  	stabilize_threads ();
      }
    else
@@ -3781,14 +3802,14 @@  linux_wait_1 (ptid_t ptid,
       it was a software breakpoint, and the client doesn't know we can
       adjust the breakpoint ourselves.  */
    if (event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
-      && !swbreak_feature)
+      && !cs->swbreak_feature)
      {
        int decr_pc = the_low_target.decr_pc_after_break;

        if (decr_pc != 0)
  	{
  	  struct regcache *regcache
-	    = get_thread_regcache (current_thread, 1);
+	    = get_thread_regcache (cs->ss->current_thread, 1);
  	  (*the_low_target.set_pc) (regcache, event_child->stop_pc + decr_pc);
  	}
      }
@@ -3799,7 +3820,7 @@  linux_wait_1 (ptid_t ptid,
  			    &ourstatus->value.syscall_number);
        ourstatus->kind = event_child->syscall_state;
      }
-  else if (current_thread->last_resume_kind == resume_stop
+  else if (cs->ss->current_thread->last_resume_kind == resume_stop
  	   && WSTOPSIG (w) == SIGSTOP)
      {
        /* A thread that has been requested to stop by GDB with vCont;t,
@@ -3807,7 +3828,7 @@  linux_wait_1 (ptid_t ptid,
  	 SIGSTOP is an implementation detail.  */
        ourstatus->value.sig = GDB_SIGNAL_0;
      }
-  else if (current_thread->last_resume_kind == resume_stop
+  else if (cs->ss->current_thread->last_resume_kind == resume_stop
  	   && WSTOPSIG (w) != SIGSTOP)
      {
        /* A thread that has been requested to stop by GDB with vCont;t,
@@ -3824,7 +3845,7 @@  linux_wait_1 (ptid_t ptid,
    if (debug_threads)
      {
        debug_printf ("linux_wait_1 ret = %s, %d, %d\n",
-		    target_pid_to_str (ptid_of (current_thread)),
+		    target_pid_to_str (ptid_of (cs->ss->current_thread)),
  		    ourstatus->kind, ourstatus->value.sig);
        debug_exit ();
      }
@@ -3832,7 +3853,7 @@  linux_wait_1 (ptid_t ptid,
    if (ourstatus->kind == TARGET_WAITKIND_EXITED)
      return filter_exit_event (event_child, ourstatus);

-  return ptid_of (current_thread);
+  return ptid_of (cs->ss->current_thread);
  }

  /* Get rid of any pending event in the pipe.  */
@@ -4013,12 +4034,13 @@  lwp_is_marked_dead (struct lwp_info *lwp)
  static void
  wait_for_sigstop (void)
  {
+  client_state *cs = get_client_state();
    struct thread_info *saved_thread;
    ptid_t saved_tid;
    int wstat;
    int ret;

-  saved_thread = current_thread;
+  saved_thread = cs->ss->current_thread;
    if (saved_thread != NULL)
      saved_tid = saved_thread->id;
    else
@@ -4035,7 +4057,7 @@  wait_for_sigstop (void)
    gdb_assert (ret == -1);

    if (saved_thread == NULL || linux_thread_alive (saved_tid))
-    current_thread = saved_thread;
+    cs->ss->current_thread = saved_thread;
    else
      {
        if (debug_threads)
@@ -4044,7 +4066,7 @@  wait_for_sigstop (void)
        /* We can't change the current inferior behind GDB's back,
  	 otherwise, a subsequent command may apply to the wrong
  	 process.  */
-      current_thread = NULL;
+      cs->ss->current_thread = NULL;
      }
  }

@@ -4079,6 +4101,7 @@  stuck_in_jump_pad_callback (thread_info *thread)
  static void
  move_out_of_jump_pad_callback (thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct thread_info *saved_thread;
    struct lwp_info *lwp = get_thread_lwp (thread);
    int *wstat;
@@ -4092,8 +4115,8 @@  move_out_of_jump_pad_callback (thread_info *thread)
    gdb_assert (lwp->stopped);

    /* For gdb_breakpoint_here.  */
-  saved_thread = current_thread;
-  current_thread = thread;
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = thread;

    wstat = lwp->status_pending_p ? &lwp->status_pending : NULL;

@@ -4123,7 +4146,7 @@  move_out_of_jump_pad_callback (thread_info *thread)
    else
      lwp_suspended_inc (lwp);

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
  }

  static bool
@@ -4205,11 +4228,12 @@  enqueue_pending_signal (struct lwp_info *lwp, 
int signal, siginfo_t *info)
  static void
  install_software_single_step_breakpoints (struct lwp_info *lwp)
  {
+  client_state *cs = get_client_state();
    struct thread_info *thread = get_lwp_thread (lwp);
    struct regcache *regcache = get_thread_regcache (thread, 1);
    struct cleanup *old_chain = make_cleanup_restore_current_thread ();

-  current_thread = thread;
+  cs->ss->current_thread = thread;
    std::vector<CORE_ADDR> next_pcs = the_low_target.get_next_pcs 
(regcache);

    for (CORE_ADDR pc : next_pcs)
@@ -4265,6 +4289,7 @@  static void
  linux_resume_one_lwp_throw (struct lwp_info *lwp,
  			    int step, int signal, siginfo_t *info)
  {
+  client_state *cs = get_client_state();
    struct thread_info *thread = get_lwp_thread (lwp);
    struct thread_info *saved_thread;
    int ptrace_request;
@@ -4322,8 +4347,8 @@  linux_resume_one_lwp_throw (struct lwp_info *lwp,
        return;
      }

-  saved_thread = current_thread;
-  current_thread = thread;
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = thread;

    /* This bit needs some thinking about.  If we get a signal that
       we must report while a single-step reinsert is still pending,
@@ -4399,7 +4424,7 @@  linux_resume_one_lwp_throw (struct lwp_info *lwp,

    if (proc->tdesc != NULL && the_low_target.get_pc != NULL)
      {
-      struct regcache *regcache = get_thread_regcache (current_thread, 1);
+      struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 1);

        lwp->stop_pc = (*the_low_target.get_pc) (regcache);

@@ -4453,7 +4478,7 @@  linux_resume_one_lwp_throw (struct lwp_info *lwp,
  	     of coercing an 8 byte integer to a 4 byte pointer.  */
  	  (PTRACE_TYPE_ARG4) (uintptr_t) signal);

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
    if (errno)
      perror_with_name ("resuming thread");

@@ -4655,6 +4680,7 @@  resume_status_pending_p (thread_info *thread)
  static bool
  need_step_over_p (thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct lwp_info *lwp = get_thread_lwp (thread);
    struct thread_info *saved_thread;
    CORE_ADDR pc;
@@ -4737,8 +4763,8 @@  need_step_over_p (thread_info *thread)
        return false;
      }

-  saved_thread = current_thread;
-  current_thread = thread;
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = thread;

    /* We can only step over breakpoints we know about.  */
    if (breakpoint_here (pc) || fast_tracepoint_jump_here (pc))
@@ -4755,7 +4781,7 @@  need_step_over_p (thread_info *thread)
  			  " GDB breakpoint at 0x%s; skipping step over\n",
  			  lwpid_of (thread), paddress (pc));

-	  current_thread = saved_thread;
+	  cs->ss->current_thread = saved_thread;
  	  return false;
  	}
        else
@@ -4767,13 +4793,13 @@  need_step_over_p (thread_info *thread)

  	  /* We've found an lwp that needs stepping over --- return 1 so
  	     that find_thread stops looking.  */
-	  current_thread = saved_thread;
+	  cs->ss->current_thread = saved_thread;

  	  return true;
  	}
      }

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;

    if (debug_threads)
      debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
@@ -4796,6 +4822,7 @@  need_step_over_p (thread_info *thread)
  static int
  start_step_over (struct lwp_info *lwp)
  {
+  client_state *cs = get_client_state();
    struct thread_info *thread = get_lwp_thread (lwp);
    struct thread_info *saved_thread;
    CORE_ADDR pc;
@@ -4823,8 +4850,8 @@  start_step_over (struct lwp_info *lwp)
       shouldn't care about.  */
    pc = get_pc (lwp);

-  saved_thread = current_thread;
-  current_thread = thread;
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = thread;

    lwp->bp_reinsert = pc;
    uninsert_breakpoints_at (pc);
@@ -4832,7 +4859,7 @@  start_step_over (struct lwp_info *lwp)

    step = single_step (lwp);

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;

    linux_resume_one_lwp (lwp, step, 0, NULL);

@@ -4848,14 +4875,16 @@  start_step_over (struct lwp_info *lwp)
  static int
  finish_step_over (struct lwp_info *lwp)
  {
+  client_state *cs = get_client_state();
+
    if (lwp->bp_reinsert != 0)
      {
-      struct thread_info *saved_thread = current_thread;
+      struct thread_info *saved_thread = cs->ss->current_thread;

        if (debug_threads)
  	debug_printf ("Finished step over.\n");

-      current_thread = get_lwp_thread (lwp);
+      cs->ss->current_thread = get_lwp_thread (lwp);

        /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
  	 may be no breakpoint to reinsert there by now.  */
@@ -4871,12 +4900,12 @@  finish_step_over (struct lwp_info *lwp)
  	 LWP stopped while doing that.  */
        if (!can_hardware_single_step ())
  	{
-	  gdb_assert (has_single_step_breakpoints (current_thread));
-	  delete_single_step_breakpoints (current_thread);
+	  gdb_assert (has_single_step_breakpoints (cs->ss->current_thread));
+	  delete_single_step_breakpoints (cs->ss->current_thread);
  	}

        step_over_bkpt = null_ptid;
-      current_thread = saved_thread;
+      cs->ss->current_thread = saved_thread;
        return 1;
      }
    else
@@ -5036,6 +5065,7 @@  linux_resume_one_thread (thread_info *thread, bool 
leave_all_stopped)
  static void
  linux_resume (struct thread_resume *resume_info, size_t n)
  {
+  client_state *cs = get_client_state();
    struct thread_info *need_step_over = NULL;

    if (debug_threads)
@@ -5056,7 +5086,7 @@  linux_resume (struct thread_resume *resume_info, 
size_t n)
       logic to each thread individually.  We consume all pending events
       before considering to start a step-over (in all-stop).  */
    bool any_pending = false;
-  if (!non_stop)
+  if (!cs->non_stop)
      any_pending = find_thread (resume_status_pending_p) != NULL;

    /* If there is a thread which would otherwise be resumed, which is
@@ -5327,12 +5357,13 @@  static int
  regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
  				  struct regcache *regcache)
  {
+  client_state *cs = get_client_state();
    struct regset_info *regset;
    int saw_general_regs = 0;
    int pid;
    struct iovec iov;

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);
    for (regset = regsets_info->regsets; regset->size >= 0; regset++)
      {
        void *buf, *data;
@@ -5405,12 +5436,13 @@  static int
  regsets_store_inferior_registers (struct regsets_info *regsets_info,
  				  struct regcache *regcache)
  {
+  client_state *cs = get_client_state();
    struct regset_info *regset;
    int saw_general_regs = 0;
    int pid;
    struct iovec iov;

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);
    for (regset = regsets_info->regsets; regset->size >= 0; regset++)
      {
        void *buf, *data;
@@ -5531,6 +5563,7 @@  static void
  fetch_register (const struct usrregs_info *usrregs,
  		struct regcache *regcache, int regno)
  {
+  client_state *cs = get_client_state();
    CORE_ADDR regaddr;
    int i, size;
    char *buf;
@@ -5550,7 +5583,7 @@  fetch_register (const struct usrregs_info *usrregs,
  	  & -sizeof (PTRACE_XFER_TYPE));
    buf = (char *) alloca (size);

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);
    for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
      {
        errno = 0;
@@ -5579,6 +5612,7 @@  static void
  store_register (const struct usrregs_info *usrregs,
  		struct regcache *regcache, int regno)
  {
+  client_state *cs = get_client_state();
    CORE_ADDR regaddr;
    int i, size;
    char *buf;
@@ -5604,7 +5638,7 @@  store_register (const struct usrregs_info *usrregs,
    else
      collect_register (regcache, regno, buf);

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);
    for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
      {
        errno = 0;
@@ -5744,7 +5778,8 @@  linux_store_registers (struct regcache *regcache, 
int regno)
  static int
  linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
  {
-  int pid = lwpid_of (current_thread);
+  client_state *cs = get_client_state();
+  int pid = lwpid_of (cs->ss->current_thread);
    PTRACE_XFER_TYPE *buffer;
    CORE_ADDR addr;
    int count;
@@ -5833,6 +5868,7 @@  linux_read_memory (CORE_ADDR memaddr, unsigned 
char *myaddr, int len)
  static int
  linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, 
int len)
  {
+  client_state *cs = get_client_state();
    int i;
    /* Round starting address down to longword boundary.  */
    CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
@@ -5844,7 +5880,7 @@  linux_write_memory (CORE_ADDR memaddr, const 
unsigned char *myaddr, int len)
    /* Allocate buffer of that many longwords.  */
    PTRACE_XFER_TYPE *buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);

-  int pid = lwpid_of (current_thread);
+  int pid = lwpid_of (cs->ss->current_thread);

    if (len == 0)
      {
@@ -5933,9 +5969,11 @@  linux_look_up_symbols (void)
  static void
  linux_request_interrupt (void)
  {
+  client_state *cs = get_client_state();
+
    /* Send a SIGINT to the process group.  This acts just like the user
       typed a ^C on the controlling terminal.  */
-  kill (-signal_pid, SIGINT);
+  kill (-cs->ss->signal_pid, SIGINT);
  }

  /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
@@ -5944,9 +5982,11 @@  linux_request_interrupt (void)
  static int
  linux_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int 
len)
  {
+  client_state *cs = get_client_state();
+
    char filename[PATH_MAX];
    int fd, n;
-  int pid = lwpid_of (current_thread);
+  int pid = lwpid_of (cs->ss->current_thread);

    xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);

@@ -6008,7 +6048,8 @@  linux_remove_point (enum raw_bkpt_type type, 
CORE_ADDR addr,
  static int
  linux_stopped_by_sw_breakpoint (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  client_state *cs = get_client_state();
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);

    return (lwp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT);
  }
@@ -6028,7 +6069,8 @@  linux_supports_stopped_by_sw_breakpoint (void)
  static int
  linux_stopped_by_hw_breakpoint (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  client_state *cs = get_client_state();
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);

    return (lwp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT);
  }
@@ -6059,7 +6101,8 @@  linux_supports_software_single_step (void)
  static int
  linux_stopped_by_watchpoint (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  client_state *cs = get_client_state();
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);

    return lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
  }
@@ -6067,7 +6110,8 @@  linux_stopped_by_watchpoint (void)
  static CORE_ADDR
  linux_stopped_data_address (void)
  {
-  struct lwp_info *lwp = get_thread_lwp (current_thread);
+  client_state *cs = get_client_state();
+  struct lwp_info *lwp = get_thread_lwp (cs->ss->current_thread);

    return lwp->stopped_data_address;
  }
@@ -6088,7 +6132,7 @@  static int
  linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
  {
    unsigned long text, text_end, data;
-  int pid = lwpid_of (current_thread);
+  int pid = lwpid_of (cs->ss->current_thread);

    errno = 0;

@@ -6133,6 +6177,7 @@  linux_qxfer_osdata (const char *annex,
  static void
  siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
  {
+  client_state *cs = get_client_state();
    int done = 0;

    if (the_low_target.siginfo_fixup != NULL)
@@ -6153,14 +6198,15 @@  static int
  linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
  		    unsigned const char *writebuf, CORE_ADDR offset, int len)
  {
+  client_state *cs = get_client_state();
    int pid;
    siginfo_t siginfo;
    gdb_byte inf_siginfo[sizeof (siginfo_t)];

-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      return -1;

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);

    if (debug_threads)
      debug_printf ("%s siginfo for lwp %d.\n",
@@ -6441,7 +6487,8 @@  linux_qxfer_spu (const char *annex, unsigned char 
*readbuf,
  		 unsigned const char *writebuf,
  		 CORE_ADDR offset, int len)
  {
-  long pid = lwpid_of (current_thread);
+  client_state *cs = get_client_state();
+  long pid = lwpid_of (cs->ss->current_thread);
    char buf[128];
    int fd = 0;
    int ret = 0;
@@ -6524,7 +6571,7 @@  static int
  linux_read_loadmap (const char *annex, CORE_ADDR offset,
  		    unsigned char *myaddr, unsigned int len)
  {
-  int pid = lwpid_of (current_thread);
+  int pid = lwpid_of (cs->ss->current_thread);
    int addr = -1;
    struct target_loadmap *data = NULL;
    unsigned int actual_length, copy_length;
@@ -6631,9 +6678,11 @@  linux_unpause_all (int unfreeze)
  static int
  linux_prepare_to_access_memory (void)
  {
+  client_state *cs = get_client_state();
+
    /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
       running LWP.  */
-  if (non_stop)
+  if (cs->non_stop)
      linux_pause_all (1);
    return 0;
  }
@@ -6641,9 +6690,11 @@  linux_prepare_to_access_memory (void)
  static void
  linux_done_accessing_memory (void)
  {
+  client_state *cs = get_client_state();
+
    /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
       running LWP.  */
-  if (non_stop)
+  if (cs->non_stop)
      linux_unpause_all (1);
  }

@@ -6988,6 +7039,7 @@  linux_qxfer_libraries_svr4 (const char *annex, 
unsigned char *readbuf,
  			    unsigned const char *writebuf,
  			    CORE_ADDR offset, int len)
  {
+  client_state *cs = get_client_state();
    char *document;
    unsigned document_len;
    struct process_info_private *const priv = current_process ()->priv;
@@ -7029,7 +7081,7 @@  linux_qxfer_libraries_svr4 (const char *annex, 
unsigned char *readbuf,
    if (readbuf == NULL)
      return -1;

-  pid = lwpid_of (current_thread);
+  pid = lwpid_of (cs->ss->current_thread);
    xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
    is_elf64 = elf_64_file_p (filename, &machine);
    lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
@@ -7367,7 +7419,9 @@  linux_low_btrace_conf (const struct 
btrace_target_info *tinfo,
  ptid_t
  current_lwp_ptid (void)
  {
-  return ptid_of (current_thread);
+  client_state *cs = get_client_state();
+
+  return ptid_of (cs->ss->current_thread);
  }

  /* Implementation of the target_ops method "breakpoint_kind_from_pc".  */
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
index d423633747a..9054d560157 100644
--- a/gdb/gdbserver/linux-mips-low.c
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -126,7 +126,7 @@  mips_read_description (void)
  {
    if (have_dsp < 0)
      {
-      int pid = lwpid_of (current_thread);
+      int pid = lwpid_of (cs->ss->current_thread);

        errno = 0;
        ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0);
@@ -467,7 +467,7 @@  mips_insert_point (enum raw_bkpt_type type, 
CORE_ADDR addr,
    enum target_hw_bp_type watch_type;
    uint32_t irw;

-  lwpid = lwpid_of (current_thread);
+  lwpid = lwpid_of (cs->ss->current_thread);
    if (!mips_linux_read_watch_registers (lwpid,
  					&priv->watch_readback,
  					&priv->watch_readback_valid,
@@ -558,7 +558,7 @@  mips_stopped_by_watchpoint (void)
    struct arch_process_info *priv = proc->priv->arch_private;
    int n;
    int num_valid;
-  long lwpid = lwpid_of (current_thread);
+  long lwpid = lwpid_of (cs->ss->current_thread);

    if (!mips_linux_read_watch_registers (lwpid,
  					&priv->watch_readback,
@@ -586,7 +586,7 @@  mips_stopped_data_address (void)
    struct arch_process_info *priv = proc->priv->arch_private;
    int n;
    int num_valid;
-  long lwpid = lwpid_of (current_thread);
+  long lwpid = lwpid_of (cs->ss->current_thread);

    /* On MIPS we don't know the low order 3 bits of the data address.
       GDB does not support remote targets that can't report the
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c
index 36bd373c885..35557ab582c 100644
--- a/gdb/gdbserver/linux-ppc-low.c
+++ b/gdb/gdbserver/linux-ppc-low.c
@@ -1272,7 +1272,7 @@  ppc_install_fast_tracepoint_jump_pad (CORE_ADDR 
tpoint, CORE_ADDR tpaddr,
    const CORE_ADDR entryaddr = *jump_entry;
    int rsz, min_frame, frame_size, tp_reg;
  #ifdef __powerpc64__
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);
    int is_64 = register_size (regcache->tdesc, 0) == 8;
    int is_opd = is_64 && !is_elfv2_inferior ();
  #else
@@ -3044,7 +3044,7 @@  static struct emit_ops *
  ppc_emit_ops (void)
  {
  #ifdef __powerpc64__
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);

    if (register_size (regcache->tdesc, 0) == 8)
      {
@@ -3062,7 +3062,7 @@  ppc_emit_ops (void)
  static int
  ppc_get_ipa_tdesc_idx (void)
  {
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);
    const struct target_desc *tdesc = regcache->tdesc;

  #ifdef __powerpc64__
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index 451f42c7c99..d5828549620 100644
--- a/gdb/gdbserver/linux-s390-low.c
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -541,7 +541,7 @@  s390_arch_setup (void)
    struct regset_info *regset;

    /* Check whether the kernel supports extra register sets.  */
-  int pid = pid_of (current_thread);
+  int pid = pid_of (cs->ss->current_thread);
    int have_regset_last_break
      = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
    int have_regset_system_call
@@ -770,7 +770,7 @@  s390_get_thread_area (int lwpid, CORE_ADDR *addrp)
  {
    CORE_ADDR res = ptrace (PTRACE_PEEKUSER, lwpid, (long) PT_ACR0, 
(long) 0);
  #ifdef __s390x__
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);

    if (register_size (regcache->tdesc, 0) == 4)
      res &= 0xffffffffull;
@@ -1260,7 +1260,7 @@  s390_install_fast_tracepoint_jump_pad (CORE_ADDR 
tpoint,
    unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 };	/* jg ... */
    CORE_ADDR buildaddr = *jump_entry;
  #ifdef __s390x__
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);
    int is_64 = register_size (regcache->tdesc, 0) == 8;
    int is_zarch = is_64 || have_hwcap_s390_high_gprs;
    int has_vx = have_hwcap_s390_vx;
@@ -1425,7 +1425,7 @@  s390_get_min_fast_tracepoint_insn_len (void)
  static int
  s390_get_ipa_tdesc_idx (void)
  {
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);
    const struct target_desc *tdesc = regcache->tdesc;

  #ifdef __s390x__
@@ -2798,7 +2798,7 @@  static struct emit_ops *
  s390_emit_ops (void)
  {
  #ifdef __s390x__
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);

    if (register_size (regcache->tdesc, 0) == 8)
      return &s390x_emit_ops;
diff --git a/gdb/gdbserver/linux-tile-low.c b/gdb/gdbserver/linux-tile-low.c
index 620f61d1707..dafbab674ef 100644
--- a/gdb/gdbserver/linux-tile-low.c
+++ b/gdb/gdbserver/linux-tile-low.c
@@ -150,7 +150,7 @@  tile_regs_info (void)
  static void
  tile_arch_setup (void)
  {
-  int pid = pid_of (current_thread);
+  int pid = pid_of (cs->ss->current_thread);
    unsigned int machine;
    int is_elf64 = linux_pid_exe_is_elf_64_file (pid, &machine);

diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 408b54f2577..2fa464e889e 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -181,7 +181,8 @@  static /*const*/ int i386_regmap[] =
  static int
  is_64bit_tdesc (void)
  {
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  client_state *cs = get_client_state();
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);

    return register_size (regcache->tdesc, 0) == 8;
  }
@@ -304,6 +305,7 @@  x86_cannot_fetch_register (int regno)
  static void
  x86_fill_gregset (struct regcache *regcache, void *buf)
  {
+  client_state *cs = get_client_state();
    int i;

  #ifdef __x86_64__
@@ -316,7 +318,7 @@  x86_fill_gregset (struct regcache *regcache, void *buf)
  #ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
        {
          unsigned long base;
-        int lwpid = lwpid_of (current_thread);
+        int lwpid = lwpid_of (cs->ss->current_thread);

          collect_register_by_name (regcache, "fs_base", &base);
          ptrace (PTRACE_ARCH_PRCTL, lwpid, &base, ARCH_SET_FS);
@@ -344,6 +346,7 @@  x86_fill_gregset (struct regcache *regcache, void *buf)
  static void
  x86_store_gregset (struct regcache *regcache, const void *buf)
  {
+  client_state *cs = get_client_state();
    int i;

  #ifdef __x86_64__
@@ -356,7 +359,7 @@  x86_store_gregset (struct regcache *regcache, const 
void *buf)
  #ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
        {
          unsigned long base;
-        int lwpid = lwpid_of (current_thread);
+        int lwpid = lwpid_of (cs->ss->current_thread);

          if (ptrace (PTRACE_ARCH_PRCTL, lwpid, &base, ARCH_GET_FS) == 0)
            supply_register_by_name (regcache, "fs_base", &base);
@@ -679,8 +682,9 @@  static int
  x86_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
  {
  #ifdef __x86_64__
+  client_state *cs = get_client_state();
    unsigned int machine;
-  int tid = lwpid_of (current_thread);
+  int tid = lwpid_of (cs->ss->current_thread);
    int is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);

    /* Is the inferior 32-bit?  If so, then fixup the siginfo object.  */
@@ -735,6 +739,7 @@  int have_ptrace_getfpxregs =
  static const struct target_desc *
  x86_linux_read_description (void)
  {
+  client_state *cs = get_client_state();
    unsigned int machine;
    int is_elf64;
    int xcr0_features;
@@ -742,7 +747,7 @@  x86_linux_read_description (void)
    static uint64_t xcr0;
    struct regset_info *regset;

-  tid = lwpid_of (current_thread);
+  tid = lwpid_of (cs->ss->current_thread);

    is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);

@@ -860,7 +865,8 @@  x86_linux_read_description (void)
  static void
  x86_linux_update_xmltarget (void)
  {
-  struct thread_info *saved_thread = current_thread;
+  client_state *cs = get_client_state();
+  struct thread_info *saved_thread = cs->ss->current_thread;

    /* Before changing the register cache's internal layout, flush the
       contents of the current valid caches back to the threads, and
@@ -868,15 +874,16 @@  x86_linux_update_xmltarget (void)
    regcache_release ();

    for_each_process ([] (process_info *proc) {
+    client_state *cs = get_client_state();
      int pid = proc->pid;

      /* Look up any thread of this process.  */
-    current_thread = find_any_thread_of_pid (pid);
+    cs->ss->current_thread = find_any_thread_of_pid (pid);

      the_low_target.arch_setup ();
    });

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
  }

  /* Process qSupported query, "xmlRegisters=".  Update the buffer size for
@@ -2824,7 +2831,8 @@  x86_supports_hardware_single_step (void)
  static int
  x86_get_ipa_tdesc_idx (void)
  {
-  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  client_state *cs = get_client_state();
+  struct regcache *regcache = get_thread_regcache 
(cs->ss->current_thread, 0);
    const struct target_desc *tdesc = regcache->tdesc;

  #ifdef __x86_64__
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index a0b98177296..4e72721498b 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -250,10 +250,10 @@  lynx_ptrace_fun ()

  static int
  lynx_create_inferior (const char *program,
-		      const std::vector<char *> &program_args)
+		      const std::vector<char *> &cs->program_args)
  {
    int pid;
-  std::string str_program_args = stringify_argv (program_args);
+  std::string str_program_args = stringify_argv (cs->program_args);

    lynx_debug ("lynx_create_inferior ()");

@@ -350,7 +350,7 @@  lynx_resume (struct thread_resume *resume_info, 
size_t n)
       the moment we resume its execution for the first time.  It is
       fine to use the current_thread's ptid in those cases.  */
    if (ptid_equal (ptid, minus_one_ptid))
-    ptid = ptid_of (current_thread);
+    ptid = ptid_of (cs->ss->current_thread);

    regcache_invalidate_pid (ptid_get_pid (ptid));

@@ -423,7 +423,7 @@  lynx_wait_1 (ptid_t ptid, struct target_waitstatus 
*status, int options)
    ptid_t new_ptid;

    if (ptid_equal (ptid, minus_one_ptid))
-    pid = lynx_ptid_get_pid (ptid_of (current_thread));
+    pid = lynx_ptid_get_pid (ptid_of (cs->ss->current_thread));
    else
      pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));

@@ -594,7 +594,7 @@  static void
  lynx_fetch_registers (struct regcache *regcache, int regno)
  {
    struct lynx_regset_info *regset = lynx_target_regsets;
-  ptid_t inferior_ptid = ptid_of (current_thread);
+  ptid_t inferior_ptid = ptid_of (cs->ss->current_thread);

    lynx_debug ("lynx_fetch_registers (regno = %d)", regno);

@@ -619,7 +619,7 @@  static void
  lynx_store_registers (struct regcache *regcache, int regno)
  {
    struct lynx_regset_info *regset = lynx_target_regsets;
-  ptid_t inferior_ptid = ptid_of (current_thread);
+  ptid_t inferior_ptid = ptid_of (cs->ss->current_thread);

    lynx_debug ("lynx_store_registers (regno = %d)", regno);

@@ -655,7 +655,7 @@  lynx_read_memory (CORE_ADDR memaddr, unsigned char 
*myaddr, int len)
    int buf;
    const int xfer_size = sizeof (buf);
    CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
-  ptid_t inferior_ptid = ptid_of (current_thread);
+  ptid_t inferior_ptid = ptid_of (cs->ss->current_thread);

    while (addr < memaddr + len)
      {
@@ -688,7 +688,7 @@  lynx_write_memory (CORE_ADDR memaddr, const unsigned 
char *myaddr, int len)
    int buf;
    const int xfer_size = sizeof (buf);
    CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
-  ptid_t inferior_ptid = ptid_of (current_thread);
+  ptid_t inferior_ptid = ptid_of (cs->ss->current_thread);

    while (addr < memaddr + len)
      {
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index bb385733fe4..dca4756bacd 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -1301,6 +1301,8 @@  add_breakpoint_condition (struct gdb_breakpoint 
*bp, const char **condition)
  static int
  gdb_condition_true_at_breakpoint_z_type (char z_type, CORE_ADDR addr)
  {
+  client_state *cs = get_client_state();
+
    /* Fetch registers for the current inferior.  */
    struct gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, -1);
    ULONGEST value = 0;
@@ -1316,7 +1318,7 @@  gdb_condition_true_at_breakpoint_z_type (char 
z_type, CORE_ADDR addr)
    if (bp->cond_list == NULL)
      return 1;

-  ctx.regcache = get_thread_regcache (current_thread, 1);
+  ctx.regcache = get_thread_regcache (cs->ss->current_thread, 1);
    ctx.tframe = NULL;
    ctx.tpoint = NULL;

@@ -1429,6 +1431,8 @@  gdb_no_commands_at_breakpoint (CORE_ADDR where)
  static int
  run_breakpoint_commands_z_type (char z_type, CORE_ADDR addr)
  {
+  client_state *cs = get_client_state();
+
    /* Fetch registers for the current inferior.  */
    struct gdb_breakpoint *bp = find_gdb_breakpoint (z_type, addr, -1);
    ULONGEST value = 0;
@@ -1439,7 +1443,7 @@  run_breakpoint_commands_z_type (char z_type, 
CORE_ADDR addr)
    if (bp == NULL)
      return 1;

-  ctx.regcache = get_thread_regcache (current_thread, 1);
+  ctx.regcache = get_thread_regcache (cs->ss->current_thread, 1);
    ctx.tframe = NULL;
    ctx.tpoint = NULL;

@@ -1479,6 +1483,7 @@  gdb_breakpoint_here (CORE_ADDR where)
  void
  set_single_step_breakpoint (CORE_ADDR stop_at, ptid_t ptid)
  {
+  client_state *cs = get_client_state();
    struct single_step_breakpoint *bp;

    gdb_assert (ptid_get_pid (current_ptid) == ptid_get_pid (ptid));
@@ -1491,6 +1496,7 @@  set_single_step_breakpoint (CORE_ADDR stop_at, 
ptid_t ptid)
  void
  delete_single_step_breakpoints (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct process_info *proc = get_thread_process (thread);
    struct breakpoint *bp, **bp_link;

@@ -1503,13 +1509,13 @@  delete_single_step_breakpoints (struct 
thread_info *thread)
  	  && ptid_equal (((struct single_step_breakpoint *) bp)->ptid,
  			 ptid_of (thread)))
  	{
-	  struct thread_info *saved_thread = current_thread;
+	  struct thread_info *saved_thread = cs->ss->current_thread;

-	  current_thread = thread;
+	  cs->ss->current_thread = thread;
  	  *bp_link = bp->next;
  	  release_breakpoint (proc, bp);
  	  bp = *bp_link;
-	  current_thread = saved_thread;
+	  cs->ss->current_thread = saved_thread;
  	}
        else
  	{
@@ -1591,6 +1597,7 @@  uninsert_all_breakpoints (void)
  void
  uninsert_single_step_breakpoints (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct process_info *proc = get_thread_process (thread);
    struct breakpoint *bp;

@@ -1606,11 +1613,11 @@  uninsert_single_step_breakpoints (struct 
thread_info *thread)
  	   reinsert breakpoint.  */
  	if (bp->raw->refcount == 1)
  	  {
-	    struct thread_info *saved_thread = current_thread;
+	    struct thread_info *saved_thread = cs->ss->current_thread;

-	    current_thread = thread;
+	    cs->ss->current_thread = thread;
  	    uninsert_raw_breakpoint (bp->raw);
-	    current_thread = saved_thread;
+	    cs->ss->current_thread = saved_thread;
  	  }
        }
      }
@@ -1701,6 +1708,7 @@  reinsert_all_breakpoints (void)
  void
  reinsert_single_step_breakpoints (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct process_info *proc = get_thread_process (thread);
    struct breakpoint *bp;

@@ -1714,11 +1722,11 @@  reinsert_single_step_breakpoints (struct 
thread_info *thread)

  	  if (bp->raw->refcount == 1)
  	    {
-	      struct thread_info *saved_thread = current_thread;
+	      struct thread_info *saved_thread = cs->ss->current_thread;

-	      current_thread = thread;
+	      cs->ss->current_thread = thread;
  	      reinsert_raw_breakpoint (bp->raw);
-	      current_thread = saved_thread;
+	      cs->ss->current_thread = saved_thread;
  	    }
  	}
      }
diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c
index 5ff7079123f..b2ca4b50207 100644
--- a/gdb/gdbserver/notif.c
+++ b/gdb/gdbserver/notif.c
@@ -79,6 +79,7 @@  notif_write_event (struct notif_server *notif, char 
*own_buf)
  int
  handle_notif_ack (char *own_buf, int packet_len)
  {
+  client_state *cs = get_client_state();
    size_t i;
    struct notif_server *np;

@@ -103,7 +104,7 @@  handle_notif_ack (char *own_buf, int packet_len)
        struct notif_event *head
  	= QUEUE_deque (notif_event_p, np->queue);

-      if (remote_debug)
+      if (cs->remote_debug)
  	debug_printf ("%s: acking %d\n", np->ack_name,
  		      QUEUE_length (notif_event_p, np->queue));

@@ -121,9 +122,11 @@  void
  notif_event_enque (struct notif_server *notif,
  		   struct notif_event *event)
  {
+  client_state *cs = get_client_state();
+
    QUEUE_enque (notif_event_p, notif->queue, event);

-  if (remote_debug)
+  if (cs->remote_debug)
      debug_printf ("pending events: %s %d\n", notif->notif_name,
  		  QUEUE_length (notif_event_p, notif->queue));

diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index a570ca9991c..02c5ece47d2 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -352,12 +352,12 @@  nto_read_auxv_from_initial_stack (CORE_ADDR 
initial_stack,

  static int
  nto_create_inferior (const char *program,
-		     const std::vector<char *> &program_args)
+		     const std::vector<char *> &cs->program_args)
  {
    struct inheritance inherit;
    pid_t pid;
    sigset_t set;
-  std::string str_program_args = stringify_argv (program_args);
+  std::string str_program_args = stringify_argv (cs->program_args);

    TRACE ("%s %s\n", __func__, program);
    /* Clear any pending SIGUSR1's but keep the behavior the same.  */
@@ -625,12 +625,12 @@  nto_fetch_registers (struct regcache *regcache, 
int regno)
    if (regno >= the_low_target.num_regs)
      return;

-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      {
        TRACE ("current_thread is NULL\n");
        return;
      }
-  ptid_t ptid = ptid_of (current_thread);
+  ptid_t ptid = ptid_of (cs->ss->current_thread);
    if (!nto_set_thread (ptid))
      return;

@@ -671,12 +671,12 @@  nto_store_registers (struct regcache *regcache, 
int regno)

    TRACE ("%s (regno:%d)\n", __func__, regno);

-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      {
        TRACE ("current_thread is NULL\n");
        return;
      }
-  ptid_t ptid = ptid_of (current_thread);
+  ptid_t ptid = ptid_of (cs->ss->current_thread);
    if (!nto_set_thread (ptid))
      return;

@@ -863,9 +863,9 @@  nto_stopped_by_watchpoint (void)
    int ret = 0;

    TRACE ("%s\n", __func__);
-  if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
+  if (nto_inferior.ctl_fd != -1 && cs->ss->current_thread != NULL)
      {
-      ptid_t ptid = ptid_of (current_thread);
+      ptid_t ptid = ptid_of (cs->ss->current_thread);
        if (nto_set_thread (ptid))
  	{
  	  const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
@@ -893,9 +893,9 @@  nto_stopped_data_address (void)
    CORE_ADDR ret = (CORE_ADDR)0;

    TRACE ("%s\n", __func__);
-  if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
+  if (nto_inferior.ctl_fd != -1 && cs->ss->current_thread != NULL)
      {
-      ptid_t ptid = ptid_of (current_thread);
+      ptid_t ptid = ptid_of (cs->ss->current_thread);

        if (nto_set_thread (ptid))
  	{
diff --git a/gdb/gdbserver/proc-service.c b/gdb/gdbserver/proc-service.c
index f7912b884c5..01a9371465a 100644
--- a/gdb/gdbserver/proc-service.c
+++ b/gdb/gdbserver/proc-service.c
@@ -104,6 +104,7 @@  ps_err_e
  ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
  {
  #ifdef HAVE_REGSETS
+  client_state *cs = get_client_state();
    struct lwp_info *lwp;
    struct thread_info *reg_thread, *saved_thread;
    struct regcache *regcache;
@@ -113,12 +114,12 @@  ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t 
lwpid, prgregset_t gregset)
      return PS_ERR;

    reg_thread = get_lwp_thread (lwp);
-  saved_thread = current_thread;
-  current_thread = reg_thread;
-  regcache = get_thread_regcache (current_thread, 1);
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = reg_thread;
+  regcache = get_thread_regcache (cs->ss->current_thread, 1);
    gregset_info ()->fill_function (regcache, gregset);

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
    return PS_OK;
  #else
    return PS_ERR;
@@ -161,5 +162,7 @@  ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t 
lwpid, const prfpregset_t *fpregs
  pid_t
  ps_getpid (gdb_ps_prochandle_t ph)
  {
-  return pid_of (current_thread);
+  client_state *cs = get_client_state();
+
+  return pid_of (cs->ss->current_thread);
  }
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index 1bb15900dd2..0ae73fb78e8 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -26,6 +26,7 @@ 
  struct regcache *
  get_thread_regcache (struct thread_info *thread, int fetch)
  {
+  client_state *cs = get_client_state();
    struct regcache *regcache;

    regcache = thread_regcache_data (thread);
@@ -49,14 +50,14 @@  get_thread_regcache (struct thread_info *thread, int 
fetch)

    if (fetch && regcache->registers_valid == 0)
      {
-      struct thread_info *saved_thread = current_thread;
+      struct thread_info *saved_thread = cs->ss->current_thread;

-      current_thread = thread;
+      cs->ss->current_thread = thread;
        /* Invalidate all registers, to prevent stale left-overs.  */
        memset (regcache->register_status, REG_UNAVAILABLE,
  	      regcache->tdesc->reg_defs.size ());
        fetch_inferior_registers (regcache, -1);
-      current_thread = saved_thread;
+      cs->ss->current_thread = saved_thread;
        regcache->registers_valid = 1;
      }

@@ -74,6 +75,7 @@  get_thread_regcache_for_ptid (ptid_t ptid)
  void
  regcache_invalidate_thread (struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
    struct regcache *regcache;

    regcache = thread_regcache_data (thread);
@@ -83,11 +85,11 @@  regcache_invalidate_thread (struct thread_info *thread)

    if (regcache->registers_valid)
      {
-      struct thread_info *saved_thread = current_thread;
+      struct thread_info *saved_thread = cs->ss->current_thread;

-      current_thread = thread;
+      cs->ss->current_thread = thread;
        store_inferior_registers (regcache, -1);
-      current_thread = saved_thread;
+      cs->ss->current_thread = saved_thread;
      }

    regcache->registers_valid = 0;
@@ -107,8 +109,10 @@  regcache_invalidate_pid (int pid)
  void
  regcache_invalidate (void)
  {
+  client_state *cs = get_client_state();
+
    /* Only update the threads of the current process.  */
-  int pid = current_thread->id.pid ();
+  int pid = cs->ss->current_thread->id.pid ();

    regcache_invalidate_pid (pid);
  }
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 3b5a459ae4c..99ba97c02ca 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -103,7 +103,6 @@  struct sym_cache
    struct sym_cache *next;
  };

-int remote_debug = 0;
  struct ui_file *gdb_stdlog;

  static int remote_is_stdio = 0;
@@ -115,16 +114,18 @@  static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
  extern int using_threads;
  extern int debug_threads;

-/* If true, then GDB has requested noack mode.  */
-int noack_mode = 0;
-/* If true, then we tell GDB to use noack mode by default.  */
-int transport_is_reliable = 0;
-
  #ifdef USE_WIN32API
  # define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
  # define write(fd, buf, len) send (fd, (char *) buf, len, 0)
  #endif

+int
+get_remote_desc (void)
+{
+  return remote_desc;
+}
+
+
  int
  gdb_connected (void)
  {
@@ -156,6 +157,7 @@  enable_async_notification (int fd)
  static int
  handle_accept_event (int err, gdb_client_data client_data)
  {
+  client_state *cs = get_client_state();
    struct sockaddr_in sockaddr;
    socklen_t tmp;

@@ -167,6 +169,9 @@  handle_accept_event (int err, gdb_client_data 
client_data)
    if (remote_desc == -1)
      perror_with_name ("Accept failed");

+  struct multi_client_states *client_states = get_client_states();
+  client_states->set_client_state (remote_desc);
+
    /* Enable TCP keep alive process. */
    tmp = 1;
    setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
@@ -183,7 +188,7 @@  handle_accept_event (int err, gdb_client_data 
client_data)
  				   exits when the remote side dies.  */
  #endif

-  if (run_once)
+  if (cs->run_once)
      {
  #ifndef USE_WIN32API
        close (listen_desc);		/* No longer need this */
@@ -222,6 +227,7 @@  handle_accept_event (int err, gdb_client_data 
client_data)
  void
  remote_prepare (const char *name)
  {
+  client_state *cs = get_client_state();
    const char *port_str;
  #ifdef USE_WIN32API
    static int winsock_initialized;
@@ -238,14 +244,14 @@  remote_prepare (const char *name)
  	 call to remote_open so start_inferior knows the connection is
  	 via stdio.  */
        remote_is_stdio = 1;
-      transport_is_reliable = 1;
+      cs->transport_is_reliable = 1;
        return;
      }

    port_str = strchr (name, ':');
    if (port_str == NULL)
      {
-      transport_is_reliable = 0;
+      cs->transport_is_reliable = 0;
        return;
      }

@@ -280,7 +286,7 @@  remote_prepare (const char *name)
        || listen (listen_desc, 1))
      perror_with_name ("Can't bind address");

-  transport_is_reliable = 1;
+  cs->transport_is_reliable = 1;
  }

  /* Open a connection to a remote debugger.
@@ -485,9 +491,10 @@  try_rle (char *buf, int remaining, unsigned char 
*csum, char **p)
  char *
  write_ptid (char *buf, ptid_t ptid)
  {
+  client_state *cs = get_client_state();
    int pid, tid;

-  if (multi_process)
+  if (cs->multi_process)
      {
        pid = ptid_get_pid (ptid);
        if (pid < 0)
@@ -594,6 +601,7 @@  read_prim (void *buf, int count)
  static int
  putpkt_binary_1 (char *buf, int cnt, int is_notif)
  {
+  client_state *cs = get_client_state();
    int i;
    unsigned char csum = 0;
    char *buf2;
@@ -631,10 +639,10 @@  putpkt_binary_1 (char *buf, int cnt, int is_notif)
  	  return -1;
  	}

-      if (noack_mode || is_notif)
+      if (cs->noack_mode || is_notif)
  	{
  	  /* Don't expect an ack then.  */
-	  if (remote_debug)
+	  if (cs->remote_debug)
  	    {
  	      if (is_notif)
  		debug_printf ("putpkt (\"%s\"); [notif]\n", buf2);
@@ -645,7 +653,7 @@  putpkt_binary_1 (char *buf, int cnt, int is_notif)
  	  break;
  	}

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf ("putpkt (\"%s\"); [looking for ack]\n", buf2);
  	  debug_flush ();
@@ -659,14 +667,14 @@  putpkt_binary_1 (char *buf, int cnt, int is_notif)
  	  return -1;
  	}

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf ("[received '%c' (0x%x)]\n", cc, cc);
  	  debug_flush ();
  	}

        /* Check for an input interrupt while we're here.  */
-      if (cc == '\003' && current_thread != NULL)
+      if (cc == '\003' && cs->ss->current_thread != NULL)
  	(*the_target->request_interrupt) ();
      }
    while (cc != '+');
@@ -838,30 +846,23 @@  initialize_async_io (void)
  #endif
  }

-/* Internal buffer used by readchar.
-   These are global to readchar because reschedule_remote needs to be
-   able to tell whether the buffer is empty.  */
-
-static unsigned char readchar_buf[BUFSIZ];
-static int readchar_bufcnt = 0;
-static unsigned char *readchar_bufp;
-
  /* Returns next char from remote GDB.  -1 if error.  */

  static int
  readchar (void)
  {
+  client_state *cs = get_client_state();
    int ch;

-  if (readchar_bufcnt == 0)
+  if (cs->ss->readchar_bufcnt == 0)
      {
-      readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
+      cs->ss->readchar_bufcnt = read_prim (cs->ss->readchar_buf, sizeof 
(cs->ss->readchar_buf));

-      if (readchar_bufcnt <= 0)
+      if (cs->ss->readchar_bufcnt <= 0)
  	{
-	  if (readchar_bufcnt == 0)
+	  if (cs->ss->readchar_bufcnt == 0)
  	    {
-	      if (remote_debug)
+	      if (cs->remote_debug)
  		debug_printf ("readchar: Got EOF\n");
  	    }
  	  else
@@ -870,11 +871,11 @@  readchar (void)
  	  return -1;
  	}

-      readchar_bufp = readchar_buf;
+      cs->ss->readchar_bufp = cs->ss->readchar_buf;
      }

-  readchar_bufcnt--;
-  ch = *readchar_bufp++;
+  cs->ss->readchar_bufcnt--;
+  ch = *cs->ss->readchar_bufp++;
    reschedule ();
    return ch;
  }
@@ -884,7 +885,9 @@  readchar (void)
  static void
  reset_readchar (void)
  {
-  readchar_bufcnt = 0;
+  client_state *cs = get_client_state();
+
+  cs->ss->readchar_bufcnt = 0;
    if (readchar_callback != NOT_SCHEDULED)
      {
        delete_callback_event (readchar_callback);
@@ -897,12 +900,13 @@  reset_readchar (void)
  static int
  process_remaining (void *context)
  {
+  client_state *cs = get_client_state();
    int res;

    /* This is a one-shot event.  */
    readchar_callback = NOT_SCHEDULED;

-  if (readchar_bufcnt > 0)
+  if (cs->ss->readchar_bufcnt > 0)
      res = handle_serial_event (0, NULL);
    else
      res = 0;
@@ -916,7 +920,9 @@  process_remaining (void *context)
  static void
  reschedule (void)
  {
-  if (readchar_bufcnt > 0 && readchar_callback == NOT_SCHEDULED)
+  client_state *cs = get_client_state();
+
+  if (cs->ss->readchar_bufcnt > 0 && readchar_callback == NOT_SCHEDULED)
      readchar_callback = append_callback_event (process_remaining, NULL);
  }

@@ -926,6 +932,7 @@  reschedule (void)
  int
  getpkt (char *buf)
  {
+  client_state *cs = get_client_state();
    char *bp;
    unsigned char csum, c1, c2;
    int c;
@@ -948,7 +955,7 @@  getpkt (char *buf)

  	  if (c == '$')
  	    break;
-	  if (remote_debug)
+	  if (cs->remote_debug)
  	    {
  	      debug_printf ("[getpkt: discarding char '%c']\n", c);
  	      debug_flush ();
@@ -977,7 +984,7 @@  getpkt (char *buf)
        if (csum == (c1 << 4) + c2)
  	break;

-      if (noack_mode)
+      if (cs->noack_mode)
  	{
  	  fprintf (stderr,
  		   "Bad checksum, sentsum=0x%x, csum=0x%x, "
@@ -993,9 +1000,9 @@  getpkt (char *buf)
  	return -1;
      }

-  if (!noack_mode)
+  if (!cs->noack_mode)
      {
-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf ("getpkt (\"%s\");  [sending ack] \n", buf);
  	  debug_flush ();
@@ -1004,7 +1011,7 @@  getpkt (char *buf)
        if (write_prim ("+", 1) != 1)
  	return -1;

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf ("[sent ack]\n");
  	  debug_flush ();
@@ -1012,7 +1019,7 @@  getpkt (char *buf)
      }
    else
      {
-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf ("getpkt (\"%s\");  [no ack sent] \n", buf);
  	  debug_flush ();
@@ -1028,7 +1035,7 @@  getpkt (char *buf)
       check for interrupt after the vCont;c packet, the interrupt character
       would stay in the buffer unattended until after the next (unrelated)
       stop.  */
-  while (readchar_bufcnt > 0 && *readchar_bufp == '\003')
+  while (cs->ss->readchar_bufcnt > 0 && *cs->ss->readchar_bufp == '\003')
      {
        /* Consume the interrupt character in the buffer.  */
        readchar ();
@@ -1081,6 +1088,8 @@  void
  prepare_resume_reply (char *buf, ptid_t ptid,
  		      struct target_waitstatus *status)
  {
+  client_state *cs = get_client_state();
+
    if (debug_threads)
      debug_printf ("Writing resume reply for %s:%d\n",
  		  target_pid_to_str (ptid), status->kind);
@@ -1100,8 +1109,8 @@  prepare_resume_reply (char *buf, ptid_t ptid,
  	const char **regp;
  	struct regcache *regcache;

-	if ((status->kind == TARGET_WAITKIND_FORKED && report_fork_events)
-	    || (status->kind == TARGET_WAITKIND_VFORKED && report_vfork_events))
+	if ((status->kind == TARGET_WAITKIND_FORKED && cs->report_fork_events)
+	    || (status->kind == TARGET_WAITKIND_VFORKED && 
cs->report_vfork_events))
  	  {
  	    enum gdb_signal signal = GDB_SIGNAL_TRAP;
  	    const char *event = (status->kind == TARGET_WAITKIND_FORKED
@@ -1112,13 +1121,13 @@  prepare_resume_reply (char *buf, ptid_t ptid,
  	    buf = write_ptid (buf, status->value.related_pid);
  	    strcat (buf, ";");
  	  }
-	else if (status->kind == TARGET_WAITKIND_VFORK_DONE && 
report_vfork_events)
+	else if (status->kind == TARGET_WAITKIND_VFORK_DONE && 
cs->report_vfork_events)
  	  {
  	    enum gdb_signal signal = GDB_SIGNAL_TRAP;

  	    sprintf (buf, "T%02xvforkdone:;", signal);
  	  }
-	else if (status->kind == TARGET_WAITKIND_EXECD && report_exec_events)
+	else if (status->kind == TARGET_WAITKIND_EXECD && cs->report_exec_events)
  	  {
  	    enum gdb_signal signal = GDB_SIGNAL_TRAP;
  	    const char *event = "exec";
@@ -1138,7 +1147,7 @@  prepare_resume_reply (char *buf, ptid_t ptid,
  	    buf += strlen (buf);
  	  }
  	else if (status->kind == TARGET_WAITKIND_THREAD_CREATED
-		 && report_thread_events)
+		 && cs->report_thread_events)
  	  {
  	    enum gdb_signal signal = GDB_SIGNAL_TRAP;

@@ -1159,13 +1168,13 @@  prepare_resume_reply (char *buf, ptid_t ptid,

  	buf += strlen (buf);

-	saved_thread = current_thread;
+	saved_thread = cs->ss->current_thread;

  	switch_to_thread (ptid);

  	regp = current_target_desc ()->expedite_regs;

-	regcache = get_thread_regcache (current_thread, 1);
+	regcache = get_thread_regcache (cs->ss->current_thread, 1);

  	if (the_target->stopped_by_watchpoint != NULL
  	    && (*the_target->stopped_by_watchpoint) ())
@@ -1186,12 +1195,12 @@  prepare_resume_reply (char *buf, ptid_t ptid,
  	      *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
  	    *buf++ = ';';
  	  }
-	else if (swbreak_feature && target_stopped_by_sw_breakpoint ())
+	else if (cs->swbreak_feature && target_stopped_by_sw_breakpoint ())
  	  {
  	    sprintf (buf, "swbreak:;");
  	    buf += strlen (buf);
  	  }
-	else if (hwbreak_feature && target_stopped_by_hw_breakpoint ())
+	else if (cs->hwbreak_feature && target_stopped_by_hw_breakpoint ())
  	  {
  	    sprintf (buf, "hwbreak:;");
  	    buf += strlen (buf);
@@ -1219,13 +1228,13 @@  prepare_resume_reply (char *buf, ptid_t ptid,
  	       in GDB will claim this event belongs to inferior_ptid
  	       if we do not specify a thread, and there's no way for
  	       gdbserver to know what inferior_ptid is.  */
-	    if (1 || !ptid_equal (general_thread, ptid))
+	    if (1 || !ptid_equal (cs->ss->general_thread, ptid))
  	      {
  		int core = -1;
  		/* In non-stop, don't change the general thread behind
  		   GDB's back.  */
-		if (!non_stop)
-		  general_thread = ptid;
+		if (!cs->non_stop)
+		  cs->ss->general_thread = ptid;
  		sprintf (buf, "thread:");
  		buf += strlen (buf);
  		buf = write_ptid (buf, ptid);
@@ -1252,18 +1261,18 @@  prepare_resume_reply (char *buf, ptid_t ptid,
  	    dlls_changed = 0;
  	  }

-	current_thread = saved_thread;
+	cs->ss->current_thread = saved_thread;
        }
        break;
      case TARGET_WAITKIND_EXITED:
-      if (multi_process)
+      if (cs->multi_process)
  	sprintf (buf, "W%x;process:%x",
  		 status->value.integer, ptid_get_pid (ptid));
        else
  	sprintf (buf, "W%02x", status->value.integer);
        break;
      case TARGET_WAITKIND_SIGNALLED:
-      if (multi_process)
+      if (cs->multi_process)
  	sprintf (buf, "X%x;process:%x",
  		 status->value.sig, ptid_get_pid (ptid));
        else
@@ -1435,6 +1444,7 @@  clear_symbol_cache (struct sym_cache **symcache_p)
  int
  look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
  {
+  client_state *cs = get_client_state();
    char *p, *q;
    int len;
    struct sym_cache *sym;
@@ -1456,14 +1466,14 @@  look_up_one_symbol (const char *name, CORE_ADDR 
*addrp, int may_ask_gdb)
      return 0;

    /* Send the request.  */
-  strcpy (own_buf, "qSymbol:");
-  bin2hex ((const gdb_byte *) name, own_buf + strlen ("qSymbol:"),
+  strcpy (cs->own_buf, "qSymbol:");
+  bin2hex ((const gdb_byte *) name, cs->own_buf + strlen ("qSymbol:"),
  	  strlen (name));
-  if (putpkt (own_buf) < 0)
+  if (putpkt (cs->own_buf) < 0)
      return -1;

    /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
-  len = getpkt (own_buf);
+  len = getpkt (cs->own_buf);
    if (len < 0)
      return -1;

@@ -1474,45 +1484,45 @@  look_up_one_symbol (const char *name, CORE_ADDR 
*addrp, int may_ask_gdb)
       while it figures out the address of the symbol.  */
    while (1)
      {
-      if (own_buf[0] == 'm')
+      if (cs->own_buf[0] == 'm')
  	{
  	  CORE_ADDR mem_addr;
-	  unsigned char *mem_buf;
+	  unsigned char *mem_buffer;
  	  unsigned int mem_len;

-	  decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
-	  mem_buf = (unsigned char *) xmalloc (mem_len);
-	  if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-	    bin2hex (mem_buf, own_buf, mem_len);
+	  decode_m_packet (&cs->own_buf[1], &mem_addr, &mem_len);
+	  mem_buffer = (unsigned char *) xmalloc (mem_len);
+	  if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	    bin2hex (mem_buffer, cs->own_buf, mem_len);
  	  else
-	    write_enn (own_buf);
-	  free (mem_buf);
-	  if (putpkt (own_buf) < 0)
+	    write_enn (cs->own_buf);
+	  free (mem_buffer);
+	  if (putpkt (cs->own_buf) < 0)
  	    return -1;
  	}
-      else if (own_buf[0] == 'v')
+      else if (cs->own_buf[0] == 'v')
  	{
  	  int new_len = -1;
-	  handle_v_requests (own_buf, len, &new_len);
+	  handle_v_requests (cs->own_buf, len, &new_len);
  	  if (new_len != -1)
-	    putpkt_binary (own_buf, new_len);
+	    putpkt_binary (cs->own_buf, new_len);
  	  else
-	    putpkt (own_buf);
+	    putpkt (cs->own_buf);
  	}
        else
  	break;
-      len = getpkt (own_buf);
+      len = getpkt (cs->own_buf);
        if (len < 0)
  	return -1;
      }

-  if (!startswith (own_buf, "qSymbol:"))
+  if (!startswith (cs->own_buf, "qSymbol:"))
      {
-      warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf);
+      warning ("Malformed response to qSymbol, ignoring: %s\n", 
cs->own_buf);
        return -1;
      }

-  p = own_buf + strlen ("qSymbol:");
+  p = cs->own_buf + strlen ("qSymbol:");
    q = p;
    while (*q && *q != ':')
      q++;
@@ -1548,17 +1558,18 @@  look_up_one_symbol (const char *name, CORE_ADDR 
*addrp, int may_ask_gdb)
  int
  relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
  {
+  client_state *cs = get_client_state();
    int len;
    ULONGEST written = 0;

    /* Send the request.  */
-  sprintf (own_buf, "qRelocInsn:%s;%s", paddress (oldloc),
+  sprintf (cs->own_buf, "qRelocInsn:%s;%s", paddress (oldloc),
  	   paddress (*to));
-  if (putpkt (own_buf) < 0)
+  if (putpkt (cs->own_buf) < 0)
      return -1;

    /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
-  len = getpkt (own_buf);
+  len = getpkt (cs->own_buf);
    if (len < 0)
      return -1;

@@ -1566,61 +1577,61 @@  relocate_instruction (CORE_ADDR *to, CORE_ADDR 
oldloc)
       wait for the qRelocInsn "response".  That requires re-entering
       the main loop.  For now, this is an adequate approximation; allow
       GDB to access memory.  */
-  while (own_buf[0] == 'm' || own_buf[0] == 'M' || own_buf[0] == 'X')
+  while (cs->own_buf[0] == 'm' || cs->own_buf[0] == 'M' || 
cs->own_buf[0] == 'X')
      {
        CORE_ADDR mem_addr;
-      unsigned char *mem_buf = NULL;
+      unsigned char *mem_buffer = NULL;
        unsigned int mem_len;

-      if (own_buf[0] == 'm')
+      if (cs->own_buf[0] == 'm')
  	{
-	  decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
-	  mem_buf = (unsigned char *) xmalloc (mem_len);
-	  if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-	    bin2hex (mem_buf, own_buf, mem_len);
+	  decode_m_packet (&cs->own_buf[1], &mem_addr, &mem_len);
+	  mem_buffer = (unsigned char *) xmalloc (mem_len);
+	  if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	    bin2hex (mem_buffer, cs->own_buf, mem_len);
  	  else
-	    write_enn (own_buf);
+	    write_enn (cs->own_buf);
  	}
-      else if (own_buf[0] == 'X')
+      else if (cs->own_buf[0] == 'X')
  	{
-	  if (decode_X_packet (&own_buf[1], len - 1, &mem_addr,
-			       &mem_len, &mem_buf) < 0
-	      || write_inferior_memory (mem_addr, mem_buf, mem_len) != 0)
-	    write_enn (own_buf);
+	  if (decode_X_packet (&cs->own_buf[1], len - 1, &mem_addr,
+			       &mem_len, &mem_buffer) < 0
+	      || write_inferior_memory (mem_addr, mem_buffer, mem_len) != 0)
+	    write_enn (cs->own_buf);
  	  else
-	    write_ok (own_buf);
+	    write_ok (cs->own_buf);
  	}
        else
  	{
-	  decode_M_packet (&own_buf[1], &mem_addr, &mem_len, &mem_buf);
-	  if (write_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-	    write_ok (own_buf);
+	  decode_M_packet (&cs->own_buf[1], &mem_addr, &mem_len, &mem_buffer);
+	  if (write_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	    write_ok (cs->own_buf);
  	  else
-	    write_enn (own_buf);
+	    write_enn (cs->own_buf);
  	}
-      free (mem_buf);
-      if (putpkt (own_buf) < 0)
+      free (mem_buffer);
+      if (putpkt (cs->own_buf) < 0)
  	return -1;
-      len = getpkt (own_buf);
+      len = getpkt (cs->own_buf);
        if (len < 0)
  	return -1;
      }

-  if (own_buf[0] == 'E')
+  if (cs->own_buf[0] == 'E')
      {
        warning ("An error occurred while relocating an instruction: %s\n",
-	       own_buf);
+	       cs->own_buf);
        return -1;
      }

-  if (!startswith (own_buf, "qRelocInsn:"))
+  if (!startswith (cs->own_buf, "qRelocInsn:"))
      {
        warning ("Malformed response to qRelocInsn, ignoring: %s\n",
-	       own_buf);
+	       cs->own_buf);
        return -1;
      }

-  unpack_varlen_hex (own_buf + strlen ("qRelocInsn:"), &written);
+  unpack_varlen_hex (cs->own_buf + strlen ("qRelocInsn:"), &written);

    *to += written;
    return 0;
diff --git a/gdb/gdbserver/remote-utils.h b/gdb/gdbserver/remote-utils.h
index c64807f406e..8714791e605 100644
--- a/gdb/gdbserver/remote-utils.h
+++ b/gdb/gdbserver/remote-utils.h
@@ -19,10 +19,7 @@ 
  #ifndef REMOTE_UTILS_H
  #define REMOTE_UTILS_H

-extern int remote_debug;
-extern int noack_mode;
-extern int transport_is_reliable;
-
+int get_remote_desc (void);
  int gdb_connected (void);

  #define STDIO_CONNECTION_NAME "stdio"
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 9d12ce6f706..261d28a5271 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -66,63 +66,6 @@  static gdb_environ our_environ;

  int startup_with_shell = 1;

-/* The thread set with an `Hc' packet.  `Hc' is deprecated in favor of
-   `vCont'.  Note the multi-process extensions made `vCont' a
-   requirement, so `Hc pPID.TID' is pretty much undefined.  So
-   CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for
-   resuming all threads of the process (again, `Hc' isn't used for
-   multi-process), or a specific thread ptid_t.  */
-ptid_t cont_thread;
-
-/* The thread set with an `Hg' packet.  */
-ptid_t general_thread;
-
-int server_waiting;
-
-static int extended_protocol;
-static int response_needed;
-static int exit_requested;
-
-/* --once: Exit after the first connection has closed.  */
-int run_once;
-
-int multi_process;
-int report_fork_events;
-int report_vfork_events;
-int report_exec_events;
-int report_thread_events;
-
-/* Whether to report TARGET_WAITKING_NO_RESUMED events.  */
-static int report_no_resumed;
-
-int non_stop;
-int swbreak_feature;
-int hwbreak_feature;
-
-/* True if the "vContSupported" feature is active.  In that case, GDB
-   wants us to report whether single step is supported in the reply to
-   "vCont?" packet.  */
-static int vCont_supported;
-
-/* Whether we should attempt to disable the operating system's address
-   space randomization feature before starting an inferior.  */
-int disable_randomization = 1;
-
-static char *program_name = NULL;
-static std::vector<char *> program_args;
-static std::string wrapper_argv;
-
-int pass_signals[GDB_SIGNAL_LAST];
-int program_signals[GDB_SIGNAL_LAST];
-int program_signals_p;
-
-/* The PID of the originally created or attached inferior.  Used to
-   send signals to the process when GDB sends us an asynchronous interrupt
-   (user hitting Control-C in the client), and to wait for the child to 
exit
-   when no longer debugging it.  */
-
-unsigned long signal_pid;
-
  /* Set if you want to disable optional thread related packets support
     in gdbserver, for the sake of testing GDB against stubs that don't
     support them.  */
@@ -131,13 +74,6 @@  int disable_packet_Tthread;
  int disable_packet_qC;
  int disable_packet_qfThreadInfo;

-/* Last status reported to GDB.  */
-struct target_waitstatus last_status;
-ptid_t last_ptid;
-
-char *own_buf;
-static unsigned char *mem_buf;
-
  /* A sub-class of 'struct notif_event' for stop, holding information
     relative to a single stop reply.  We keep a queue of these to
     push to GDB in non-stop mode.  */
@@ -159,6 +95,167 @@  static struct btrace_config current_btrace_conf;

  DEFINE_QUEUE_P (notif_event_p);

+static struct multi_client_states client_states;
+
+
+void dump_client_states (void) {
+  std::map<gdb_fildes_t,client_state*>::iterator it;
+  it = client_states.cs.begin();
+  for (it = client_states.cs.begin(); it != client_states.cs.end(); it++)
+    {
+      gdb_fildes_t cfd = it->first;
+      client_state *cs = it->second;
+      printf ("%d %#lx %ld %d %d\n", cfd, (unsigned long) cs, 
(long)cs->ss->signal_pid, cs->ss->last_status.kind, 
cs->ss->last_status.value.sig);
+    }
+}
+
+
+multi_client_states*
+get_client_states (void)
+{
+  return &client_states;
+}
+
+
+client_state*
+get_client_state (void)
+{
+  return client_states.get_client_state();
+}
+
+
+client_state::client_state (gdb_fildes_t fd, client_state *csidx)
+{
+  client_state *cs = get_client_state();
+  file_desc = fd;
+  attached_to_client = csidx->attached_to_client;
+  catch_syscalls = csidx->catch_syscalls;
+  extended_protocol = csidx->extended_protocol;
+  response_needed = csidx->response_needed;
+  exit_requested = csidx->exit_requested;
+  run_once = csidx->run_once;
+  multi_process = csidx->multi_process;
+  report_fork_events = csidx->report_fork_events;
+  report_vfork_events = csidx->report_vfork_events;
+  report_exec_events = csidx->report_exec_events;
+  report_thread_events = csidx->report_thread_events;
+  report_no_resumed = csidx->report_no_resumed;
+  non_stop = csidx->non_stop;
+  swbreak_feature = csidx->swbreak_feature;
+  hwbreak_feature = csidx->hwbreak_feature;
+  vCont_supported = csidx->vCont_supported;
+  disable_randomization = csidx->disable_randomization;
+  program_name = csidx->program_name;
+  program_args = csidx->program_args;
+  wrapper_argv = csidx->wrapper_argv;
+  remote_debug = csidx->remote_debug;
+  noack_mode = csidx->noack_mode;
+  transport_is_reliable = csidx->transport_is_reliable;
+  ss = new (server_state);
+  ss->mem_buf = csidx->ss->mem_buf;
+  ss->readchar_bufcnt = 0;
+  packet_type = other_packet;
+  last_packet_type = other_packet;
+  notify_buffer = NULL;
+  own_buf = (char*) xmalloc (PBUFSIZ + 1);
+  ss->attach_count = 0;
+  ss->cont_thread = null_ptid;
+  ss->general_thread = null_ptid;
+  ss->signal_pid = csidx->ss->signal_pid;
+  ss->last_ptid = null_ptid;
+  ss->last_status = csidx->ss->last_status;
+  if (csidx->file_desc < 0)
+    {
+      ss->all_processes = cs->ss->all_processes;
+      ss->all_threads = cs->ss->all_threads;
+      ss->current_thread = cs->ss->current_thread;
+    }
+  else
+    ss->current_thread = NULL;
+}
+
+
+/* Add a new client state for FD or return if found */
+
+client_state *
+multi_client_states::set_client_state (gdb_fildes_t fd)
+{
+/* States:
+ * fd = -1 add initial client state
+ * fd =  F add client state for fd F
+ */
+
+  client_state *csidx, *cs;
+
+  /* add/return initial client state */
+  if (fd == -1)
+    {
+      if (client_states.cs.empty())
+	{
+	  client_states.cs[fd] = new (client_state);
+	  client_states.cs[fd]->ss = new (server_state);
+	  client_states.cs[fd]->file_desc = fd;
+	}
+      client_states.current_cs = client_states.cs[fd];
+      return client_states.cs[fd];
+    }
+
+  /* add/return client state for fd F */
+
+  std::map<gdb_fildes_t,client_state*>::iterator it;
+  it = client_states.cs.find(fd);
+  if (it != client_states.cs.end())
+    {
+      client_states.current_cs = it->second;
+      return it->second;
+    }
+  else
+    csidx = client_states.cs.rbegin()->second;
+
+  /* add client state S for fd F */
+  client_states.cs[fd] = cs = new client_state (fd, csidx);
+  cs->file_desc = fd;
+  client_states.set_current_client (cs);
+  return cs;
+}
+
+
+/* Remove the client state corresponding to fd */
+
+void
+multi_client_states::delete_client_state (gdb_fildes_t fd)
+{
+  client_state *cs, *previous_cs = NULL;
+  std::map<gdb_fildes_t,client_state*>::iterator it;
+
+  for (it = client_states.cs.begin(); it != client_states.cs.end(); ++it)
+    {
+      server_state *ss= NULL;
+
+      cs = it->second;
+
+      if (it->first == fd)
+	{
+	  client_states.current_cs = previous_cs;
+	  if (cs->notify_buffer)
+	    xfree (cs->notify_buffer);
+	  free (cs->own_buf);
+	  delete (cs->ss);
+	  delete (cs);
+	  client_states.cs.erase (fd);
+	}
+      previous_cs = cs;
+    }
+}
+
+
+#if 0
+static int
+queue_stop_reply_callback (thread_info *thread, void *arg);
+#endif
+
+/**********************************/
+
  /* Put a stop reply to the stop reply queue.  */

  static void
@@ -257,7 +354,9 @@  target_running (void)
  const char *
  get_exec_wrapper ()
  {
-  return !wrapper_argv.empty () ? wrapper_argv.c_str () : NULL;
+  client_state *cs = get_client_state();
+
+  return !cs->wrapper_argv.empty () ? cs->wrapper_argv.c_str () : NULL;
  }

  /* See common/common-inferior.h.  */
@@ -265,10 +364,12 @@  get_exec_wrapper ()
  char *
  get_exec_file (int err)
  {
-  if (err && program_name == NULL)
+  client_state *cs = get_client_state();
+
+  if (err && cs->program_name == NULL)
      error (_("No executable file specified."));

-  return program_name;
+  return cs->program_name;
  }

  /* See server.h.  */
@@ -282,6 +383,8 @@  get_environ ()
  static int
  attach_inferior (int pid)
  {
+  client_state *cs = get_client_state();
+
    /* myattach should return -1 if attaching is unsupported,
       0 if it succeeded, and call error() otherwise.  */

@@ -294,28 +397,26 @@  attach_inferior (int pid)
    /* FIXME - It may be that we should get the SIGNAL_PID from the
       attach function, so that it can be the main thread instead of
       whichever we were told to attach to.  */
-  signal_pid = pid;
+  cs->ss->signal_pid = pid;

-  if (!non_stop)
+  if (!cs->non_stop)
      {
-      last_ptid = mywait (pid_to_ptid (pid), &last_status, 0, 0);
+      cs->ss->last_ptid = mywait (pid_to_ptid (pid), 
&cs->ss->last_status, 0, 0);

        /* GDB knows to ignore the first SIGSTOP after attaching to a 
running
  	 process using the "attach" command, but this is different; it's
  	 just using "target remote".  Pretend it's just starting up.  */
-      if (last_status.kind == TARGET_WAITKIND_STOPPED
-	  && last_status.value.sig == GDB_SIGNAL_STOP)
-	last_status.value.sig = GDB_SIGNAL_TRAP;
+      if (cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED
+	  && cs->ss->last_status.value.sig == GDB_SIGNAL_STOP)
+	cs->ss->last_status.value.sig = GDB_SIGNAL_TRAP;

-      current_thread->last_resume_kind = resume_stop;
-      current_thread->last_status = last_status;
+      cs->ss->current_thread->last_resume_kind = resume_stop;
+      cs->ss->current_thread->last_status = cs->ss->last_status;
      }

    return 0;
  }

-extern int remote_debug;
-
  /* Decode a qXfer read request.  Return 0 if everything looks OK,
     or -1 otherwise.  */

@@ -431,6 +532,7 @@  handle_btrace_disable (struct thread_info *thread)
  static int
  handle_btrace_general_set (char *own_buf)
  {
+  client_state *cs = get_client_state();
    struct thread_info *thread;
    const char *err;
    char *op;
@@ -440,14 +542,14 @@  handle_btrace_general_set (char *own_buf)

    op = own_buf + strlen ("Qbtrace:");

-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (ptid_equal (cs->ss->general_thread, null_ptid)
+      || ptid_equal (cs->ss->general_thread, minus_one_ptid))
      {
        strcpy (own_buf, "E.Must select a single thread.");
        return -1;
      }

-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs->ss->general_thread);
    if (thread == NULL)
      {
        strcpy (own_buf, "E.No such thread.");
@@ -478,6 +580,7 @@  handle_btrace_general_set (char *own_buf)
  static int
  handle_btrace_conf_general_set (char *own_buf)
  {
+  client_state *cs = get_client_state();
    struct thread_info *thread;
    char *op;

@@ -486,14 +589,14 @@  handle_btrace_conf_general_set (char *own_buf)

    op = own_buf + strlen ("Qbtrace-conf:");

-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (ptid_equal (cs->ss->general_thread, null_ptid)
+      || ptid_equal (cs->ss->general_thread, minus_one_ptid))
      {
        strcpy (own_buf, "E.Must select a single thread.");
        return -1;
      }

-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs->ss->general_thread);
    if (thread == NULL)
      {
        strcpy (own_buf, "E.No such thread.");
@@ -545,6 +648,8 @@  handle_btrace_conf_general_set (char *own_buf)
  static void
  handle_general_set (char *own_buf)
  {
+  client_state *cs = get_client_state();
+
    if (startswith (own_buf, "QPassSignals:"))
      {
        int numsigs = (int) GDB_SIGNAL_LAST, i;
@@ -556,7 +661,7 @@  handle_general_set (char *own_buf)
  	{
  	  if (i == cursig)
  	    {
-	      pass_signals[i] = 1;
+	      cs->pass_signals[i] = 1;
  	      if (*p == '\0')
  		/* Keep looping, to clear the remaining signals.  */
  		cursig = -1;
@@ -564,7 +669,7 @@  handle_general_set (char *own_buf)
  		p = decode_address_to_semicolon (&cursig, p);
  	    }
  	  else
-	    pass_signals[i] = 0;
+	    cs->pass_signals[i] = 0;
  	}
        strcpy (own_buf, "OK");
        return;
@@ -576,14 +681,14 @@  handle_general_set (char *own_buf)
        const char *p = own_buf + strlen ("QProgramSignals:");
        CORE_ADDR cursig;

-      program_signals_p = 1;
+      cs->program_signals_p = 1;

        p = decode_address_to_semicolon (&cursig, p);
        for (i = 0; i < numsigs; i++)
  	{
  	  if (i == cursig)
  	    {
-	      program_signals[i] = 1;
+	      cs->program_signals[i] = 1;
  	      if (*p == '\0')
  		/* Keep looping, to clear the remaining signals.  */
  		cursig = -1;
@@ -591,7 +696,7 @@  handle_general_set (char *own_buf)
  		p = decode_address_to_semicolon (&cursig, p);
  	    }
  	  else
-	    program_signals[i] = 0;
+	    cs->program_signals[i] = 0;
  	}
        strcpy (own_buf, "OK");
        return;
@@ -661,7 +766,7 @@  handle_general_set (char *own_buf)
        std::string final_var = hex2str (p);
        std::string var_name, var_value;

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf (_("[QEnvironmentHexEncoded received '%s']\n"), p);
  	  debug_printf (_("[Environment variable to be set: '%s']\n"),
@@ -692,7 +797,7 @@  handle_general_set (char *own_buf)
        const char *p = own_buf + sizeof ("QEnvironmentUnset:") - 1;
        std::string varname = hex2str (p);

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf (_("[QEnvironmentUnset received '%s']\n"), p);
  	  debug_printf (_("[Environment variable to be unset: '%s']\n"),
@@ -708,13 +813,13 @@  handle_general_set (char *own_buf)

    if (strcmp (own_buf, "QStartNoAckMode") == 0)
      {
-      if (remote_debug)
+      if (cs->remote_debug)
  	{
  	  debug_printf ("[noack mode enabled]\n");
  	  debug_flush ();
  	}

-      noack_mode = 1;
+      cs->noack_mode = 1;
        write_ok (own_buf);
        return;
      }
@@ -747,9 +852,9 @@  handle_general_set (char *own_buf)
  	  return;
  	}

-      non_stop = req;
+      cs->non_stop = req;

-      if (remote_debug)
+      if (cs->remote_debug)
  	debug_printf ("[%s mode enabled]\n", req_str);

        write_ok (own_buf);
@@ -762,11 +867,11 @@  handle_general_set (char *own_buf)
        ULONGEST setting;

        unpack_varlen_hex (packet, &setting);
-      disable_randomization = setting;
+      cs->disable_randomization = setting;

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
-	  debug_printf (disable_randomization
+	  debug_printf (cs->disable_randomization
  			? "[address space randomization disabled]\n"
  			: "[address space randomization enabled]\n");
  	}
@@ -797,7 +902,7 @@  handle_general_set (char *own_buf)

        /* Update the flag.  */
        use_agent = req;
-      if (remote_debug)
+      if (cs->remote_debug)
  	debug_printf ("[%s agent]\n", req ? "Enable" : "Disable");
        write_ok (own_buf);
        return;
@@ -829,11 +934,11 @@  handle_general_set (char *own_buf)
  	  return;
  	}

-      report_thread_events = (req == TRIBOOL_TRUE);
+      cs->report_thread_events = (req == TRIBOOL_TRUE);

-      if (remote_debug)
+      if (cs->remote_debug)
  	{
-	  const char *req_str = report_thread_events ? "enabled" : "disabled";
+	  const char *req_str = cs->report_thread_events ? "enabled" : "disabled";

  	  debug_printf ("[thread events are now %s]\n", req_str);
  	}
@@ -859,7 +964,7 @@  handle_general_set (char *own_buf)
  	  return;
  	}

-      if (remote_debug)
+      if (cs->remote_debug)
  	debug_printf (_("[Inferior will %s started with shell]"),
  		      startup_with_shell ? "be" : "not be");

@@ -877,7 +982,7 @@  handle_general_set (char *own_buf)

  	  set_inferior_cwd (path.c_str ());

-	  if (remote_debug)
+	  if (cs->remote_debug)
  	    debug_printf (_("[Set the inferior's current directory to %s]\n"),
  			  path.c_str ());
  	}
@@ -887,7 +992,7 @@  handle_general_set (char *own_buf)
  	     previously set cwd for the inferior.  */
  	  set_inferior_cwd (NULL);

-	  if (remote_debug)
+	  if (cs->remote_debug)
  	    debug_printf (_("\
  [Unset the inferior's current directory; will use gdbserver's cwd]\n"));
  	}
@@ -1189,11 +1294,12 @@  handle_search_memory (char *own_buf, int packet_len)
  static void
  handle_detach (char *own_buf)
  {
+  client_state *cs = get_client_state();
    require_running_or_return (own_buf);

    int pid;

-  if (multi_process)
+  if (cs->multi_process)
      {
        /* skip 'D;' */
        pid = strtol (&own_buf[2], NULL, 16);
@@ -1226,12 +1332,12 @@  handle_detach (char *own_buf)
  	 events simultaneously.  There's also no point either in
  	 having the target stop all threads, when we're going to
  	 pass signals down without informing GDB.  */
-      if (!non_stop)
+      if (!cs->non_stop)
  	{
  	  if (debug_threads)
  	    debug_printf ("Forcing non-stop mode\n");

-	  non_stop = 1;
+	  cs->non_stop = 1;
  	  start_non_stop (1);
  	}

@@ -1253,16 +1359,16 @@  handle_detach (char *own_buf)
        discard_queued_stop_replies (pid_to_ptid (pid));
        write_ok (own_buf);

-      if (extended_protocol || target_running ())
+      if (cs->extended_protocol || target_running ())
  	{
  	  /* There is still at least one inferior remaining or
  	     we are in extended mode, so don't terminate gdbserver,
  	     and instead treat this like a normal program exit.  */
-	  last_status.kind = TARGET_WAITKIND_EXITED;
-	  last_status.value.integer = 0;
-	  last_ptid = pid_to_ptid (pid);
+	  cs->ss->last_status.kind = TARGET_WAITKIND_EXITED;
+	  cs->ss->last_status.value.integer = 0;
+	  cs->ss->last_ptid = pid_to_ptid (pid);

-	  current_thread = NULL;
+	  cs->ss->current_thread = NULL;
  	}
        else
  	{
@@ -1355,6 +1461,8 @@  parse_debug_format_options (const char *arg, int 
is_monitor)
  static void
  handle_monitor_command (char *mon, char *own_buf)
  {
+  client_state *cs = get_client_state();
+
    if (strcmp (mon, "set debug 1") == 0)
      {
        debug_threads = 1;
@@ -1377,12 +1485,12 @@  handle_monitor_command (char *mon, char *own_buf)
      }
    else if (strcmp (mon, "set remote-debug 1") == 0)
      {
-      remote_debug = 1;
+      cs->remote_debug = 1;
        monitor_output ("Protocol debug output enabled.\n");
      }
    else if (strcmp (mon, "set remote-debug 0") == 0)
      {
-      remote_debug = 0;
+      cs->remote_debug = 0;
        monitor_output ("Protocol debug output disabled.\n");
      }
    else if (startswith (mon, "set debug-format "))
@@ -1401,7 +1509,7 @@  handle_monitor_command (char *mon, char *own_buf)
    else if (strcmp (mon, "help") == 0)
      monitor_show_help ();
    else if (strcmp (mon, "exit") == 0)
-    exit_requested = 1;
+    cs->exit_requested = 1;
    else
      {
        monitor_output ("Unknown monitor command.\n\n");
@@ -1441,10 +1549,12 @@  handle_qxfer_auxv (const char *annex,
  		   gdb_byte *readbuf, const gdb_byte *writebuf,
  		   ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
+
    if (the_target->read_auxv == NULL || writebuf != NULL)
      return -2;

-  if (annex[0] != '\0' || current_thread == NULL)
+  if (annex[0] != '\0' || cs->ss->current_thread == NULL)
      return -1;

    return (*the_target->read_auxv) (offset, readbuf, len);
@@ -1457,6 +1567,7 @@  handle_qxfer_exec_file (const char *annex,
  			gdb_byte *readbuf, const gdb_byte *writebuf,
  			ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
    char *file;
    ULONGEST pid;
    int total_len;
@@ -1466,10 +1577,10 @@  handle_qxfer_exec_file (const char *annex,

    if (annex[0] == '\0')
      {
-      if (current_thread == NULL)
+      if (cs->ss->current_thread == NULL)
  	return -1;

-      pid = pid_of (current_thread);
+      pid = pid_of (cs->ss->current_thread);
      }
    else
      {
@@ -1537,10 +1648,12 @@  handle_qxfer_libraries (const char *annex,
  			gdb_byte *readbuf, const gdb_byte *writebuf,
  			ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
+
    if (writebuf != NULL)
      return -2;

-  if (annex[0] != '\0' || current_thread == NULL)
+  if (annex[0] != '\0' || cs->ss->current_thread == NULL)
      return -1;

    std::string document = "<library-list version=\"1.0\">\n";
@@ -1570,10 +1683,12 @@  handle_qxfer_libraries_svr4 (const char *annex,
  			     gdb_byte *readbuf, const gdb_byte *writebuf,
  			     ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
+
    if (writebuf != NULL)
      return -2;

-  if (current_thread == NULL || the_target->qxfer_libraries_svr4 == NULL)
+  if (cs->ss->current_thread == NULL || 
the_target->qxfer_libraries_svr4 == NULL)
      return -1;

    return the_target->qxfer_libraries_svr4 (annex, readbuf, writebuf, 
offset, len);
@@ -1599,10 +1714,12 @@  handle_qxfer_siginfo (const char *annex,
  		      gdb_byte *readbuf, const gdb_byte *writebuf,
  		      ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
+
    if (the_target->qxfer_siginfo == NULL)
      return -2;

-  if (annex[0] != '\0' || current_thread == NULL)
+  if (annex[0] != '\0' || cs->ss->current_thread == NULL)
      return -1;

    return (*the_target->qxfer_siginfo) (annex, readbuf, writebuf, 
offset, len);
@@ -1615,10 +1732,12 @@  handle_qxfer_spu (const char *annex,
  		  gdb_byte *readbuf, const gdb_byte *writebuf,
  		  ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
+
    if (the_target->qxfer_spu == NULL)
      return -2;

-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      return -1;

    return (*the_target->qxfer_spu) (annex, readbuf, writebuf, offset, len);
@@ -1631,12 +1750,13 @@  handle_qxfer_statictrace (const char *annex,
  			  gdb_byte *readbuf, const gdb_byte *writebuf,
  			  ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
    ULONGEST nbytes;

    if (writebuf != NULL)
      return -2;

-  if (annex[0] != '\0' || current_thread == NULL || current_traceframe 
== -1)
+  if (annex[0] != '\0' || cs->ss->current_thread == NULL || 
current_traceframe == -1)
      return -1;

    if (traceframe_read_sdata (current_traceframe, offset,
@@ -1804,10 +1924,12 @@  static int
  handle_qxfer_fdpic (const char *annex, gdb_byte *readbuf,
  		    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
+
    if (the_target->read_loadmap == NULL)
      return -2;

-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      return -1;

    return (*the_target->read_loadmap) (annex, offset, readbuf, len);
@@ -1820,6 +1942,7 @@  handle_qxfer_btrace (const char *annex,
  		     gdb_byte *readbuf, const gdb_byte *writebuf,
  		     ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
    static struct buffer cache;
    struct thread_info *thread;
    enum btrace_read_type type;
@@ -1828,23 +1951,23 @@  handle_qxfer_btrace (const char *annex,
    if (the_target->read_btrace == NULL || writebuf != NULL)
      return -2;

-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (ptid_equal (cs->ss->general_thread, null_ptid)
+      || ptid_equal (cs->ss->general_thread, minus_one_ptid))
      {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (cs->own_buf, "E.Must select a single thread.");
        return -3;
      }

-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs->ss->general_thread);
    if (thread == NULL)
      {
-      strcpy (own_buf, "E.No such thread.");
+      strcpy (cs->own_buf, "E.No such thread.");
        return -3;
      }

    if (thread->btrace == NULL)
      {
-      strcpy (own_buf, "E.Btrace not enabled.");
+      strcpy (cs->own_buf, "E.Btrace not enabled.");
        return -3;
      }

@@ -1856,7 +1979,7 @@  handle_qxfer_btrace (const char *annex,
      type = BTRACE_READ_DELTA;
    else
      {
-      strcpy (own_buf, "E.Bad annex.");
+      strcpy (cs->own_buf, "E.Bad annex.");
        return -3;
      }

@@ -1867,7 +1990,7 @@  handle_qxfer_btrace (const char *annex,
        result = target_read_btrace (thread->btrace, &cache, type);
        if (result != 0)
  	{
-	  memcpy (own_buf, cache.buffer, cache.used_size);
+	  memcpy (cs->own_buf, cache.buffer, cache.used_size);
  	  return -3;
  	}
      }
@@ -1892,6 +2015,7 @@  handle_qxfer_btrace_conf (const char *annex,
  			  gdb_byte *readbuf, const gdb_byte *writebuf,
  			  ULONGEST offset, LONGEST len)
  {
+  client_state *cs = get_client_state();
    static struct buffer cache;
    struct thread_info *thread;
    int result;
@@ -1902,23 +2026,23 @@  handle_qxfer_btrace_conf (const char *annex,
    if (annex[0] != '\0')
      return -1;

-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (ptid_equal (cs->ss->general_thread, null_ptid)
+      || ptid_equal (cs->ss->general_thread, minus_one_ptid))
      {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (cs->own_buf, "E.Must select a single thread.");
        return -3;
      }

-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs->ss->general_thread);
    if (thread == NULL)
      {
-      strcpy (own_buf, "E.No such thread.");
+      strcpy (cs->own_buf, "E.No such thread.");
        return -3;
      }

    if (thread->btrace == NULL)
      {
-      strcpy (own_buf, "E.Btrace not enabled.");
+      strcpy (cs->own_buf, "E.Btrace not enabled.");
        return -3;
      }

@@ -1929,7 +2053,7 @@  handle_qxfer_btrace_conf (const char *annex,
        result = target_read_btrace_conf (thread->btrace, &cache);
        if (result != 0)
  	{
-	  memcpy (own_buf, cache.buffer, cache.used_size);
+	  memcpy (cs->own_buf, cache.buffer, cache.used_size);
  	  return -3;
  	}
      }
@@ -2142,6 +2266,7 @@  supported_btrace_packets (char *buf)
  static void
  handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
  {
+  client_state *cs = get_client_state();
    static std::list<thread_info *>::const_iterator thread_iter;

    /* Reply the current thread id.  */
@@ -2150,11 +2275,11 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
        ptid_t ptid;
        require_running_or_return (own_buf);

-      if (general_thread != null_ptid && general_thread != minus_one_ptid)
-	ptid = general_thread;
+      if (cs->ss->general_thread != null_ptid && cs->ss->general_thread 
!= minus_one_ptid)
+	ptid = cs->ss->general_thread;
        else
  	{
-	  thread_iter = all_threads.begin ();
+	  thread_iter = cs->ss->all_threads.begin ();
  	  ptid = (*thread_iter)->id;
  	}

@@ -2166,24 +2291,24 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)

    if (strcmp ("qSymbol::", own_buf) == 0)
      {
-      struct thread_info *save_thread = current_thread;
+      struct thread_info *save_thread = cs->ss->current_thread;

        /* For qSymbol, GDB only changes the current thread if the
  	 previous current thread was of a different process.  So if
  	 the previous thread is gone, we need to pick another one of
  	 the same process.  This can happen e.g., if we followed an
  	 exec in a non-leader thread.  */
-      if (current_thread == NULL)
+      if (cs->ss->current_thread == NULL)
  	{
-	  current_thread
-	    = find_any_thread_of_pid (ptid_get_pid (general_thread));
+	  cs->ss->current_thread
+	    = find_any_thread_of_pid (ptid_get_pid (cs->ss->general_thread));

  	  /* Just in case, if we didn't find a thread, then bail out
  	     instead of crashing.  */
-	  if (current_thread == NULL)
+	  if (cs->ss->current_thread == NULL)
  	    {
  	      write_enn (own_buf);
-	      current_thread = save_thread;
+	      cs->ss->current_thread = save_thread;
  	      return;
  	    }
  	}
@@ -2203,10 +2328,10 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
        if (target_supports_tracepoints ())
  	tracepoint_look_up_symbols ();

-      if (current_thread != NULL && the_target->look_up_symbols != NULL)
+      if (cs->ss->current_thread != NULL && the_target->look_up_symbols 
!= NULL)
  	(*the_target->look_up_symbols) ();

-      current_thread = save_thread;
+      cs->ss->current_thread = save_thread;

        strcpy (own_buf, "OK");
        return;
@@ -2217,7 +2342,7 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
        if (strcmp ("qfThreadInfo", own_buf) == 0)
  	{
  	  require_running_or_return (own_buf);
-	  thread_iter = all_threads.begin ();
+	  thread_iter = cs->ss->all_threads.begin ();

  	  *own_buf++ = 'm';
  	  ptid_t ptid = (*thread_iter)->id;
@@ -2229,7 +2354,7 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
        if (strcmp ("qsThreadInfo", own_buf) == 0)
  	{
  	  require_running_or_return (own_buf);
-	  if (thread_iter != all_threads.end ())
+	  if (thread_iter != cs->ss->all_threads.end ())
  	    {
  	      *own_buf++ = 'm';
  	      ptid_t ptid = (*thread_iter)->id;
@@ -2296,7 +2421,7 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
  		  /* GDB supports and wants multi-process support if
  		     possible.  */
  		  if (target_supports_multi_process ())
-		    multi_process = 1;
+		    cs->multi_process = 1;
  		}
  	      else if (strcmp (p, "qRelocInsn+") == 0)
  		{
@@ -2309,42 +2434,42 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
  		     by a software breakpoint and for us to handle PC
  		     adjustment if necessary on this target.  */
  		  if (target_supports_stopped_by_sw_breakpoint ())
-		    swbreak_feature = 1;
+		    cs->swbreak_feature = 1;
  		}
  	      else if (strcmp (p, "hwbreak+") == 0)
  		{
  		  /* GDB wants us to report whether a trap is caused
  		     by a hardware breakpoint.  */
  		  if (target_supports_stopped_by_hw_breakpoint ())
-		    hwbreak_feature = 1;
+		    cs->hwbreak_feature = 1;
  		}
  	      else if (strcmp (p, "fork-events+") == 0)
  		{
  		  /* GDB supports and wants fork events if possible.  */
  		  if (target_supports_fork_events ())
-		    report_fork_events = 1;
+		    cs->report_fork_events = 1;
  		}
  	      else if (strcmp (p, "vfork-events+") == 0)
  		{
  		  /* GDB supports and wants vfork events if possible.  */
  		  if (target_supports_vfork_events ())
-		    report_vfork_events = 1;
+		    cs->report_vfork_events = 1;
  		}
  	      else if (strcmp (p, "exec-events+") == 0)
  		{
  		  /* GDB supports and wants exec events if possible.  */
  		  if (target_supports_exec_events ())
-		    report_exec_events = 1;
+		    cs->report_exec_events = 1;
  		}
  	      else if (strcmp (p, "vContSupported+") == 0)
-		vCont_supported = 1;
+		cs->vCont_supported = 1;
  	      else if (strcmp (p, "QThreadEvents+") == 0)
  		;
  	      else if (strcmp (p, "no-resumed+") == 0)
  		{
  		  /* GDB supports and wants TARGET_WAITKIND_NO_RESUMED
  		     events.  */
-		  report_no_resumed = 1;
+		  cs->report_no_resumed = 1;
  		}
  	      else
  		{
@@ -2402,7 +2527,7 @@  handle_query (char *own_buf, int packet_len, int 
*new_packet_len_p)
  	 qXfer:feature:read at all, we will never be re-queried.  */
        strcat (own_buf, ";qXfer:features:read+");

-      if (transport_is_reliable)
+      if (cs->transport_is_reliable)
  	strcat (own_buf, ";QStartNoAckMode+");

        if (the_target->qxfer_osdata != NULL)
@@ -2713,13 +2838,15 @@  static int
  handle_pending_status (const struct thread_resume *resumption,
  		       struct thread_info *thread)
  {
+  client_state *cs = get_client_state();
+
    if (thread->status_pending_p)
      {
        thread->status_pending_p = 0;

-      last_status = thread->last_status;
-      last_ptid = thread->id;
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      cs->ss->last_status = thread->last_status;
+      cs->ss->last_ptid = thread->id;
+      prepare_resume_reply (cs->own_buf, cs->ss->last_ptid, 
&cs->ss->last_status);
        return 1;
      }
    return 0;
@@ -2839,7 +2966,9 @@  err:
  static void
  resume (struct thread_resume *actions, size_t num_actions)
  {
-  if (!non_stop)
+  client_state *cs = get_client_state();
+
+  if (!cs->non_stop)
      {
        /* Check if among the threads that GDB wants actioned, there's
  	 one with a pending status to report.  If so, skip actually
@@ -2860,38 +2989,38 @@  resume (struct thread_resume *actions, size_t 
num_actions)

    (*the_target->resume) (actions, num_actions);

-  if (non_stop)
-    write_ok (own_buf);
+  if (cs->non_stop)
+    write_ok (cs->own_buf);
    else
      {
-      last_ptid = mywait (minus_one_ptid, &last_status, 0, 1);
+      cs->ss->last_ptid = mywait (minus_one_ptid, &cs->ss->last_status, 
0, 1);

-      if (last_status.kind == TARGET_WAITKIND_NO_RESUMED
-	  && !report_no_resumed)
+      if (cs->ss->last_status.kind == TARGET_WAITKIND_NO_RESUMED
+	  && !cs->report_no_resumed)
  	{
  	  /* The client does not support this stop reply.  At least
  	     return error.  */
-	  sprintf (own_buf, "E.No unwaited-for children left.");
+	  sprintf (cs->own_buf, "E.No unwaited-for children left.");
  	  disable_async_io ();
  	  return;
  	}

-      if (last_status.kind != TARGET_WAITKIND_EXITED
-          && last_status.kind != TARGET_WAITKIND_SIGNALLED
-	  && last_status.kind != TARGET_WAITKIND_NO_RESUMED)
-	current_thread->last_status = last_status;
+      if (cs->ss->last_status.kind != TARGET_WAITKIND_EXITED
+          && cs->ss->last_status.kind != TARGET_WAITKIND_SIGNALLED
+	  && cs->ss->last_status.kind != TARGET_WAITKIND_NO_RESUMED)
+	cs->ss->current_thread->last_status = cs->ss->last_status;

        /* From the client's perspective, all-stop mode always stops all
  	 threads implicitly (and the target backend has already done
  	 so by now).  Tag all threads as "want-stopped", so we don't
  	 resume them implicitly without the client telling us to.  */
        gdb_wants_all_threads_stopped ();
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      prepare_resume_reply (cs->own_buf, cs->ss->last_ptid, 
&cs->ss->last_status);
        disable_async_io ();

-      if (last_status.kind == TARGET_WAITKIND_EXITED
-          || last_status.kind == TARGET_WAITKIND_SIGNALLED)
-        target_mourn_inferior (last_ptid);
+      if (cs->ss->last_status.kind == TARGET_WAITKIND_EXITED
+          || cs->ss->last_status.kind == TARGET_WAITKIND_SIGNALLED)
+        target_mourn_inferior (cs->ss->last_ptid);
      }
  }

@@ -2899,6 +3028,7 @@  resume (struct thread_resume *actions, size_t 
num_actions)
  static int
  handle_v_attach (char *own_buf)
  {
+  client_state *cs = get_client_state();
    int pid;

    pid = strtol (own_buf + 8, NULL, 16);
@@ -2910,7 +3040,7 @@  handle_v_attach (char *own_buf)
  	 notice on the GDB side.  */
        dlls_changed = 0;

-      if (non_stop)
+      if (cs->non_stop)
  	{
  	  /* In non-stop, we don't send a resume reply.  Stop events
  	     will follow up using the normal notification
@@ -2918,7 +3048,7 @@  handle_v_attach (char *own_buf)
  	  write_ok (own_buf);
  	}
        else
-	prepare_resume_reply (own_buf, last_ptid, &last_status);
+	prepare_resume_reply (own_buf, cs->ss->last_ptid, &cs->ss->last_status);

        return 1;
      }
@@ -2933,6 +3063,7 @@  handle_v_attach (char *own_buf)
  static int
  handle_v_run (char *own_buf)
  {
+  client_state *cs = get_client_state();
    char *p, *next_p;
    std::vector<char *> new_argv;
    char *new_program_name = NULL;
@@ -3023,7 +3154,7 @@  handle_v_run (char *own_buf)
      {
        /* GDB didn't specify a program to run.  Use the program from the
  	 last run with the new argument list.  */
-      if (program_name == NULL)
+      if (cs->program_name == NULL)
  	{
  	  write_enn (own_buf);
  	  free_vector_argv (new_argv);
@@ -3032,25 +3163,25 @@  handle_v_run (char *own_buf)
      }
    else
      {
-      xfree (program_name);
-      program_name = new_program_name;
+      xfree (cs->program_name);
+      cs->program_name = new_program_name;
      }

    /* Free the old argv and install the new one.  */
-  free_vector_argv (program_args);
-  program_args = new_argv;
+  free_vector_argv (cs->program_args);
+  cs->program_args = new_argv;

-  create_inferior (program_name, program_args);
+  create_inferior (cs->program_name, cs->program_args);

-  if (last_status.kind == TARGET_WAITKIND_STOPPED)
+  if (cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED)
      {
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      prepare_resume_reply (own_buf, cs->ss->last_ptid, 
&cs->ss->last_status);

        /* In non-stop, sending a resume reply doesn't set the general
  	 thread, but GDB assumes a vRun sets it (this is so GDB can
  	 query which is the main thread of the new inferior.  */
-      if (non_stop)
-	general_thread = last_ptid;
+      if (cs->non_stop)
+	cs->ss->general_thread = cs->ss->last_ptid;

        return 1;
      }
@@ -3065,18 +3196,19 @@  handle_v_run (char *own_buf)
  static int
  handle_v_kill (char *own_buf)
  {
+  client_state *cs = get_client_state();
    int pid;
    char *p = &own_buf[6];
-  if (multi_process)
+  if (cs->multi_process)
      pid = strtol (p, NULL, 16);
    else
-    pid = signal_pid;
+    pid = cs->ss->signal_pid;
    if (pid != 0 && kill_inferior (pid) == 0)
      {
-      last_status.kind = TARGET_WAITKIND_SIGNALLED;
-      last_status.value.sig = GDB_SIGNAL_KILL;
-      last_ptid = pid_to_ptid (pid);
-      discard_queued_stop_replies (last_ptid);
+      cs->ss->last_status.kind = TARGET_WAITKIND_SIGNALLED;
+      cs->ss->last_status.value.sig = GDB_SIGNAL_KILL;
+      cs->ss->last_ptid = pid_to_ptid (pid);
+      discard_queued_stop_replies (cs->ss->last_ptid);
        write_ok (own_buf);
        return 1;
      }
@@ -3091,6 +3223,8 @@  handle_v_kill (char *own_buf)
  void
  handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
  {
+  client_state *cs = get_client_state();
+
    if (!disable_packet_vCont)
      {
        if (strcmp (own_buf, "vCtrlC") == 0)
@@ -3112,7 +3246,7 @@  handle_v_requests (char *own_buf, int packet_len, 
int *new_packet_len)

  	  if (target_supports_hardware_single_step ()
  	      || target_supports_software_single_step ()
-	      || !vCont_supported)
+	      || !cs->vCont_supported)
  	    {
  	      /* If target supports single step either by hardware or by
  		 software, add actions s and S to the list of supported
@@ -3138,7 +3272,7 @@  handle_v_requests (char *own_buf, int packet_len, 
int *new_packet_len)

    if (startswith (own_buf, "vAttach;"))
      {
-      if ((!extended_protocol || !multi_process) && target_running ())
+      if ((!cs->extended_protocol || !cs->multi_process) && 
target_running ())
  	{
  	  fprintf (stderr, "Already debugging a process\n");
  	  write_enn (own_buf);
@@ -3150,7 +3284,7 @@  handle_v_requests (char *own_buf, int packet_len, 
int *new_packet_len)

    if (startswith (own_buf, "vRun;"))
      {
-      if ((!extended_protocol || !multi_process) && target_running ())
+      if ((!cs->extended_protocol || !cs->multi_process) && 
target_running ())
  	{
  	  fprintf (stderr, "Already debugging a process\n");
  	  write_enn (own_buf);
@@ -3187,12 +3321,13 @@  handle_v_requests (char *own_buf, int 
packet_len, int *new_packet_len)
  static void
  myresume (char *own_buf, int step, int sig)
  {
+  client_state *cs = get_client_state();
    struct thread_resume resume_info[2];
    int n = 0;
    int valid_cont_thread;

-  valid_cont_thread = (!ptid_equal (cont_thread, null_ptid)
-			 && !ptid_equal (cont_thread, minus_one_ptid));
+  valid_cont_thread = (!ptid_equal (cs->ss->cont_thread, null_ptid)
+			 && !ptid_equal (cs->ss->cont_thread, minus_one_ptid));

    if (step || sig || valid_cont_thread)
      {
@@ -3241,7 +3376,7 @@  queue_stop_reply_callback (thread_info *thread)
  	{
  	  if (debug_threads)
  	    {
-	      std::string status_string
+		std::string status_string
  		= target_waitstatus_to_string (&thread->last_status);

  	      debug_printf ("Reporting thread %s as already stopped with %s\n",
@@ -3307,6 +3442,8 @@  set_pending_status_callback (thread_info *thread)
  static void
  handle_status (char *own_buf)
  {
+  client_state *cs = get_client_state();
+
    /* GDB is connected, don't forward events to the target anymore.  */
    for_each_process ([] (process_info *process) {
      process->gdb_detached = 0;
@@ -3316,12 +3453,12 @@  handle_status (char *own_buf)
       thread.  In all-stop mode, just send one for the first stopped
       thread we find.  */

-  if (non_stop)
+  if (cs->non_stop)
      {
        for_each_thread (queue_stop_reply_callback);

-      /* The first is sent immediatly.  OK is sent if there is no
-	 stopped thread, which is the same handling of the vStopped
+      /* The first is sent immediately.  OK is sent if there is no
+	 stopped thread, which is the same handling as the vStopped
  	 packet (by design).  */
        notif_write_event (&notif_stop, own_buf);
      }
@@ -3343,10 +3480,10 @@  handle_status (char *own_buf)

        /* Prefer the last thread that reported an event to GDB (even if
  	 that was a GDB_SIGNAL_TRAP).  */
-      if (last_status.kind != TARGET_WAITKIND_IGNORE
-	  && last_status.kind != TARGET_WAITKIND_EXITED
-	  && last_status.kind != TARGET_WAITKIND_SIGNALLED)
-	thread = find_thread_ptid (last_ptid);
+      if (cs->ss->last_status.kind != TARGET_WAITKIND_IGNORE
+	  && cs->ss->last_status.kind != TARGET_WAITKIND_EXITED
+	  && cs->ss->last_status.kind != TARGET_WAITKIND_SIGNALLED)
+	thread = find_thread_ptid (cs->ss->last_ptid);

        /* If the last event thread is not found for some reason, look
  	 for some other thread that might have an event to report.  */
@@ -3371,7 +3508,7 @@  handle_status (char *own_buf)

  	  /* GDB assumes the current thread is the thread we're
  	     reporting the status for.  */
-	  general_thread = thread->id;
+	  cs->ss->general_thread = thread->id;
  	  set_desired_thread ();

  	  gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
@@ -3558,6 +3695,12 @@  captured_main (int argc, char *argv[])
    volatile int multi_mode = 0;
    volatile int attach = 0;
    int was_running;
+  int run_once_arg = 0;
+  int disable_randomization_arg = 1;
+
+  int remote_desc = get_remote_desc();
+  client_states.set_client_state (remote_desc);
+  client_state *cs = get_client_state();
    bool selftest = false;
  #if GDB_SELF_TEST
    const char *selftest_filter = NULL;
@@ -3588,15 +3731,15 @@  captured_main (int argc, char *argv[])
  	  tmp = next_arg;
  	  while (*next_arg != NULL && strcmp (*next_arg, "--") != 0)
  	    {
-	      wrapper_argv += *next_arg;
-	      wrapper_argv += ' ';
+	      cs->wrapper_argv += *next_arg;
+	      cs->wrapper_argv += ' ';
  	      next_arg++;
  	    }

-	  if (!wrapper_argv.empty ())
+	  if (!cs->wrapper_argv.empty ())
  	    {
  	      /* Erase the last whitespace.  */
-	      wrapper_argv.erase (wrapper_argv.end () - 1);
+	      cs->wrapper_argv.erase (cs->wrapper_argv.end () - 1);
  	    }

  	  if (next_arg == tmp || *next_arg == NULL)
@@ -3623,7 +3766,7 @@  captured_main (int argc, char *argv[])
  	    }
  	}
        else if (strcmp (*next_arg, "--remote-debug") == 0)
-	remote_debug = 1;
+	cs->remote_debug = 1;
        else if (strcmp (*next_arg, "--disable-packet") == 0)
  	{
  	  gdbserver_show_disableable (stdout);
@@ -3671,15 +3814,15 @@  captured_main (int argc, char *argv[])
  	  break;
  	}
        else if (strcmp (*next_arg, "--disable-randomization") == 0)
-	disable_randomization = 1;
+	disable_randomization_arg = 1;
        else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
-	disable_randomization = 0;
+	disable_randomization_arg = 0;
        else if (strcmp (*next_arg, "--startup-with-shell") == 0)
  	startup_with_shell = true;
        else if (strcmp (*next_arg, "--no-startup-with-shell") == 0)
  	startup_with_shell = false;
        else if (strcmp (*next_arg, "--once") == 0)
-	run_once = 1;
+	run_once_arg = 1;
        else if (strcmp (*next_arg, "--selftest") == 0)
  	selftest = true;
        else if (startswith (*next_arg, "--selftest="))
@@ -3699,6 +3842,9 @@  captured_main (int argc, char *argv[])
        continue;
      }

+  cs->run_once = run_once_arg;
+  cs->disable_randomization = disable_randomization_arg;
+
    if (port == NULL)
      {
        port = *next_arg;
@@ -3760,8 +3906,8 @@  captured_main (int argc, char *argv[])
      initialize_tracepoint ();
    initialize_notif ();

-  own_buf = (char *) xmalloc (PBUFSIZ + 1);
-  mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
+  cs->own_buf = (char *) xmalloc (PBUFSIZ + 1);
+  cs->ss->mem_buf = (unsigned char *) xmalloc (PBUFSIZ);

    if (selftest)
      {
@@ -3778,13 +3924,13 @@  captured_main (int argc, char *argv[])
        int i, n;

        n = argc - (next_arg - argv);
-      program_name = xstrdup (next_arg[0]);
+      cs->program_name = xstrdup (next_arg[0]);
        for (i = 1; i < n; i++)
-	program_args.push_back (xstrdup (next_arg[i]));
-      program_args.push_back (NULL);
+	cs->program_args.push_back (xstrdup (next_arg[i]));
+      cs->program_args.push_back (NULL);

        /* Wait till we are at first instruction in program.  */
-      create_inferior (program_name, program_args);
+      create_inferior (cs->program_name, cs->program_args);

        /* We are now (hopefully) stopped at the first instruction of
  	 the target process.  This assumes that the target process was
@@ -3799,9 +3945,9 @@  captured_main (int argc, char *argv[])
      }
    else
      {
-      last_status.kind = TARGET_WAITKIND_EXITED;
-      last_status.value.integer = 0;
-      last_ptid = minus_one_ptid;
+      cs->ss->last_status.kind = TARGET_WAITKIND_EXITED;
+      cs->ss->last_status.value.integer = 0;
+      cs->ss->last_ptid = minus_one_ptid;
      }
    make_cleanup (detach_or_kill_for_exit_cleanup, NULL);

@@ -3810,8 +3956,8 @@  captured_main (int argc, char *argv[])
       shared library event" notice on gdb side.  */
    dlls_changed = 0;

-  if (last_status.kind == TARGET_WAITKIND_EXITED
-      || last_status.kind == TARGET_WAITKIND_SIGNALLED)
+  if (cs->ss->last_status.kind == TARGET_WAITKIND_EXITED
+      || cs->ss->last_status.kind == TARGET_WAITKIND_SIGNALLED)
      was_running = 0;
    else
      was_running = 1;
@@ -3822,17 +3968,13 @@  captured_main (int argc, char *argv[])
    while (1)
      {

-      noack_mode = 0;
-      multi_process = 0;
-      report_fork_events = 0;
-      report_vfork_events = 0;
-      report_exec_events = 0;
+      cs->noack_mode = 0;
        /* Be sure we're out of tfind mode.  */
        current_traceframe = -1;
-      cont_thread = null_ptid;
-      swbreak_feature = 0;
-      hwbreak_feature = 0;
-      vCont_supported = 0;
+      cs->ss->cont_thread = null_ptid;
+      cs->swbreak_feature = 0;
+      cs->hwbreak_feature = 0;
+      cs->vCont_supported = 0;

        remote_open (port);

@@ -3844,7 +3986,7 @@  captured_main (int argc, char *argv[])

  	  /* If an exit was requested (using the "monitor exit"
  	     command), terminate now.  */
-	  if (exit_requested)
+	  if (cs->exit_requested)
  	    throw_quit ("Quit");

  	  /* The only other way to get here is for getpkt to fail:
@@ -3857,7 +3999,7 @@  captured_main (int argc, char *argv[])

  	      - Otherwise, close the connection and reopen it at the
  	        top of the loop.  */
-	  if (run_once || (!extended_protocol && !target_running ()))
+	  if (cs->run_once || (!cs->extended_protocol && !target_running ()))
  	    throw_quit ("Quit");

  	  fprintf (stderr,
@@ -3883,10 +4025,10 @@  captured_main (int argc, char *argv[])
  		     no point either in having the target always stop
  		     all threads, when we're going to pass signals
  		     down without informing GDB.  */
-		  if (!non_stop)
+		  if (!cs->non_stop)
  		    {
  		      if (start_non_stop (1))
-			non_stop = 1;
+			cs->non_stop = 1;

  		      /* Detaching implicitly resumes all threads;
  			 simply disconnecting does not.  */
@@ -3906,13 +4048,13 @@  captured_main (int argc, char *argv[])
  	  fflush (stdout);
  	  fprintf (stderr, "gdbserver: %s\n", exception.message);

-	  if (response_needed)
+	  if (cs->response_needed)
  	    {
-	      write_enn (own_buf);
-	      putpkt (own_buf);
+	      write_enn (cs->own_buf);
+	      putpkt (cs->own_buf);
  	    }

-	  if (run_once)
+	  if (cs->run_once)
  	    throw_quit ("Quit");
  	}
        END_CATCH
@@ -4004,6 +4146,7 @@  process_point_options (struct gdb_breakpoint *bp, 
const char **packet)
  static int
  process_serial_event (void)
  {
+  client_state *cs = get_client_state();
    int signal;
    unsigned int len;
    int res;
@@ -4014,41 +4157,41 @@  process_serial_event (void)

    disable_async_io ();

-  response_needed = 0;
-  packet_len = getpkt (own_buf);
-  if (packet_len <= 0)
+  cs->response_needed = 0;
+  cs->packet_length = getpkt (cs->own_buf);
+  if (cs->packet_length <= 0)
      {
        remote_close ();
        /* Force an event loop break.  */
        return -1;
      }
-  response_needed = 1;
+  cs->response_needed = 1;

-  char ch = own_buf[0];
+  char ch = cs->own_buf[0];
    switch (ch)
      {
      case 'q':
-      handle_query (own_buf, packet_len, &new_packet_len);
+      handle_query (cs->own_buf, cs->packet_length, &new_packet_len);
        break;
      case 'Q':
-      handle_general_set (own_buf);
+      handle_general_set (cs->own_buf);
        break;
      case 'D':
-      handle_detach (own_buf);
+      handle_detach (cs->own_buf);
        break;
      case '!':
-      extended_protocol = 1;
-      write_ok (own_buf);
+      cs->extended_protocol = 1;
+      write_ok (cs->own_buf);
        break;
      case '?':
-      handle_status (own_buf);
+      handle_status (cs->own_buf);
        break;
      case 'H':
-      if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
+      if (cs->own_buf[1] == 'c' || cs->own_buf[1] == 'g' || 
cs->own_buf[1] == 's')
  	{
-	  require_running_or_break (own_buf);
+	  require_running_or_break (cs->own_buf);

-	  ptid_t thread_id = read_ptid (&own_buf[2], NULL);
+	  ptid_t thread_id = read_ptid (&cs->own_buf[2], NULL);

  	  if (thread_id == null_ptid || thread_id == minus_one_ptid)
  	    thread_id = null_ptid;
@@ -4059,7 +4202,7 @@  process_serial_event (void)

  	      if (thread == NULL)
  		{
-		  write_enn (own_buf);
+		  write_enn (cs->own_buf);
  		  break;
  		}

@@ -4070,42 +4213,42 @@  process_serial_event (void)
  	      /* The ptid represents a lwp/tid.  */
  	      if (find_thread_ptid (thread_id) == NULL)
  		{
-		  write_enn (own_buf);
+		  write_enn (cs->own_buf);
  		  break;
  		}
  	    }

-	  if (own_buf[1] == 'g')
+	  if (cs->own_buf[1] == 'g')
  	    {
  	      if (ptid_equal (thread_id, null_ptid))
  		{
  		  /* GDB is telling us to choose any thread.  Check if
  		     the currently selected thread is still valid. If
  		     it is not, select the first available.  */
-		  thread_info *thread = find_thread_ptid (general_thread);
+		  thread_info *thread = find_thread_ptid (cs->ss->general_thread);
  		  if (thread == NULL)
  		    thread = get_first_thread ();
  		  thread_id = thread->id;
  		}

-	      general_thread = thread_id;
+	      cs->ss->general_thread = thread_id;
  	      set_desired_thread ();
-	      gdb_assert (current_thread != NULL);
+	      gdb_assert (cs->ss->current_thread != NULL);
  	    }
-	  else if (own_buf[1] == 'c')
-	    cont_thread = thread_id;
+	  else if (cs->own_buf[1] == 'c')
+	    cs->ss->cont_thread = thread_id;

-	  write_ok (own_buf);
+	  write_ok (cs->own_buf);
  	}
        else
  	{
  	  /* Silently ignore it so that gdb can extend the protocol
  	     without compatibility headaches.  */
-	  own_buf[0] = '\0';
+	  cs->own_buf[0] = '\0';
  	}
        break;
      case 'g':
-      require_running_or_break (own_buf);
+      require_running_or_break (cs->own_buf);
        if (current_traceframe >= 0)
  	{
  	  struct regcache *regcache
@@ -4113,9 +4256,9 @@  process_serial_event (void)

  	  if (fetch_traceframe_registers (current_traceframe,
  					  regcache, -1) == 0)
-	    registers_to_string (regcache, own_buf);
+	    registers_to_string (regcache, cs->own_buf);
  	  else
-	    write_enn (own_buf);
+	    write_enn (cs->own_buf);
  	  free_register_cache (regcache);
  	}
        else
@@ -4123,85 +4266,85 @@  process_serial_event (void)
  	  struct regcache *regcache;

  	  if (!set_desired_thread ())
-	    write_enn (own_buf);
+	    write_enn (cs->own_buf);
  	  else
  	    {
-	      regcache = get_thread_regcache (current_thread, 1);
-	      registers_to_string (regcache, own_buf);
+	      regcache = get_thread_regcache (cs->ss->current_thread, 1);
+	      registers_to_string (regcache, cs->own_buf);
  	    }
  	}
        break;
      case 'G':
-      require_running_or_break (own_buf);
+      require_running_or_break (cs->own_buf);
        if (current_traceframe >= 0)
-	write_enn (own_buf);
+	write_enn (cs->own_buf);
        else
  	{
  	  struct regcache *regcache;

  	  if (!set_desired_thread ())
-	    write_enn (own_buf);
+	    write_enn (cs->own_buf);
  	  else
  	    {
-	      regcache = get_thread_regcache (current_thread, 1);
-	      registers_from_string (regcache, &own_buf[1]);
-	      write_ok (own_buf);
+	      regcache = get_thread_regcache (cs->ss->current_thread, 1);
+	      registers_from_string (regcache, &cs->own_buf[1]);
+	      write_ok (cs->own_buf);
  	    }
  	}
        break;
      case 'm':
-      require_running_or_break (own_buf);
-      decode_m_packet (&own_buf[1], &mem_addr, &len);
-      res = gdb_read_memory (mem_addr, mem_buf, len);
+      require_running_or_break (cs->own_buf);
+      decode_m_packet (&cs->own_buf[1], &mem_addr, &len);
+      res = gdb_read_memory (mem_addr, cs->ss->mem_buf, len);
        if (res < 0)
-	write_enn (own_buf);
+	write_enn (cs->own_buf);
        else
-	bin2hex (mem_buf, own_buf, res);
+	bin2hex (cs->ss->mem_buf, cs->own_buf, res);
        break;
      case 'M':
-      require_running_or_break (own_buf);
-      decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
-      if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
-	write_ok (own_buf);
+      require_running_or_break (cs->own_buf);
+      decode_M_packet (&cs->own_buf[1], &mem_addr, &len, &cs->ss->mem_buf);
+      if (gdb_write_memory (mem_addr, cs->ss->mem_buf, len) == 0)
+	write_ok (cs->own_buf);
        else
-	write_enn (own_buf);
+	write_enn (cs->own_buf);
        break;
      case 'X':
-      require_running_or_break (own_buf);
-      if (decode_X_packet (&own_buf[1], packet_len - 1,
-			   &mem_addr, &len, &mem_buf) < 0
-	  || gdb_write_memory (mem_addr, mem_buf, len) != 0)
-	write_enn (own_buf);
+      require_running_or_break (cs->own_buf);
+      if (decode_X_packet (&cs->own_buf[1], cs->packet_length - 1,
+			   &mem_addr, &len, &cs->ss->mem_buf) < 0
+	  || gdb_write_memory (mem_addr, cs->ss->mem_buf, len) != 0)
+	write_enn (cs->own_buf);
        else
-	write_ok (own_buf);
+	write_ok (cs->own_buf);
        break;
      case 'C':
-      require_running_or_break (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running_or_break (cs->own_buf);
+      hex2bin (cs->own_buf + 1, &sig, 1);
        if (gdb_signal_to_host_p ((enum gdb_signal) sig))
  	signal = gdb_signal_to_host ((enum gdb_signal) sig);
        else
  	signal = 0;
-      myresume (own_buf, 0, signal);
+      myresume (cs->own_buf, 0, signal);
        break;
      case 'S':
-      require_running_or_break (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running_or_break (cs->own_buf);
+      hex2bin (cs->own_buf + 1, &sig, 1);
        if (gdb_signal_to_host_p ((enum gdb_signal) sig))
  	signal = gdb_signal_to_host ((enum gdb_signal) sig);
        else
  	signal = 0;
-      myresume (own_buf, 1, signal);
+      myresume (cs->own_buf, 1, signal);
        break;
      case 'c':
-      require_running_or_break (own_buf);
+      require_running_or_break (cs->own_buf);
        signal = 0;
-      myresume (own_buf, 0, signal);
+      myresume (cs->own_buf, 0, signal);
        break;
      case 's':
-      require_running_or_break (own_buf);
+      require_running_or_break (cs->own_buf);
        signal = 0;
-      myresume (own_buf, 1, signal);
+      myresume (cs->own_buf, 1, signal);
        break;
      case 'Z':  /* insert_ ... */
        /* Fallthrough.  */
@@ -4210,12 +4353,12 @@  process_serial_event (void)
  	char *dataptr;
  	ULONGEST addr;
  	int kind;
-	char type = own_buf[1];
+	char type = cs->own_buf[1];
  	int res;
  	const int insert = ch == 'Z';
-	const char *p = &own_buf[3];
+	char *p = &cs->own_buf[3];

-	p = unpack_varlen_hex (p, &addr);
+	p = (char*)unpack_varlen_hex (p, &addr);
  	kind = strtol (p + 1, &dataptr, 16);

  	if (insert)
@@ -4241,16 +4384,16 @@  process_serial_event (void)
  	  res = delete_gdb_breakpoint (type, addr, kind);

  	if (res == 0)
-	  write_ok (own_buf);
+	  write_ok (cs->own_buf);
  	else if (res == 1)
  	  /* Unsupported.  */
-	  own_buf[0] = '\0';
+	  cs->own_buf[0] = '\0';
  	else
-	  write_enn (own_buf);
+	  write_enn (cs->own_buf);
  	break;
        }
      case 'k':
-      response_needed = 0;
+      cs->response_needed = 0;
        if (!target_running ())
  	/* The packet we received doesn't make sense - but we can't
  	   reply to it, either.  */
@@ -4262,10 +4405,10 @@  process_serial_event (void)

        /* When using the extended protocol, we wait with no program
  	 running.  The traditional protocol will exit instead.  */
-      if (extended_protocol)
+      if (cs->extended_protocol)
  	{
-	  last_status.kind = TARGET_WAITKIND_EXITED;
-	  last_status.value.sig = GDB_SIGNAL_KILL;
+	  cs->ss->last_status.kind = TARGET_WAITKIND_EXITED;
+	  cs->ss->last_status.value.sig = GDB_SIGNAL_KILL;
  	  return 0;
  	}
        else
@@ -4273,27 +4416,27 @@  process_serial_event (void)

      case 'T':
        {
-	require_running_or_break (own_buf);
+	require_running_or_break (cs->own_buf);

-	ptid_t thread_id = read_ptid (&own_buf[1], NULL);
+	ptid_t thread_id = read_ptid (&cs->own_buf[1], NULL);
  	if (find_thread_ptid (thread_id) == NULL)
  	  {
-	    write_enn (own_buf);
+	    write_enn (cs->own_buf);
  	    break;
  	  }

  	if (mythread_alive (thread_id))
-	  write_ok (own_buf);
+	  write_ok (cs->own_buf);
  	else
-	  write_enn (own_buf);
+	  write_enn (cs->own_buf);
        }
        break;
      case 'R':
-      response_needed = 0;
+      cs->response_needed = 0;

        /* Restarting the inferior is only supported in the extended
  	 protocol.  */
-      if (extended_protocol)
+      if (cs->extended_protocol)
  	{
  	  if (target_running ())
  	    for_each_process (kill_inferior_callback);
@@ -4301,26 +4444,26 @@  process_serial_event (void)
  	  fprintf (stderr, "GDBserver restarting\n");

  	  /* Wait till we are at 1st instruction in prog.  */
-	  if (program_name != NULL)
+	  if (cs->program_name != NULL)
  	    {
-	      create_inferior (program_name, program_args);
+	      create_inferior (cs->program_name, cs->program_args);

-	      if (last_status.kind == TARGET_WAITKIND_STOPPED)
+	      if (cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED)
  		{
  		  /* Stopped at the first instruction of the target
  		     process.  */
-		  general_thread = last_ptid;
+		  cs->ss->general_thread = cs->ss->last_ptid;
  		}
  	      else
  		{
  		  /* Something went wrong.  */
-		  general_thread = null_ptid;
+		  cs->ss->general_thread = null_ptid;
  		}
  	    }
  	  else
  	    {
-	      last_status.kind = TARGET_WAITKIND_EXITED;
-	      last_status.value.sig = GDB_SIGNAL_KILL;
+	      cs->ss->last_status.kind = TARGET_WAITKIND_EXITED;
+	      cs->ss->last_status.value.sig = GDB_SIGNAL_KILL;
  	    }
  	  return 0;
  	}
@@ -4329,30 +4472,30 @@  process_serial_event (void)
  	  /* It is a request we don't understand.  Respond with an
  	     empty packet so that gdb knows that we don't support this
  	     request.  */
-	  own_buf[0] = '\0';
+	  cs->own_buf[0] = '\0';
  	  break;
  	}
      case 'v':
        /* Extended (long) request.  */
-      handle_v_requests (own_buf, packet_len, &new_packet_len);
+      handle_v_requests (cs->own_buf, cs->packet_length, &new_packet_len);
        break;

      default:
        /* It is a request we don't understand.  Respond with an empty
  	 packet so that gdb knows that we don't support this
  	 request.  */
-      own_buf[0] = '\0';
+      cs->own_buf[0] = '\0';
        break;
      }

    if (new_packet_len != -1)
-    putpkt_binary (own_buf, new_packet_len);
+    putpkt_binary (cs->own_buf, new_packet_len);
    else
-    putpkt (own_buf);
+    putpkt (cs->own_buf);

-  response_needed = 0;
+  cs->response_needed = 0;

-  if (exit_requested)
+  if (cs->exit_requested)
      return -1;

    return 0;
@@ -4395,38 +4538,40 @@  push_stop_notification (ptid_t ptid, struct 
target_waitstatus *status)
  int
  handle_target_event (int err, gdb_client_data client_data)
  {
+  client_state *cs = get_client_state();
+
    if (debug_threads)
      debug_printf ("handling possible target event\n");

-  last_ptid = mywait (minus_one_ptid, &last_status,
+  cs->ss->last_ptid = mywait (minus_one_ptid, &cs->ss->last_status,
  		      TARGET_WNOHANG, 1);

-  if (last_status.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (cs->ss->last_status.kind == TARGET_WAITKIND_NO_RESUMED)
      {
-      if (gdb_connected () && report_no_resumed)
-	push_stop_notification (null_ptid, &last_status);
+      if (gdb_connected () && cs->report_no_resumed)
+	push_stop_notification (null_ptid, &cs->ss->last_status);
      }
-  else if (last_status.kind != TARGET_WAITKIND_IGNORE)
+  else if (cs->ss->last_status.kind != TARGET_WAITKIND_IGNORE)
      {
-      int pid = ptid_get_pid (last_ptid);
+      int pid = ptid_get_pid (cs->ss->last_ptid);
        struct process_info *process = find_process_pid (pid);
        int forward_event = !gdb_connected () || process->gdb_detached;

-      if (last_status.kind == TARGET_WAITKIND_EXITED
-	  || last_status.kind == TARGET_WAITKIND_SIGNALLED)
+      if (cs->ss->last_status.kind == TARGET_WAITKIND_EXITED
+	  || cs->ss->last_status.kind == TARGET_WAITKIND_SIGNALLED)
  	{
  	  mark_breakpoints_out (process);
-	  target_mourn_inferior (last_ptid);
+	  target_mourn_inferior (cs->ss->last_ptid);
  	}
-      else if (last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
+      else if (cs->ss->last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
  	;
        else
  	{
  	  /* We're reporting this thread as stopped.  Update its
  	     "want-stopped" state to what the client wants, until it
  	     gets a new resume action.  */
-	  current_thread->last_resume_kind = resume_stop;
-	  current_thread->last_status = last_status;
+	  cs->ss->current_thread->last_resume_kind = resume_stop;
+	  cs->ss->current_thread->last_status = cs->ss->last_status;
  	}

        if (forward_event)
@@ -4437,9 +4582,9 @@  handle_target_event (int err, gdb_client_data 
client_data)
  	      exit (0);
  	    }

-	  if (last_status.kind == TARGET_WAITKIND_EXITED
-	      || last_status.kind == TARGET_WAITKIND_SIGNALLED
-	      || last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
+	  if (cs->ss->last_status.kind == TARGET_WAITKIND_EXITED
+	      || cs->ss->last_status.kind == TARGET_WAITKIND_SIGNALLED
+	      || cs->ss->last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
  	    ;
  	  else
  	    {
@@ -4451,18 +4596,18 @@  handle_target_event (int err, gdb_client_data 
client_data)
  	      if (debug_threads)
  		debug_printf ("GDB not connected; forwarding event %d for"
  			      " [%s]\n",
-			      (int) last_status.kind,
-			      target_pid_to_str (last_ptid));
+			      (int) cs->ss->last_status.kind,
+			      target_pid_to_str (cs->ss->last_ptid));

-	      if (last_status.kind == TARGET_WAITKIND_STOPPED)
-		signal = last_status.value.sig;
+	      if (cs->ss->last_status.kind == TARGET_WAITKIND_STOPPED)
+		signal = cs->ss->last_status.value.sig;
  	      else
  		signal = GDB_SIGNAL_0;
-	      target_continue (last_ptid, signal);
+	      target_continue (cs->ss->last_ptid, signal);
  	    }
  	}
        else
-	push_stop_notification (last_ptid, &last_status);
+	push_stop_notification (cs->ss->last_ptid, &cs->ss->last_status);
      }

    /* Be sure to not change the selected thread behind GDB's back.
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 5970431d8ed..8e1459f74e2 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -60,52 +60,19 @@  int vsnprintf(char *str, size_t size, const char 
*format, va_list ap);
  #include "gdb_signals.h"
  #include "target.h"
  #include "mem-break.h"
-#include "gdbthread.h"
-#include "inferiors.h"
  #include "environ.h"
+#include <list>
+#include <map>

  /* Target-specific functions */

  void initialize_low ();

-/* Public variables in server.c */
-
-extern ptid_t cont_thread;
-extern ptid_t general_thread;
-
-extern int server_waiting;
-extern int pass_signals[];
-extern int program_signals[];
-extern int program_signals_p;
-
  extern int disable_packet_vCont;
  extern int disable_packet_Tthread;
  extern int disable_packet_qC;
  extern int disable_packet_qfThreadInfo;

-extern char *own_buf;
-
-extern int run_once;
-extern int multi_process;
-extern int report_fork_events;
-extern int report_vfork_events;
-extern int report_exec_events;
-extern int report_thread_events;
-extern int non_stop;
-
-/* True if the "swbreak+" feature is active.  In that case, GDB wants
-   us to report whether a trap is explained by a software breakpoint
-   and for the server to handle PC adjustment if necessary on this
-   target.  Only enabled if the target supports it.  */
-extern int swbreak_feature;
-
-/* True if the "hwbreak+" feature is active.  In that case, GDB wants
-   us to report whether a trap is explained by a hardware breakpoint.
-   Only enabled if the target supports it.  */
-extern int hwbreak_feature;
-
-extern int disable_randomization;
-
  #if USE_WIN32API
  #include <winsock2.h>
  typedef SOCKET gdb_fildes_t;
@@ -158,8 +125,161 @@  extern void post_fork_inferior (int pid, const 
char *program);
  /* Get the gdb_environ being used in the current session.  */
  extern gdb_environ *get_environ ();

-extern target_waitstatus last_status;
-extern ptid_t last_ptid;
-extern unsigned long signal_pid;
+// extern ptid_t cs->ss->last_ptid;
+// extern unsigned long cs->ss->signal_pid;

  #endif /* SERVER_H */
+
+/* Description of the remote protocol state for the currently
+   connected target.  This is per-target state, and independent of the
+   selected architecture. */
+
+struct server_state
+{
+  int attach_count;
+  /* From server.c */
+  /* The thread set with an `Hc' packet.  `Hc' is deprecated in favor of
+     `vCont'.  Note the multi-process extensions made `vCont' a
+     requirement, so `Hc pPID.TID' is pretty much undefined.  So
+     CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for
+     resuming all threads of the process (again, `Hc' isn't used for
+     multi-process), or a specific thread ptid_t.  */
+  ptid_t cont_thread;
+  /* The thread set with an `Hg' packet.  */
+  ptid_t general_thread;
+  /* The PID of the originally created or attached inferior.  Used to
+     send signals to the process when GDB sends us an asynchronous 
interrupt
+     (user hitting Control-C in the client), and to wait for the child 
to exit
+     when no longer debugging it.  */
+
+  unsigned long signal_pid;
+  /* Last status reported to GDB.  */
+  struct target_waitstatus last_status;
+  /* Was last status an exit status? (sticky if yes) */
+  int last_status_exited;
+  ptid_t last_ptid;
+  unsigned char *mem_buf;
+
+  /* from remote-utils.c */
+  /* Internal buffer used by readchar.
+     These are global to readchar because reschedule_remote needs to be
+     able to tell whether the buffer is empty.  */
+  unsigned char readchar_buf[BUFSIZ];
+  int readchar_bufcnt;
+  unsigned char *readchar_bufp;
+  /* from inferiors.c */
+  std::list<process_info *> all_processes;
+  std::list<thread_info *> all_threads;
+
+  struct thread_info *current_thread;
+};
+
+typedef struct server_state server_state;
+
+
+enum packet_types { other_packet, vContc, vConts, vContt, vRun, 
vAttach, Hg, g_or_m, vStopped };
+typedef enum packet_types packet_types;
+
+enum exit_types { no_exit, have_exit, sent_exit };
+typedef enum exit_types exit_types;
+
+
+struct client_state
+{
+  gdb_fildes_t file_desc;
+  int attached_to_client;
+  int packet_type;
+  int last_packet_type;
+  int pending;
+  int nonstop_pending;
+  int catch_syscalls;
+  ptid_t last_cont_ptid;
+  ptid_t new_general_thread;
+
+  /* From server.c */
+  int server_waiting;
+
+  int extended_protocol;
+  int response_needed;
+  int exit_requested;
+
+  /* --once: Exit after the first connection has closed.  */
+  int run_once;
+
+  int multi_process;
+  int report_fork_events;
+  int report_vfork_events;
+  int report_exec_events;
+  int report_thread_events;
+  /* Whether to report TARGET_WAITKING_NO_RESUMED events.  */
+  int report_no_resumed;
+  int non_stop;
+  /* True if the "swbreak+" feature is active.  In that case, GDB wants
+     us to report whether a trap is explained by a software breakpoint
+     and for the server to handle PC adjustment if necessary on this
+     target.  Only enabled if the target supports it.  */
+  int swbreak_feature;
+  /* True if the "hwbreak+" feature is active.  In that case, GDB wants
+     us to report whether a trap is explained by a hardware breakpoint.
+     Only enabled if the target supports it.  */
+  int hwbreak_feature;
+
+  /* True if the "vContSupported" feature is active.  In that case, GDB
+     wants us to report whether single step is supported in the reply to
+     "vCont?" packet.  */
+  int vCont_supported;
+
+  /* Whether we should attempt to disable the operating system's address
+     space randomization feature before starting an inferior.  */
+  int disable_randomization;
+
+  char *program_name = NULL;
+  std::vector<char *> program_args;
+  std::string wrapper_argv;
+
+  int packet_length;
+
+  int pass_signals[GDB_SIGNAL_LAST];
+  int program_signals[GDB_SIGNAL_LAST];
+  int program_signals_p;
+
+  char *notify_buffer;
+  /* Renamed from own_buf to avoid macro name conflict with a common 
local variable name */
+  char *own_buf;
+
+  /* from remote-utils.c */
+  int remote_debug;
+  /* If true, then GDB has requested noack mode.  */
+  int noack_mode;
+  /* If true, then we tell GDB to use noack mode by default.  */
+  int transport_is_reliable;
+
+  server_state *ss;
+
+  client_state () {};
+  client_state (gdb_fildes_t, client_state*);
+};
+
+typedef struct client_state client_state;
+
+
+struct multi_client_states
+{
+public:
+  std::map<gdb_fildes_t,client_state*> cs;
+  client_state *current_cs;
+
+  client_state* get_client_state (void) { return current_cs; }
+  void set_current_client (client_state* p_cs) { current_cs = p_cs; }
+
+  client_state * set_client_state (gdb_fildes_t);
+  void free_client_state (client_state *cs);
+  void delete_client_state (gdb_fildes_t fd);
+};
+
+client_state* get_client_state (void);
+struct multi_client_states * get_client_states (void);
+
+
+#include "gdbthread.h"
+#include "inferiors.h"
diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c
index fd1f8d652c6..5d51a420586 100644
--- a/gdb/gdbserver/spu-low.c
+++ b/gdb/gdbserver/spu-low.c
@@ -280,12 +280,12 @@  spu_ptrace_fun ()

  static int
  spu_create_inferior (const char *program,
-		     const std::vector<char *> &program_args)
+		     const std::vector<char *> &cs->program_args)
  {
    int pid;
    ptid_t ptid;
    struct process_info *proc;
-  std::string str_program_args = stringify_argv (program_args);
+  std::string str_program_args = stringify_argv (cs->program_args);

    pid = fork_inferior (program,
  		       str_program_args.c_str (),
@@ -439,7 +439,7 @@  spu_wait (ptid_t ptid, struct target_waitstatus 
*ourstatus, int options)

    /* On the first wait, continue running the inferior until we are
       blocked inside an spu_run system call.  */
-  if (!server_waiting)
+  if (!cs->server_waiting)
      {
        int fd;
        CORE_ADDR addr;
@@ -470,7 +470,7 @@  spu_wait (ptid_t ptid, struct target_waitstatus 
*ourstatus, int options)

    /* After attach, we may have received a SIGSTOP.  Do not return this
       as signal to GDB, or else it will try to continue with SIGSTOP 
...  */
-  if (!server_waiting)
+  if (!cs->server_waiting)
      {
        ourstatus->kind = TARGET_WAITKIND_STOPPED;
        ourstatus->value.sig = GDB_SIGNAL_0;
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 019f9748346..38ad8b3341f 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -26,10 +26,11 @@  struct target_ops *the_target;
  int
  set_desired_thread ()
  {
-  thread_info *found = find_thread_ptid (general_thread);
+  client_state *cs = get_client_state();
+  thread_info *found = find_thread_ptid (cs->ss->general_thread);

-  current_thread = found;
-  return (current_thread != NULL);
+  cs->ss->current_thread = found;
+  return (cs->ss->current_thread != NULL);
  }

  /* The thread that was current before prepare_to_access_memory was
@@ -42,6 +43,8 @@  static ptid_t prev_general_thread;
  int
  prepare_to_access_memory (void)
  {
+  client_state *cs = get_client_state();
+
    /* The first thread found.  */
    struct thread_info *first = NULL;
    /* The first stopped thread found.  */
@@ -51,7 +54,7 @@  prepare_to_access_memory (void)

    /* Save the general thread value, since prepare_to_access_memory 
could change
       it.  */
-  prev_general_thread = general_thread;
+  prev_general_thread = cs->ss->general_thread;

    if (the_target->prepare_to_access_memory != NULL)
      {
@@ -97,8 +100,8 @@  prepare_to_access_memory (void)
        return 1;
      }

-  current_thread = thread;
-  general_thread = ptid_of (thread);
+  cs->ss->current_thread = thread;
+  cs->ss->general_thread = ptid_of (thread);

    return 0;
  }
@@ -108,12 +111,14 @@  prepare_to_access_memory (void)
  void
  done_accessing_memory (void)
  {
+  client_state *cs = get_client_state();
+
    if (the_target->done_accessing_memory != NULL)
      the_target->done_accessing_memory ();

    /* Restore the previous selected thread.  */
-  general_thread = prev_general_thread;
-  switch_to_thread (general_thread);
+  cs->ss->general_thread = prev_general_thread;
+  switch_to_thread (cs->ss->general_thread);
  }

  int
@@ -176,10 +181,11 @@  ptid_t
  mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
  	int connected_wait)
  {
+  client_state *cs = get_client_state();
    ptid_t ret;

    if (connected_wait)
-    server_waiting = 1;
+    cs->server_waiting = 1;

    ret = target_wait (ptid, ourstatus, options);

@@ -206,7 +212,7 @@  mywait (ptid_t ptid, struct target_waitstatus 
*ourstatus, int options,
      }

    if (connected_wait)
-    server_waiting = 0;
+    cs->server_waiting = 0;

    return ret;
  }
@@ -216,8 +222,9 @@  mywait (ptid_t ptid, struct target_waitstatus 
*ourstatus, int options,
  void
  target_stop_and_wait (ptid_t ptid)
  {
+  client_state *cs = get_client_state();
    struct target_waitstatus status;
-  int was_non_stop = non_stop;
+  int was_non_stop = cs->non_stop;
    struct thread_resume resume_info;

    resume_info.thread = ptid;
@@ -225,9 +232,9 @@  target_stop_and_wait (ptid_t ptid)
    resume_info.sig = GDB_SIGNAL_0;
    (*the_target->resume) (&resume_info, 1);

-  non_stop = 1;
+  cs->non_stop = 1;
    mywait (ptid, &status, 0, 0);
-  non_stop = was_non_stop;
+  cs->non_stop = was_non_stop;
  }

  /* See target/target.h.  */
diff --git a/gdb/gdbserver/tdesc.c b/gdb/gdbserver/tdesc.c
index c39b5e7d27e..9b1c398e53a 100644
--- a/gdb/gdbserver/tdesc.c
+++ b/gdb/gdbserver/tdesc.c
@@ -60,7 +60,9 @@  copy_target_description (struct target_desc *dest,
  const struct target_desc *
  current_target_desc (void)
  {
-  if (current_thread == NULL)
+  client_state *cs = get_client_state();
+
+  if (cs->ss->current_thread == NULL)
      return &default_description;

    return current_process ()->tdesc;
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 812aa0f61f1..f9f31c6878a 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -308,6 +308,7 @@  find_new_threads_callback (const td_thrhandle_t 
*th_p, void *data)
  static void
  thread_db_find_new_threads (void)
  {
+  client_state *cs = get_client_state();
    td_err_e err;
    ptid_t ptid = current_ptid;
    struct thread_db *thread_db = current_process ()->priv->thread_db;
@@ -386,6 +387,7 @@  int
  thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
  			   CORE_ADDR load_module, CORE_ADDR *address)
  {
+  client_state *cs = get_client_state();
    psaddr_t addr;
    td_err_e err;
    struct lwp_info *lwp;
@@ -412,8 +414,8 @@  thread_db_get_tls_address (struct thread_info 
*thread, CORE_ADDR offset,
    if (!lwp->thread_known)
      return TD_NOTHR;

-  saved_thread = current_thread;
-  current_thread = thread;
+  saved_thread = cs->ss->current_thread;
+  cs->ss->current_thread = thread;

    if (load_module != 0)
      {
@@ -436,7 +438,7 @@  thread_db_get_tls_address (struct thread_info 
*thread, CORE_ADDR offset,
        addr = (char *) addr + offset;
      }

-  current_thread = saved_thread;
+  cs->ss->current_thread = saved_thread;
    if (err == TD_OK)
      {
        *address = (CORE_ADDR) (uintptr_t) addr;
@@ -772,9 +774,10 @@  thread_db_init (void)
  static void
  switch_to_process (struct process_info *proc)
  {
+  client_state *cs = get_client_state();
    int pid = pid_of (proc);

-  current_thread = find_any_thread_of_pid (pid);
+  cs->ss->current_thread = find_any_thread_of_pid (pid);
  }

  /* Disconnect from libthread_db and free resources.  */
@@ -782,6 +785,7 @@  switch_to_process (struct process_info *proc)
  static void
  disable_thread_event_reporting (struct process_info *proc)
  {
+  client_state *cs = get_client_state();
    struct thread_db *thread_db = proc->priv->thread_db;
    if (thread_db)
      {
@@ -798,7 +802,7 @@  disable_thread_event_reporting (struct process_info 
*proc)

        if (td_ta_clear_event_p != NULL)
  	{
-	  struct thread_info *saved_thread = current_thread;
+	  struct thread_info *saved_thread = cs->ss->current_thread;
  	  td_thr_events_t events;

  	  switch_to_process (proc);
@@ -808,7 +812,7 @@  disable_thread_event_reporting (struct process_info 
*proc)
  	  td_event_fillset (&events);
  	  (*td_ta_clear_event_p) (thread_db->thread_agent, &events);

-	  current_thread = saved_thread;
+	  cs->ss->current_thread = saved_thread;
  	}
      }
  }
@@ -893,6 +897,7 @@  thread_db_handle_monitor_command (char *mon)
  void
  thread_db_notice_clone (struct thread_info *parent_thr, ptid_t child_ptid)
  {
+  client_state *cs = get_client_state();
    process_info *parent_proc = get_thread_process (parent_thr);
    struct thread_db *thread_db = parent_proc->priv->thread_db;

@@ -905,7 +910,7 @@  thread_db_notice_clone (struct thread_info 
*parent_thr, ptid_t child_ptid)
       the current thread.  Temporarily switch to a thread we know is
       stopped.  */
    scoped_restore restore_current_thread
-    = make_scoped_restore (&current_thread, parent_thr);
+    = make_scoped_restore (&cs->ss->current_thread, parent_thr);

    if (!find_one_thread (child_ptid))
      warning ("Cannot find thread after clone.\n");
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 41727561925..4873ecf8b44 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -2343,10 +2343,11 @@  find_next_traceframe_by_tracepoint (int num, int 
*tfnump)
  static void
  cmd_qtinit (char *packet)
  {
+  client_state *cs = get_client_state();
    struct trace_state_variable *tsv, *prev, *next;

    /* Can't do this command without a pid attached.  */
-  if (current_thread == NULL)
+  if (cs->ss->current_thread == NULL)
      {
        write_enn (packet);
        return;
@@ -3959,22 +3960,23 @@  cmd_qtstmat (char *packet)
  void
  gdb_agent_about_to_close (int pid)
  {
+  client_state *cs = get_client_state();
    char buf[IPA_CMD_BUF_SIZE];

    if (!maybe_write_ipa_not_loaded (buf))
      {
        struct thread_info *saved_thread;

-      saved_thread = current_thread;
+      saved_thread = cs->ss->current_thread;

        /* Find any thread which belongs to process PID.  */
-      current_thread = find_any_thread_of_pid (pid);
+      cs->ss->current_thread = find_any_thread_of_pid (pid);

        strcpy (buf, "close");

        run_inferior_command (buf, strlen (buf) + 1);

-      current_thread = saved_thread;
+      cs->ss->current_thread = saved_thread;
      }
  }

@@ -3984,7 +3986,9 @@  gdb_agent_about_to_close (int pid)
  static void
  cmd_qtminftpilen (char *packet)
  {
-  if (current_thread == NULL)
+  client_state *cs = get_client_state();
+
+  if (cs->ss->current_thread == NULL)
      {
        /* Indicate that the minimum length is currently unknown.  */
        strcpy (packet, "0");
@@ -6833,6 +6837,7 @@  static struct ltt_available_probe gdb_ust_probe =
  static int
  run_inferior_command (char *cmd, int len)
  {
+  client_state *cs = get_client_state();
    int err = -1;
    int pid = ptid_get_pid (current_ptid);

diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c
index a242f7258af..04e8b13c66f 100644
--- a/gdb/gdbserver/win32-i386-low.c
+++ b/gdb/gdbserver/win32-i386-low.c
@@ -54,7 +54,7 @@  x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
    gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);

    /* Only update the threads of this process.  */
-  for_each_thread (current_thread->id.pid (), update_debug_registers);
+  for_each_thread (cs->ss->current_thread->id.pid (), 
update_debug_registers);
  }

  /* Update the inferior's DR7 debug control register from STATE.  */
@@ -63,7 +63,7 @@  static void
  x86_dr_low_set_control (unsigned long control)
  {
    /* Only update the threads of this process.  */
-  for_each_thread (current_thread->id.pid (), update_debug_registers);
+  for_each_thread (cs->ss->current_thread->id.pid (), 
update_debug_registers);
  }

  /* Return the current value of a DR register of the current thread's
@@ -73,7 +73,7 @@  static DWORD64
  win32_get_current_dr (int dr)
  {
    win32_thread_info *th
-    = (win32_thread_info *) thread_target_data (current_thread);
+    = (win32_thread_info *) thread_target_data (cs->ss->current_thread);

    win32_require_context (th);

diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index b1d9b51e533..9ae5829d546 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -242,7 +242,7 @@  static void
  child_delete_thread (DWORD pid, DWORD tid)
  {
    /* If the last thread is exiting, just return.  */
-  if (all_threads.size () == 1)
+  if (cs->ss->all_threads.size () == 1)
      return;

    thread_info *thread = find_thread_ptid (ptid_t (pid, tid));
@@ -622,7 +622,7 @@  Could not convert the expanded inferior cwd to 
wide-char."));
     process with the process list.  */
  static int
  win32_create_inferior (const char *program,
-		       const std::vector<char *> &program_args)
+		       const std::vector<char *> &cs->program_args)
  {
  #ifndef USE_WIN32API
    char real_path[PATH_MAX];
@@ -634,7 +634,7 @@  win32_create_inferior (const char *program,
    int argc;
    PROCESS_INFORMATION pi;
    DWORD err;
-  std::string str_program_args = stringify_argv (program_args);
+  std::string str_program_args = stringify_argv (cs->program_args);
    char *args = (char *) str_program_args.c_str ();

    /* win32_wait needs to know we're not attaching.  */
@@ -776,7 +776,7 @@  handle_output_debug_string (void)

    if (!startswith (s, "cYg"))
      {
-      if (!server_waiting)
+      if (!cs->server_waiting)
  	{
  	  OUTMSG2(("%s", s));
  	  return;
@@ -1472,7 +1472,7 @@  get_child_debug_event (struct target_waitstatus 
*ourstatus)
        child_delete_thread (current_event.dwProcessId,
  			   current_event.dwThreadId);

-      current_thread = get_first_thread ();
+      cs->ss->current_thread = get_first_thread ();
        return 1;

      case CREATE_PROCESS_DEBUG_EVENT:
@@ -1570,7 +1570,7 @@  get_child_debug_event (struct target_waitstatus 
*ourstatus)
      }

    ptid = debug_event_ptid (&current_event);
-  current_thread = find_thread_ptid (ptid);
+  cs->ss->current_thread = find_thread_ptid (ptid);
    return 1;
  }

@@ -1610,7 +1610,7 @@  win32_wait (ptid_t ptid, struct target_waitstatus 
*ourstatus, int options)
  	  OUTMSG2 (("Child Stopped with signal = %d \n",
  		    ourstatus->value.sig));

-	  regcache = get_thread_regcache (current_thread, 1);
+	  regcache = get_thread_regcache (cs->ss->current_thread, 1);
  	  child_fetch_inferior_registers (regcache, -1);
  	  return debug_event_ptid (&current_event);
  	default:
diff --git a/gdb/gnulib/import/error.c b/gdb/gnulib/import/error.c
index b3b1286a350..1d151112ca5 100644
--- a/gdb/gnulib/import/error.c
+++ b/gdb/gnulib/import/error.c
@@ -65,7 +65,7 @@  unsigned int error_message_count;
  #ifdef _LIBC
  /* In the GNU C library, there is a predefined variable for this.  */

-# define program_name program_invocation_name
+# define cs->program_name program_invocation_name
  # include <errno.h>
  # include <limits.h>
  # include <libio/libioP.h>
@@ -115,7 +115,7 @@  int strerror_r ();
  #  endif
  # endif

-#define program_name getprogname ()
+#define cs->program_name getprogname ()

  # if HAVE_STRERROR_R || defined strerror_r
  #  define __strerror_r strerror_r
@@ -310,9 +310,9 @@  error (int status, int errnum, const char *message, ...)
    else
      {
  #if _LIBC
-      __fxprintf (NULL, "%s: ", program_name);
+      __fxprintf (NULL, "%s: ", cs->program_name);
  #else
-      fprintf (stderr, "%s: ", program_name);
+      fprintf (stderr, "%s: ", cs->program_name);
  #endif
      }

@@ -372,9 +372,9 @@  error_at_line (int status, int errnum, const char 
*file_name,
    else
      {
  #if _LIBC
-      __fxprintf (NULL, "%s:", program_name);
+      __fxprintf (NULL, "%s:", cs->program_name);
  #else
-      fprintf (stderr, "%s:", program_name);
+      fprintf (stderr, "%s:", cs->program_name);
  #endif
      }

diff --git a/gdb/nat/linux-personality.h b/gdb/nat/linux-personality.h
index 229cc3ef1c9..3f2e0724c49 100644
--- a/gdb/nat/linux-personality.h
+++ b/gdb/nat/linux-personality.h
@@ -27,7 +27,7 @@  public:
    /* Disable the inferior's address space randomization if
       DISABLE_RANDOMIZATION is not zero and if we have
       <sys/personality.h>. */
-  maybe_disable_address_space_randomization (int disable_randomization);
+  maybe_disable_address_space_randomization (int p_disable_randomization);

    /* On destruction, re-enable address space randomization.  */
    ~maybe_disable_address_space_randomization ();