public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] consolidate gdbserver global data
@ 2015-11-15 16:53 Stan Cox
  2015-11-25 19:05 ` Stan Cox
  0 siblings, 1 reply; 6+ messages in thread
From: Stan Cox @ 2015-11-15 16:53 UTC (permalink / raw)
  To: gdb-patches

This patch consolidates global data into two structures.  Data that is
related to the client is defined in the client_status structure.  Data
that is related to the inferior running under gdbserver is defined in 
the server_status structure.  This delineation is to allow, as a future
expansion, the ability to have multiple clients, for example gdb and
strace, connected to the same inferior.  To maintain source 
compatibility, macros are defined so that global variable references do 
not have to be changed to be structure member references.  To 
accommodate this a few variable names that conflicted were changed. 
Currently set_client_state
sets up a single client state and get_client_state returns it.  Going
forward this infrastructure can be expanded so that multiple clients can
be supported.


gdb/gdbserver/Changelog

	* gdb/nat/linux-personality.h (maybe_disable_address_space_randomization):
	disable_randomization conflicts with client_state macro name below.


gdb/gdbserver/Changelog

	* server.h (struct server_state, struct client_state):  New.
	Move global data items here and remove the extern declarations.
	Add defines for struct members for source compatibility.
	(struct client_states)  New.  Head of client_state list.

	* server.c (cont_thread, server_waiting, extended_protocol)
	(response_needed, exit_requested, run_once, multi_process)
	(report_fork_events, report_vfork_events, report_exec_events)
	(non_stop, swbreak_feature, hwbreak_feature, vCont_supported)
	(disable_randomization, program_argv, wrapper_argv, pass_signals)
	(program_signals, signal_pid, disable_packet_vCont)
	(disable_packet_Tthread, disable_packet_qC)
	(disable_packet_qfThreadInfo, last_status, last_ptid, own_buf)
	(mem_buf):  Moved to struct client_status, struct server_status
	(set_client_state): Set client_states, the head of the struct
	client_state list.
	(get_client_state): Return the current client_state.
	(handle_qxfer_btrace, resume):  Global own_buf now own_buffer
	Global last_status now last_waitstatus.  (Change all references)
	(captured_main):  Move initialization to set_client_state.

	* (remote-utils.c, remote-utils.h)  Make get_remote_desc available
	for grabbing a client's file descriptor.

	* linux-low.c:  Global last_status now last_waitstatus.  (Change all)

	* inferiors.h (all_processes, all_threads, current_thread)  Move
	to client_status

	* gdbthread.h (last_status):  Now known as last_waitstatus.


diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index d6959f4..004c334 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -37,7 +37,7 @@ struct thread_info
    enum resume_kind last_resume_kind;

    /* The last wait status reported for this thread.  */
-  struct target_waitstatus last_status;
+  struct target_waitstatus last_waitstatus;

    /* True if LAST_STATUS hasn't been reported to GDB yet.  */
    int status_pending_p;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 72a3ef1..ab80a96 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -22,10 +22,6 @@
  #include "gdbthread.h"
  #include "dll.h"

-struct inferior_list all_processes;
-struct inferior_list all_threads;
-
-struct thread_info *current_thread;

  #define get_thread(inf) ((struct thread_info *)(inf))

@@ -109,7 +105,7 @@ add_thread (ptid_t thread_id, void *target_data)

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

    add_inferior_to_list (&all_threads, &new_thread->entry);

diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index d722616..d457a35 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -84,8 +84,6 @@ struct process_info
  struct process_info *current_process (void);
  struct process_info *get_thread_process (struct thread_info *);

-extern struct inferior_list all_processes;
-
  void add_inferior_to_list (struct inferior_list *list,
  			   struct inferior_list_entry *new_inferior);
  void for_each_inferior (struct inferior_list *list,
@@ -122,7 +120,6 @@ int one_inferior_p (struct inferior_list *list);
  #define ALL_PROCESSES(cur, tmp)					\
    ALL_INFERIORS_TYPE (struct process_info, &all_processes, cur, tmp)

-extern struct thread_info *current_thread;
  void remove_inferior (struct inferior_list *list,
  		      struct inferior_list_entry *entry);

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 41ab510..b4724a0 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -506,7 +506,7 @@ handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
  	  child_lwp->status_pending_p = 0;
  	  child_thr = get_lwp_thread (child_lwp);
  	  child_thr->last_resume_kind = resume_stop;
-	  child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
+	  child_thr->last_waitstatus.kind = TARGET_WAITKIND_STOPPED;

  	  /* If we're suspending all threads, leave this one suspended
  	     too.  */
@@ -626,7 +626,7 @@ handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
        event_lwp->status_pending_p = 1;
        event_lwp->status_pending = wstat;
        event_thr->last_resume_kind = resume_continue;
-      event_thr->last_status.kind = TARGET_WAITKIND_IGNORE;
+      event_thr->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;

        /* Report the event.  */
        *orig_event_lwp = event_lwp;
@@ -1272,13 +1272,13 @@ get_detach_signal (struct thread_info *thread)
        /* If the thread had been suspended by gdbserver, and it stopped
  	 cleanly, then it'll have stopped with SIGSTOP.  But we don't
  	 want to deliver that SIGSTOP.  */
-      if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-	  || thread->last_status.value.sig == GDB_SIGNAL_0)
+      if (thread->last_waitstatus.kind != TARGET_WAITKIND_STOPPED
+	  || thread->last_waitstatus.value.sig == GDB_SIGNAL_0)
  	return 0;

        /* Otherwise, we may need to deliver the signal we
  	 intercepted.  */
-      status = lp->last_status;
+      status = lp->last_waitstatus;
      }

    if (!WIFSTOPPED (status))
@@ -1489,7 +1489,7 @@ thread_still_has_status_pending_p (struct 
thread_info *thread)
    /* If we got a `vCont;t', but we haven't reported a stop yet, do
       report any status pending the LWP may have.  */
    if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+      && thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE)
      return 0;

    if (thread->last_resume_kind != resume_stop
@@ -1500,7 +1500,7 @@ thread_still_has_status_pending_p (struct 
thread_info *thread)
        CORE_ADDR pc;
        int discard = 0;

-      gdb_assert (lp->last_status != 0);
+      gdb_assert (lp->last_waitstatus != 0);

        pc = get_pc (lp);

@@ -2218,7 +2218,7 @@ linux_low_filter_event (int lwpid, int wstat)

    child->stopped = 1;

-  child->last_status = wstat;
+  child->last_waitstatus = wstat;

    /* Check if the thread has exited.  */
    if ((WIFEXITED (wstat) || WIFSIGNALED (wstat)))
@@ -2379,7 +2379,7 @@ resume_stopped_resumed_lwps (struct 
inferior_list_entry *entry)
        && !lp->suspended
        && !lp->status_pending_p
        && thread->last_resume_kind != resume_stop
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE)
      {
        int step = thread->last_resume_kind == resume_step;

@@ -2628,7 +2628,7 @@ count_events_callback (struct inferior_list_entry 
*entry, void *data)
    gdb_assert (count != NULL);

    /* Count only resumed LWPs that have an event pending. */
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE
        && lp->status_pending_p)
      (*count)++;

@@ -2643,7 +2643,7 @@ select_singlestep_lwp_callback (struct 
inferior_list_entry *entry, void *data)
    struct thread_info *thread = (struct thread_info *) entry;
    struct lwp_info *lp = get_thread_lwp (thread);

-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE
        && thread->last_resume_kind == resume_step
        && lp->status_pending_p)
      return 1;
@@ -2663,7 +2663,7 @@ select_event_lwp_callback (struct 
inferior_list_entry *entry, void *data)
    gdb_assert (selector != NULL);

    /* Select only resumed LWPs that have an event pending. */
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE
        && lp->status_pending_p)
      if ((*selector)-- == 0)
        return 1;
@@ -4165,7 +4165,7 @@ linux_set_resume_request (struct 
inferior_list_entry *entry, void *arg)
  	    {
  	      if (debug_threads)
  		debug_printf ("already %s LWP %ld at GDB's request\n",
-			      (thread->last_status.kind
+			      (thread->last_waitstatus.kind
  			       == TARGET_WAITKIND_STOPPED)
  			      ? "stopped"
  			      : "stopping",
@@ -4570,7 +4570,7 @@ linux_resume_one_thread (struct 
inferior_list_entry *entry, void *arg)

        /* For stop requests, we're done.  */
        lwp->resume = NULL;
-      thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+      thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;
        return 0;
      }

@@ -4611,8 +4611,8 @@ linux_resume_one_thread (struct 
inferior_list_entry *entry, void *arg)
  	     make sure to queue its siginfo.  We can ignore the return
  	     value of ptrace; if it fails, we'll skip
  	     PTRACE_SETSIGINFO.  */
-	  if (WIFSTOPPED (lwp->last_status)
-	      && WSTOPSIG (lwp->last_status) == lwp->resume->sig)
+	  if (WIFSTOPPED (lwp->last_waitstatus)
+	      && WSTOPSIG (lwp->last_waitstatus) == lwp->resume->sig)
  	    ptrace (PTRACE_GETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
  		    &p_sig->info);

@@ -4620,7 +4620,7 @@ linux_resume_one_thread (struct 
inferior_list_entry *entry, void *arg)
  	}
      }

-  thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+  thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;
    lwp->resume = NULL;
    return 0;
  }
@@ -4719,7 +4719,7 @@ proceed_one_lwp (struct inferior_list_entry 
*entry, void *except)
      }

    if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+      && thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE)
      {
        if (debug_threads)
  	debug_printf ("   client wants LWP to remain %ld stopped\n",
@@ -5498,8 +5498,6 @@ linux_look_up_symbols (void)
  static void
  linux_request_interrupt (void)
  {
-  extern unsigned long signal_pid;
-
    /* Send a SIGINT to the process group.  This acts just like the user
       typed a ^C on the controlling terminal.  */
    kill (-signal_pid, SIGINT);
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index ccf4c94..1d87cd9 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -272,7 +272,7 @@ struct lwp_info
    int stopped;

    /* When stopped is set, the last wait status recorded for this lwp.  */
-  int last_status;
+  int last_waitstatus;

    /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for
       this LWP's last event, to pass to GDB without any further
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index e366091..41ee4b3 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -122,6 +122,19 @@ int transport_is_reliable = 0;
  # define write(fd, buf, len) send (fd, (char *) buf, len, 0)
  #endif

+
+int
+get_remote_desc ()
+{
+  return remote_desc;
+}
+
+void
+set_remote_desc (gdb_fildes_t fd)
+{
+  remote_desc = fd;
+}
+
  int
  gdb_connected (void)
  {
@@ -860,13 +873,6 @@ initialize_async_io (void)
    unblock_async_io ();
  }

-/* 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.  */

@@ -1474,16 +1480,16 @@ look_up_one_symbol (const char *name, CORE_ADDR 
*addrp, int may_ask_gdb)
    while (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);
+      mem_buffer = (unsigned char *) xmalloc (mem_len);
+      if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	bin2hex (mem_buffer, own_buf, mem_len);
        else
  	write_enn (own_buf);
-      free (mem_buf);
+      free (mem_buffer);
        if (putpkt (own_buf) < 0)
  	return -1;
        len = getpkt (own_buf);
@@ -1556,36 +1562,36 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR 
oldloc)
    while (own_buf[0] == 'm' || own_buf[0] == 'M' || 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')
  	{
  	  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);
+	  mem_buffer = (unsigned char *) xmalloc (mem_len);
+	  if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	    bin2hex (mem_buffer, own_buf, mem_len);
  	  else
  	    write_enn (own_buf);
  	}
        else if (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)
+			       &mem_len, &mem_buffer) < 0
+	      || write_inferior_memory (mem_addr, mem_buffer, mem_len) != 0)
  	    write_enn (own_buf);
  	  else
  	    write_ok (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)
+	  decode_M_packet (&own_buf[1], &mem_addr, &mem_len, &mem_buffer);
+	  if (write_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
  	    write_ok (own_buf);
  	  else
  	    write_enn (own_buf);
  	}
-      free (mem_buf);
+      free (mem_buffer);
        if (putpkt (own_buf) < 0)
  	return -1;
        len = getpkt (own_buf);
diff --git a/gdb/gdbserver/remote-utils.h b/gdb/gdbserver/remote-utils.h
index 5fc43f4..2a1c62f 100644
--- a/gdb/gdbserver/remote-utils.h
+++ b/gdb/gdbserver/remote-utils.h
@@ -23,6 +23,9 @@ extern int remote_debug;
  extern int noack_mode;
  extern int transport_is_reliable;

+int get_remote_desc (void);
+void set_remote_desc (gdb_fildes_t);
+
  int gdb_connected (void);

  #define STDIO_CONNECTION_NAME "stdio"
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index fd2804b..e1fa1bc 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -36,55 +36,6 @@
  #include "dll.h"
  #include "hostio.h"

-/* 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;
-
-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 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_argv, **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;

  #ifdef SIGTTOU
  /* A file descriptor for the controlling terminal.  */
@@ -102,21 +53,6 @@ restore_old_foreground_pgrp (void)
  }
  #endif

-/* 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.  */
-int disable_packet_vCont;
-int disable_packet_Tthread;
-int disable_packet_qC;
-int disable_packet_qfThreadInfo;
-
-/* Last status reported to GDB.  */
-static struct target_waitstatus last_status;
-static ptid_t last_ptid;
-
-static 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.  */
@@ -138,6 +74,35 @@ static struct btrace_config current_btrace_conf;

  DEFINE_QUEUE_P (notif_event_p);

+static struct client_states  client_states;
+
+
+/* Add a new client state for FD or return if found */
+
+client_state *
+set_client_state (gdb_fildes_t fd)
+{
+  if (client_states.first == NULL)
+    {
+      client_states.first = XCNEW (client_state);
+      client_states.first->ss = XCNEW (server_state);
+    }
+  client_states.current_fd = fd;
+  client_states.current_cs = client_states.first;
+  own_buffer = (char *) xmalloc (PBUFSIZ + 1);
+  return client_states.first;
+}
+
+
+/* Return the current client state */
+
+client_state *
+get_client_state (void)
+{
+ return client_states.current_cs;
+}
+
+
  /* Put a stop reply to the stop reply queue.  */

  static void
@@ -273,7 +238,7 @@ start_inferior (char **argv)
  		break;

  	      current_thread->last_resume_kind = resume_stop;
-	      current_thread->last_status = last_status;
+	      current_thread->last_waitstatus = last_status;
  	    }
  	  while (last_status.value.sig != GDB_SIGNAL_TRAP);
  	}
@@ -291,7 +256,7 @@ start_inferior (char **argv)
        && last_status.kind != TARGET_WAITKIND_SIGNALLED)
      {
        current_thread->last_resume_kind = resume_stop;
-      current_thread->last_status = last_status;
+      current_thread->last_waitstatus = last_status;
      }
    else
      mourn_inferior (find_process_pid (ptid_get_pid (last_ptid)));
@@ -328,7 +293,7 @@ attach_inferior (int pid)
  	last_status.value.sig = GDB_SIGNAL_TRAP;

        current_thread->last_resume_kind = resume_stop;
-      current_thread->last_status = last_status;
+      current_thread->last_waitstatus = last_status;
      }

    return 0;
@@ -592,6 +557,7 @@ handle_general_set (char *own_buf)
        return;
      }

+
    if (startswith (own_buf, "QProgramSignals:"))
      {
        int numsigs = (int) GDB_SIGNAL_LAST, i;
@@ -1618,20 +1584,20 @@ handle_qxfer_btrace (const char *annex,
    if (ptid_equal (general_thread, null_ptid)
        || ptid_equal (general_thread, minus_one_ptid))
      {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (own_buffer, "E.Must select a single thread.");
        return -3;
      }

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

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

@@ -1643,7 +1609,7 @@ handle_qxfer_btrace (const char *annex,
      type = BTRACE_READ_DELTA;
    else
      {
-      strcpy (own_buf, "E.Bad annex.");
+      strcpy (own_buffer, "E.Bad annex.");
        return -3;
      }

@@ -1654,7 +1620,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 (own_buffer, cache.buffer, cache.used_size);
  	  return -3;
  	}
      }
@@ -1692,20 +1658,20 @@ handle_qxfer_btrace_conf (const char *annex,
    if (ptid_equal (general_thread, null_ptid)
        || ptid_equal (general_thread, minus_one_ptid))
      {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (own_buffer, "E.Must select a single thread.");
        return -3;
      }

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

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

@@ -1716,7 +1682,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 (own_buffer, cache.buffer, cache.used_size);
  	  return -3;
  	}
      }
@@ -2499,9 +2465,9 @@ handle_pending_status (const struct thread_resume 
*resumption,
      {
        thread->status_pending_p = 0;

-      last_status = thread->last_status;
+      last_status = thread->last_waitstatus;
        last_ptid = thread->entry.id;
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      prepare_resume_reply (own_buffer, last_ptid, &last_status);
        return 1;
      }
    return 0;
@@ -2640,7 +2606,7 @@ resume (struct thread_resume *actions, size_t 
num_actions)
    (*the_target->resume) (actions, num_actions);

    if (non_stop)
-    write_ok (own_buf);
+    write_ok (own_buffer);
    else
      {
        last_ptid = mywait (minus_one_ptid, &last_status, 0, 1);
@@ -2649,7 +2615,7 @@ resume (struct thread_resume *actions, size_t 
num_actions)
  	{
  	  /* No proper RSP support for this yet.  At least return
  	     error.  */
-	  sprintf (own_buf, "E.No unwaited-for children left.");
+	  sprintf (own_buffer, "E.No unwaited-for children left.");
  	  disable_async_io ();
  	  return;
  	}
@@ -2657,14 +2623,14 @@ resume (struct thread_resume *actions, size_t 
num_actions)
        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;
+	current_thread->last_waitstatus = 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 (own_buffer, last_ptid, &last_status);
        disable_async_io ();

        if (last_status.kind == TARGET_WAITKIND_EXITED
@@ -2957,7 +2923,7 @@ queue_stop_reply_callback (struct 
inferior_list_entry *entry, void *arg)
        struct vstop_notif *new_notif = XNEW (struct vstop_notif);

        new_notif->ptid = entry->id;
-      new_notif->status = thread->last_status;
+      new_notif->status = thread->last_waitstatus;
        /* Pass the last stop reply back to GDB, but don't notify
  	 yet.  */
        notif_event_enque (&notif_stop,
@@ -2970,7 +2936,7 @@ queue_stop_reply_callback (struct 
inferior_list_entry *entry, void *arg)
  	  if (debug_threads)
  	    {
  	      char *status_string
-		= target_waitstatus_to_string (&thread->last_status);
+		= target_waitstatus_to_string (&thread->last_waitstatus);

  	      debug_printf ("Reporting thread %s as already stopped with %s\n",
  			    target_pid_to_str (entry->id),
@@ -2979,11 +2945,11 @@ queue_stop_reply_callback (struct 
inferior_list_entry *entry, void *arg)
  	      xfree (status_string);
  	    }

-	  gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
+	  gdb_assert (thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE);

  	  /* Pass the last stop reply back to GDB, but don't notify
  	     yet.  */
-	  queue_stop_reply (entry->id, &thread->last_status);
+	  queue_stop_reply (entry->id, &thread->last_waitstatus);
  	}
      }

@@ -3001,12 +2967,12 @@ gdb_wants_thread_stopped (struct 
inferior_list_entry *entry)

    thread->last_resume_kind = resume_stop;

-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE)
      {
        /* Most threads are stopped implicitly (all-stop); tag that with
  	 signal 0.  */
-      thread->last_status.kind = TARGET_WAITKIND_STOPPED;
-      thread->last_status.value.sig = GDB_SIGNAL_0;
+      thread->last_waitstatus.kind = TARGET_WAITKIND_STOPPED;
+      thread->last_waitstatus.value.sig = GDB_SIGNAL_0;
      }
  }

@@ -3047,15 +3013,15 @@ set_pending_status_callback (struct 
inferior_list_entry *entry)
  {
    struct thread_info *thread = (struct thread_info *) entry;

-  if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-      || (thread->last_status.value.sig != GDB_SIGNAL_0
+  if (thread->last_waitstatus.kind != TARGET_WAITKIND_STOPPED
+      || (thread->last_waitstatus.value.sig != GDB_SIGNAL_0
  	  /* A breakpoint, watchpoint or finished step from a previous
  	     GDB run isn't considered interesting for a new GDB run.
  	     If we left those pending, the new GDB could consider them
  	     random SIGTRAPs.  This leaves out real async traps.  We'd
  	     have to peek into the (target-specific) siginfo to
  	     distinguish those.  */
-	  && thread->last_status.value.sig != GDB_SIGNAL_TRAP))
+	  && thread->last_waitstatus.value.sig != GDB_SIGNAL_TRAP))
      thread->status_pending_p = 1;
  }

@@ -3138,8 +3104,8 @@ handle_status (char *own_buf)
  	  general_thread = thread->id;
  	  set_desired_thread (1);

-	  gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
-	  prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
+	  gdb_assert (tp->last_waitstatus.kind != TARGET_WAITKIND_IGNORE);
+	  prepare_resume_reply (own_buf, tp->entry.id, &tp->last_waitstatus);
  	}
        else
  	strcpy (own_buf, "W00");
@@ -3366,6 +3332,11 @@ 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();
+  set_client_state (remote_desc);

    while (*next_arg != NULL && **next_arg == '-')
      {
@@ -3462,11 +3433,11 @@ 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, "--once") == 0)
-	run_once = 1;
+	run_once_arg = 1;
        else
  	{
  	  fprintf (stderr, "Unknown argument: %s\n", *next_arg);
@@ -3477,6 +3448,10 @@ captured_main (int argc, char *argv[])
        continue;
      }

+  run_once = run_once_arg;
+  disable_randomization = disable_randomization_arg;
+  program_argv = NULL;
+
    port = *next_arg;
    next_arg++;
    if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
@@ -3527,7 +3502,6 @@ captured_main (int argc, char *argv[])
      initialize_tracepoint ();
    initialize_notif ();

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

    if (pid == 0 && *next_arg != NULL)
@@ -3580,10 +3554,6 @@ captured_main (int argc, char *argv[])
      {

        noack_mode = 0;
-      multi_process = 0;
-      report_fork_events = 0;
-      report_vfork_events = 0;
-      report_exec_events = 0;
        /* Be sure we're out of tfind mode.  */
        current_traceframe = -1;
        cont_thread = null_ptid;
@@ -3653,8 +3623,8 @@ captured_main (int argc, char *argv[])

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

  	  if (run_once)
@@ -3779,7 +3749,7 @@ process_serial_event (void)
    disable_async_io ();

    response_needed = 0;
-  packet_len = getpkt (own_buf);
+  packet_len = getpkt (own_buffer);
    if (packet_len <= 0)
      {
        remote_close ();
@@ -3789,22 +3759,22 @@ process_serial_event (void)
    response_needed = 1;

    i = 0;
-  ch = own_buf[i++];
+  ch = own_buffer[i++];
    switch (ch)
      {
      case 'q':
-      handle_query (own_buf, packet_len, &new_packet_len);
+      handle_query (own_buffer, packet_len, &new_packet_len);
        break;
      case 'Q':
-      handle_general_set (own_buf);
+      handle_general_set (own_buffer);
        break;
      case 'D':
-      require_running (own_buf);
+      require_running (own_buffer);

        if (multi_process)
  	{
  	  i++; /* skip ';' */
-	  pid = strtol (&own_buf[i], NULL, 16);
+	  pid = strtol (&own_buffer[i], NULL, 16);
  	}
        else
  	pid = ptid_get_pid (current_ptid);
@@ -3816,7 +3786,7 @@ process_serial_event (void)

  	  if (process == NULL)
  	    {
-	      write_enn (own_buf);
+	      write_enn (own_buffer);
  	      break;
  	    }

@@ -3852,18 +3822,18 @@ process_serial_event (void)
  	  resume_info.sig = 0;
  	  (*the_target->resume) (&resume_info, 1);

-	  write_ok (own_buf);
+	  write_ok (own_buffer);
  	  break; /* from switch/case */
  	}

        fprintf (stderr, "Detaching from process %d\n", pid);
        stop_tracing ();
        if (detach_inferior (pid) != 0)
-	write_enn (own_buf);
+	write_enn (own_buffer);
        else
  	{
  	  discard_queued_stop_replies (pid_to_ptid (pid));
-	  write_ok (own_buf);
+	  write_ok (own_buffer);

  	  if (extended_protocol)
  	    {
@@ -3876,7 +3846,7 @@ process_serial_event (void)
  	    }
  	  else
  	    {
-	      putpkt (own_buf);
+	      putpkt (own_buffer);
  	      remote_close ();

  	      /* If we are attached, then we can exit.  Otherwise, we
@@ -3889,20 +3859,20 @@ process_serial_event (void)
        break;
      case '!':
        extended_protocol = 1;
-      write_ok (own_buf);
+      write_ok (own_buffer);
        break;
      case '?':
-      handle_status (own_buf);
+      handle_status (own_buffer);
        break;
      case 'H':
-      if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
+      if (own_buffer[1] == 'c' || own_buffer[1] == 'g' || own_buffer[1] 
== 's')
  	{
  	  ptid_t gdb_id, thread_id;
  	  int pid;

-	  require_running (own_buf);
+	  require_running (own_buffer);

-	  gdb_id = read_ptid (&own_buf[2], NULL);
+	  gdb_id = read_ptid (&own_buffer[2], NULL);

  	  pid = ptid_get_pid (gdb_id);

@@ -3919,7 +3889,7 @@ process_serial_event (void)
  						      &pid);
  	      if (!thread)
  		{
-		  write_enn (own_buf);
+		  write_enn (own_buffer);
  		  break;
  		}

@@ -3930,12 +3900,12 @@ process_serial_event (void)
  	      thread_id = gdb_id_to_thread_id (gdb_id);
  	      if (ptid_equal (thread_id, null_ptid))
  		{
-		  write_enn (own_buf);
+		  write_enn (own_buffer);
  		  break;
  		}
  	    }

-	  if (own_buf[1] == 'g')
+	  if (own_buffer[1] == 'g')
  	    {
  	      if (ptid_equal (thread_id, null_ptid))
  		{
@@ -3954,20 +3924,20 @@ process_serial_event (void)
  	      set_desired_thread (1);
  	      gdb_assert (current_thread != NULL);
  	    }
-	  else if (own_buf[1] == 'c')
+	  else if (own_buffer[1] == 'c')
  	    cont_thread = thread_id;

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

  	  if (fetch_traceframe_registers (current_traceframe,
  					  regcache, -1) == 0)
-	    registers_to_string (regcache, own_buf);
+	    registers_to_string (regcache, own_buffer);
  	  else
-	    write_enn (own_buf);
+	    write_enn (own_buffer);
  	  free_register_cache (regcache);
  	}
        else
@@ -3985,85 +3955,85 @@ process_serial_event (void)
  	  struct regcache *regcache;

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

  	  if (!set_desired_thread (1))
-	    write_enn (own_buf);
+	    write_enn (own_buffer);
  	  else
  	    {
  	      regcache = get_thread_regcache (current_thread, 1);
-	      registers_from_string (regcache, &own_buf[1]);
-	      write_ok (own_buf);
+	      registers_from_string (regcache, &own_buffer[1]);
+	      write_ok (own_buffer);
  	    }
  	}
        break;
      case 'm':
-      require_running (own_buf);
-      decode_m_packet (&own_buf[1], &mem_addr, &len);
+      require_running (own_buffer);
+      decode_m_packet (&own_buffer[1], &mem_addr, &len);
        res = gdb_read_memory (mem_addr, mem_buf, len);
        if (res < 0)
-	write_enn (own_buf);
+	write_enn (own_buffer);
        else
-	bin2hex (mem_buf, own_buf, res);
+	bin2hex (mem_buf, own_buffer, res);
        break;
      case 'M':
-      require_running (own_buf);
-      decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
+      require_running (own_buffer);
+      decode_M_packet (&own_buffer[1], &mem_addr, &len, &mem_buf);
        if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
-	write_ok (own_buf);
+	write_ok (own_buffer);
        else
-	write_enn (own_buf);
+	write_enn (own_buffer);
        break;
      case 'X':
-      require_running (own_buf);
-      if (decode_X_packet (&own_buf[1], packet_len - 1,
+      require_running (own_buffer);
+      if (decode_X_packet (&own_buffer[1], packet_len - 1,
  			   &mem_addr, &len, &mem_buf) < 0
  	  || gdb_write_memory (mem_addr, mem_buf, len) != 0)
-	write_enn (own_buf);
+	write_enn (own_buffer);
        else
-	write_ok (own_buf);
+	write_ok (own_buffer);
        break;
      case 'C':
-      require_running (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running (own_buffer);
+      hex2bin (own_buffer + 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 (own_buffer, 0, signal);
        break;
      case 'S':
-      require_running (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running (own_buffer);
+      hex2bin (own_buffer + 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 (own_buffer, 1, signal);
        break;
      case 'c':
-      require_running (own_buf);
+      require_running (own_buffer);
        signal = 0;
-      myresume (own_buf, 0, signal);
+      myresume (own_buffer, 0, signal);
        break;
      case 's':
-      require_running (own_buf);
+      require_running (own_buffer);
        signal = 0;
-      myresume (own_buf, 1, signal);
+      myresume (own_buffer, 1, signal);
        break;
      case 'Z':  /* insert_ ... */
        /* Fallthrough.  */
@@ -4072,10 +4042,10 @@ process_serial_event (void)
  	char *dataptr;
  	ULONGEST addr;
  	int kind;
-	char type = own_buf[1];
+	char type = own_buffer[1];
  	int res;
  	const int insert = ch == 'Z';
-	char *p = &own_buf[3];
+	char *p = &own_buffer[3];

  	p = unpack_varlen_hex (p, &addr);
  	kind = strtol (p + 1, &dataptr, 16);
@@ -4102,12 +4072,12 @@ process_serial_event (void)
  	  res = delete_gdb_breakpoint (type, addr, kind);

  	if (res == 0)
-	  write_ok (own_buf);
+	  write_ok (own_buffer);
  	else if (res == 1)
  	  /* Unsupported.  */
-	  own_buf[0] = '\0';
+	  own_buffer[0] = '\0';
  	else
-	  write_enn (own_buf);
+	  write_enn (own_buffer);
  	break;
        }
      case 'k':
@@ -4135,20 +4105,20 @@ process_serial_event (void)
        {
  	ptid_t gdb_id, thread_id;

-	require_running (own_buf);
+	require_running (own_buffer);

-	gdb_id = read_ptid (&own_buf[1], NULL);
+	gdb_id = read_ptid (&own_buffer[1], NULL);
  	thread_id = gdb_id_to_thread_id (gdb_id);
  	if (ptid_equal (thread_id, null_ptid))
  	  {
-	    write_enn (own_buf);
+	    write_enn (own_buffer);
  	    break;
  	  }

  	if (mythread_alive (thread_id))
-	  write_ok (own_buf);
+	  write_ok (own_buffer);
  	else
-	  write_enn (own_buf);
+	  write_enn (own_buffer);
        }
        break;
      case 'R':
@@ -4191,26 +4161,26 @@ 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';
+	  own_buffer[0] = '\0';
  	  break;
  	}
      case 'v':
        /* Extended (long) request.  */
-      handle_v_requests (own_buf, packet_len, &new_packet_len);
+      handle_v_requests (own_buffer, packet_len, &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';
+      own_buffer[0] = '\0';
        break;
      }

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

    response_needed = 0;

@@ -4287,7 +4257,7 @@ handle_target_event (int err, gdb_client_data 
client_data)
  	     "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;
+	  current_thread->last_waitstatus = last_status;
  	}

        if (forward_event)
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 96ad4fa..d634ff8 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -67,42 +67,6 @@ int vsnprintf(char *str, size_t size, const char 
*format, va_list ap);

  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 int run_once;
-extern int multi_process;
-extern int report_fork_events;
-extern int report_vfork_events;
-extern int report_exec_events;
-extern int non_stop;
-extern int extended_protocol;
-
-/* 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;
@@ -134,3 +98,143 @@ extern void discard_queued_stop_replies (ptid_t ptid);
  #define PBUFSIZ 16384

  #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
+{
+  /* 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_;
+  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 */
+  struct inferior_list all_processes_;
+  struct inferior_list all_threads_;
+  struct thread_info *current_thread_;
+};
+
+typedef struct server_state server_state;
+
+struct client_state
+{
+  /* 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 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_;
+
+  int disable_packet_vCont_;
+  int disable_packet_Tthread_;
+  int disable_packet_qC_;
+  int disable_packet_qfThreadInfo_;
+
+  char **program_argv_, **wrapper_argv_;
+
+  int pass_signals_[GDB_SIGNAL_LAST];
+  int program_signals_[GDB_SIGNAL_LAST];
+  int program_signals_p_;
+  char *own_buffer_;
+  server_state *ss;
+};
+
+typedef struct client_state client_state;
+
+struct client_states
+{
+  client_state *first;
+  client_state *current_cs;
+  gdb_fildes_t current_fd;
+};
+
+client_state * get_client_state ();
+
+#define cont_thread	(get_client_state()->ss->cont_thread_)
+#define general_thread	(get_client_state()->ss->general_thread_)
+#define signal_pid	(get_client_state()->ss->signal_pid_)
+#define last_status	(get_client_state()->ss->last_status_)
+#define last_ptid	(get_client_state()->ss->last_ptid_)
+#define mem_buf		(get_client_state()->ss->mem_buf_)
+#define readchar_buf	(get_client_state()->ss->readchar_buf_)
+#define readchar_bufcnt	(get_client_state()->ss->readchar_bufcnt_)
+#define readchar_bufp	(get_client_state()->ss->readchar_bufp_)
+#define all_processes  	(get_client_state()->ss->all_processes_)
+#define all_threads	(get_client_state()->ss->all_threads_)
+#define current_thread   (get_client_state()->ss->current_thread_)
+#define server_waiting	(get_client_state()->server_waiting_)
+#define extended_protocol	(get_client_state()->extended_protocol_)
+#define response_needed	(get_client_state()->response_needed_)
+#define exit_requested	(get_client_state()->exit_requested_)
+#define run_once	(get_client_state()->run_once_)
+#define multi_process	(get_client_state()->multi_process_)
+#define report_fork_events	(get_client_state()->report_fork_events_)
+#define report_vfork_events	(get_client_state()->report_vfork_events_)
+#define report_exec_events	(get_client_state()->report_exec_events_)
+#define non_stop	(get_client_state()->non_stop_)
+#define swbreak_feature	(get_client_state()->swbreak_feature_)
+#define hwbreak_feature	(get_client_state()->hwbreak_feature_)
+#define vCont_supported (get_client_state()->vCont_supported_)
+#define disable_randomization	(get_client_state()->disable_randomization_)
+#define disable_packet_vCont (get_client_state()->disable_packet_vCont_)
+#define disable_packet_Tthread 
(get_client_state()->disable_packet_Tthread_)
+#define disable_packet_qC (get_client_state()->disable_packet_qC_)
+#define disable_packet_qfThreadInfo 
(get_client_state()->disable_packet_qfThreadInfo_)
+#define program_argv	(get_client_state()->program_argv_)
+#define wrapper_argv	(get_client_state()->wrapper_argv_)
+#define pass_signals	(get_client_state()->pass_signals_)
+#define program_signals	(get_client_state()->program_signals_)
+#define program_signals_p	(get_client_state()->program_signals_p_)
+#define own_buffer	(get_client_state()->own_buffer_)
diff --git a/gdb/nat/linux-personality.h b/gdb/nat/linux-personality.h
index 009e614..5f7fa8b 100644
--- a/gdb/nat/linux-personality.h
+++ b/gdb/nat/linux-personality.h
@@ -26,6 +26,6 @@
     re-enable the inferior's address space randomization.  */

  extern struct cleanup *maybe_disable_address_space_randomization
-  (int disable_randomization);
+  (int disable_randomization_p);

  #endif /* ! NAT_LINUX_PERSONALITY_H */

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] consolidate gdbserver global data
  2015-11-15 16:53 [PATCH] consolidate gdbserver global data Stan Cox
@ 2015-11-25 19:05 ` Stan Cox
  2015-12-17 21:06   ` [PATCH v2 1/2] " Stan Cox
  2015-12-17 21:15   ` [PATCH v2 2/2] " Stan Cox
  0 siblings, 2 replies; 6+ messages in thread
From: Stan Cox @ 2015-11-25 19:05 UTC (permalink / raw)
  To: gdb-patches

Any thoughts/comments on this patch that consolidates gdbserver external 
data as shown in this example?

(gdb) print *cs
$2 = {server_waiting_ = 0,
   extended_protocol_ = 1, response_needed_ = 1, exit_requested_ = 0, 
run_once_ = 0, multi_process_ = 1, report_fork_events_ = 1,
   report_vfork_events_ = 1, non_stop_ = 1, swbreak_feature_ = 1, 
hwbreak_feature_ = 1, disable_randomization_ = 1,
   program_argv_ = 0x682840, wrapper_argv_ = 0x0, packet_length_ = 16, 
pass_signals_ =     {0 <repeats 14 times>,
   in_buffer_ = 0x6833c0 "vCont;t:p6feb.-1ו\225\225\225\225", 
<incomplete sequence \327>, own_buffer_ = 0x689fa0 "OK",
   client_breakpoints = 0x0, ss = 0x680430, next = 0x0}

(gdb) print *cs->ss
$3 = {attach_count_ = 1, cont_thread_ = {pid = 0, lwp = 0, tid = 0}, 
general_thread_ = {pid = 28651, lwp = 28651, tid = 0},
   signal_pid_ = 28651, last_status_ = {kind = 
TARGET_WAITKIND_NO_RESUMED, value = {integer = 5, sig = GDB_SIGNAL_TRAP,
       related_pid = {pid = 5, lwp = 0, tid = 0}, execd_pathname = 0x5,
       syscall_number = 5}}, last_ptid_ = {pid = 0, lwp = 0, tid = 0},
   mem_buf_ = 0x67bc70 ,
   readchar_buf_ =  "$vCont;t:p6feb.-1#52:64bit-avx.xml:",
   readchar_bufp_ = 0x6804c4 ":64bit-avx.xml:0,fff#1bfc;",
   all_processes_ = {head = 0x682a80, tail = 0x682a80},
   all_threads_ = {head = 0x682cb0, tail = 0x682cb0},
   current_thread_ = 0x682cb0}


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/2] consolidate gdbserver global data
  2015-11-25 19:05 ` Stan Cox
@ 2015-12-17 21:06   ` Stan Cox
  2015-12-17 21:15   ` [PATCH v2 2/2] " Stan Cox
  1 sibling, 0 replies; 6+ messages in thread
From: Stan Cox @ 2015-12-17 21:06 UTC (permalink / raw)
  To: gdb-patches

The previous patch was split into two parts to hopefully make it a bit 
easier to digest.  This first patch simply changes a few variable names 
that conflict with the names of gdbserver external data variables. 
Those conflicts are:
  - struct thread_info member last_status
    renamed to last_waitstatus
  - various local variables mem_buf
    renamed to mem_buffer
  - a parameter in nat/linux-personality.h disable_randomization
    renamed to disable_randomization
  - the external data variable own_buf
    renamed to own_buffer
    to avoid conflicts with a frequently used local variable own_buf
The next patch consolidates global data into structures.  To maintain 
source compatibility, macros are defined such that, e.g. out_buf will 
logically expand to client_state->out_buf.  The above name changes will 
avoid name conflicts.

gdb/gdbserver/Changelog

     * server.c (handle_qxfer_btrace, resume):  Global own_buf now 
own_buffer
     thread_info last_status now last_waitstatus.  (Change all references)

     * remote-utils.c Local mem_buf name mem_buffer.  (Change all)

     * linux-low.c:  Global last_status now last_waitstatus.  (Change all)

     * gdbthread.h (last_status):  Now known as last_waitstatus.



diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index 0510419..7bada2f 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -37,7 +37,7 @@ struct thread_info
    enum resume_kind last_resume_kind;

    /* The last wait status reported for this thread.  */
-  struct target_waitstatus last_status;
+  struct target_waitstatus last_waitstatus;

    /* True if LAST_STATUS hasn't been reported to GDB yet.  */
    int status_pending_p;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 95f3ad0..4d64250 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -109,7 +109,7 @@ add_thread (ptid_t thread_id, void *target_data)

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

    add_inferior_to_list (&all_threads, &new_thread->entry);

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 5e2dc58..1f0a977 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -520,7 +520,7 @@ handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
  	  child_lwp->status_pending_p = 0;
  	  child_thr = get_lwp_thread (child_lwp);
  	  child_thr->last_resume_kind = resume_stop;
-	  child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
+	  child_thr->last_waitstatus.kind = TARGET_WAITKIND_STOPPED;

  	  /* If we're suspending all threads, leave this one suspended
  	     too.  */
@@ -646,7 +646,7 @@ handle_extended_wait (struct lwp_info 
**orig_event_lwp, int wstat)
        event_lwp->status_pending_p = 1;
        event_lwp->status_pending = wstat;
        event_thr->last_resume_kind = resume_continue;
-      event_thr->last_status.kind = TARGET_WAITKIND_IGNORE;
+      event_thr->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;

        /* Report the event.  */
        *orig_event_lwp = event_lwp;
@@ -1342,13 +1342,13 @@ get_detach_signal (struct thread_info *thread)
        /* If the thread had been suspended by gdbserver, and it stopped
  	 cleanly, then it'll have stopped with SIGSTOP.  But we don't
  	 want to deliver that SIGSTOP.  */
-      if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-	  || thread->last_status.value.sig == GDB_SIGNAL_0)
+      if (thread->last_waitstatus.kind != TARGET_WAITKIND_STOPPED
+	  || thread->last_waitstatus.value.sig == GDB_SIGNAL_0)
  	return 0;

        /* Otherwise, we may need to deliver the signal we
  	 intercepted.  */
-      status = lp->last_status;
+      status = lp->last_waitstatus;
      }

    if (!WIFSTOPPED (status))
@@ -1564,7 +1564,7 @@ thread_still_has_status_pending_p (struct 
thread_info *thread)
        CORE_ADDR pc;
        int discard = 0;

-      gdb_assert (lp->last_status != 0);
+      gdb_assert (lp->last_waitstatus != 0);

        pc = get_pc (lp);

@@ -1626,7 +1626,7 @@ lwp_resumed (struct lwp_info *lwp)
       corresponding stop to gdb yet?  If so, the thread is still
       resumed/running from gdb's perspective.  */
    if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE)
      return 1;

    return 0;
@@ -2305,7 +2305,7 @@ linux_low_filter_event (int lwpid, int wstat)

    child->stopped = 1;

-  child->last_status = wstat;
+  child->last_waitstatus = wstat;

    /* Check if the thread has exited.  */
    if ((WIFEXITED (wstat) || WIFSIGNALED (wstat)))
@@ -2462,7 +2462,7 @@ resume_stopped_resumed_lwps (struct 
inferior_list_entry *entry)
    if (lp->stopped
        && !lp->suspended
        && !lp->status_pending_p
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE)
      {
        int step = thread->last_resume_kind == resume_step;

@@ -2699,7 +2699,7 @@ count_events_callback (struct inferior_list_entry 
*entry, void *data)
    gdb_assert (count != NULL);

    /* Count only resumed LWPs that have an event pending. */
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE
        && lp->status_pending_p)
      (*count)++;

@@ -2714,7 +2714,7 @@ select_singlestep_lwp_callback (struct 
inferior_list_entry *entry, void *data)
    struct thread_info *thread = (struct thread_info *) entry;
    struct lwp_info *lp = get_thread_lwp (thread);

-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE
        && thread->last_resume_kind == resume_step
        && lp->status_pending_p)
      return 1;
@@ -2734,7 +2734,7 @@ select_event_lwp_callback (struct 
inferior_list_entry *entry, void *data)
    gdb_assert (selector != NULL);

    /* Select only resumed LWPs that have an event pending. */
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE
        && lp->status_pending_p)
      if ((*selector)-- == 0)
        return 1;
@@ -4287,7 +4287,7 @@ linux_set_resume_request (struct 
inferior_list_entry *entry, void *arg)
  	    {
  	      if (debug_threads)
  		debug_printf ("already %s LWP %ld at GDB's request\n",
-			      (thread->last_status.kind
+			      (thread->last_waitstatus.kind
  			       == TARGET_WAITKIND_STOPPED)
  			      ? "stopped"
  			      : "stopping",
@@ -4697,7 +4697,7 @@ linux_resume_one_thread (struct 
inferior_list_entry *entry, void *arg)

        /* For stop requests, we're done.  */
        lwp->resume = NULL;
-      thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+      thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;
        return 0;
      }

@@ -4738,8 +4738,8 @@ linux_resume_one_thread (struct 
inferior_list_entry *entry, void *arg)
  	     make sure to queue its siginfo.  We can ignore the return
  	     value of ptrace; if it fails, we'll skip
  	     PTRACE_SETSIGINFO.  */
-	  if (WIFSTOPPED (lwp->last_status)
-	      && WSTOPSIG (lwp->last_status) == lwp->resume->sig)
+	  if (WIFSTOPPED (lwp->last_waitstatus)
+	      && WSTOPSIG (lwp->last_waitstatus) == lwp->resume->sig)
  	    ptrace (PTRACE_GETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
  		    &p_sig->info);

@@ -4747,7 +4747,7 @@ linux_resume_one_thread (struct 
inferior_list_entry *entry, void *arg)
  	}
      }

-  thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+  thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;
    lwp->resume = NULL;
    return 0;
  }
@@ -4851,7 +4851,7 @@ proceed_one_lwp (struct inferior_list_entry 
*entry, void *except)
      }

    if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+      && thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE)
      {
        if (debug_threads)
  	debug_printf ("   client wants LWP to remain %ld stopped\n",
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index c211a37..dbfb7f2 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -278,7 +278,7 @@ struct lwp_info
    int stopped;

    /* When stopped is set, the last wait status recorded for this lwp.  */
-  int last_status;
+  int last_waitstatus;

    /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for
       this LWP's last event, to pass to GDB without any further
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 05e3d63..a00a9f5 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1493,16 +1493,16 @@ look_up_one_symbol (const char *name, CORE_ADDR 
*addrp, int may_ask_gdb)
    while (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);
+      mem_buffer = (unsigned char *) xmalloc (mem_len);
+      if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	bin2hex (mem_buffer, own_buf, mem_len);
        else
  	write_enn (own_buf);
-      free (mem_buf);
+      free (mem_buffer);
        if (putpkt (own_buf) < 0)
  	return -1;
        len = getpkt (own_buf);
@@ -1575,36 +1575,36 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR 
oldloc)
    while (own_buf[0] == 'm' || own_buf[0] == 'M' || 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')
  	{
  	  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);
+	  mem_buffer = (unsigned char *) xmalloc (mem_len);
+	  if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+	    bin2hex (mem_buffer, own_buf, mem_len);
  	  else
  	    write_enn (own_buf);
  	}
        else if (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)
+			       &mem_len, &mem_buffer) < 0
+	      || write_inferior_memory (mem_addr, mem_buffer, mem_len) != 0)
  	    write_enn (own_buf);
  	  else
  	    write_ok (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)
+	  decode_M_packet (&own_buf[1], &mem_addr, &mem_len, &mem_buffer);
+	  if (write_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
  	    write_ok (own_buf);
  	  else
  	    write_enn (own_buf);
  	}
-      free (mem_buf);
+      free (mem_buffer);
        if (putpkt (own_buf) < 0)
  	return -1;
	       len = getpkt (own_buf);
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 8f097e5..ec408d3 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -119,7 +119,7 @@ int disable_packet_qfThreadInfo;
  static struct target_waitstatus last_status;
  static ptid_t last_ptid;

-static char *own_buf;
+static char *own_buffer;
  static unsigned char *mem_buf;

  /* A sub-class of 'struct notif_event' for stop, holding information
@@ -278,7 +278,7 @@ start_inferior (char **argv)
  		break;

  	      current_thread->last_resume_kind = resume_stop;
-	      current_thread->last_status = last_status;
+	      current_thread->last_waitstatus = last_status;
  	    }
  	  while (last_status.value.sig != GDB_SIGNAL_TRAP);
  	}
@@ -296,7 +296,7 @@ start_inferior (char **argv)
        && last_status.kind != TARGET_WAITKIND_SIGNALLED)
      {
        current_thread->last_resume_kind = resume_stop;
-      current_thread->last_status = last_status;
+      current_thread->last_waitstatus = last_status;
      }
    else
      mourn_inferior (find_process_pid (ptid_get_pid (last_ptid)));
@@ -333,7 +333,7 @@ attach_inferior (int pid)
  	last_status.value.sig = GDB_SIGNAL_TRAP;

        current_thread->last_resume_kind = resume_stop;
-      current_thread->last_status = last_status;
+      current_thread->last_waitstatus = last_status;
      }

    return 0;
@@ -1658,20 +1658,20 @@ handle_qxfer_btrace (const char *annex,
    if (ptid_equal (general_thread, null_ptid)
        || ptid_equal (general_thread, minus_one_ptid))
      {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (own_buffer, "E.Must select a single thread.");
        return -3;
      }

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

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

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

@@ -1694,7 +1694,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 (own_buffer, cache.buffer, cache.used_size);
  	  return -3;
  	}
      }
@@ -1732,20 +1732,20 @@ handle_qxfer_btrace_conf (const char *annex,
    if (ptid_equal (general_thread, null_ptid)
        || ptid_equal (general_thread, minus_one_ptid))
      {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (own_buffer, "E.Must select a single thread.");
        return -3;
      }

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

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

@@ -1756,7 +1756,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 (own_buffer, cache.buffer, cache.used_size);
  	  return -3;
  	}
      }
@@ -2582,9 +2582,9 @@ handle_pending_status (const struct thread_resume 
*resumption,
      {
        thread->status_pending_p = 0;

-      last_status = thread->last_status;
+      last_status = thread->last_waitstatus;
        last_ptid = thread->entry.id;
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      prepare_resume_reply (own_buffer, last_ptid, &last_status);
        return 1;
      }
    return 0;
@@ -2723,7 +2723,7 @@ resume (struct thread_resume *actions, size_t 
num_actions)
    (*the_target->resume) (actions, num_actions);

    if (non_stop)
-    write_ok (own_buf);
+    write_ok (own_buffer);
    else
      {
        last_ptid = mywait (minus_one_ptid, &last_status, 0, 1);
@@ -2733,7 +2733,7 @@ resume (struct thread_resume *actions, size_t 
num_actions)
  	{
  	  /* The client does not support this stop reply.  At least
  	     return error.  */
-	  sprintf (own_buf, "E.No unwaited-for children left.");
+	  sprintf (own_buffer, "E.No unwaited-for children left.");
  	  disable_async_io ();
  	  return;
  	}
@@ -2741,14 +2741,14 @@ resume (struct thread_resume *actions, size_t 
num_actions)
        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;
+	current_thread->last_waitstatus = 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 (own_buffer, last_ptid, &last_status);
        disable_async_io ();

        if (last_status.kind == TARGET_WAITKIND_EXITED
@@ -3048,7 +3048,7 @@ queue_stop_reply_callback (struct 
inferior_list_entry *entry, void *arg)
        struct vstop_notif *new_notif = XNEW (struct vstop_notif);

        new_notif->ptid = entry->id;
-      new_notif->status = thread->last_status;
+      new_notif->status = thread->last_waitstatus;
        /* Pass the last stop reply back to GDB, but don't notify
  	 yet.  */
        notif_event_enque (&notif_stop,
@@ -3061,7 +3061,7 @@ queue_stop_reply_callback (struct 
inferior_list_entry *entry, void *arg)
  	  if (debug_threads)
  	    {
  	      char *status_string
-		= target_waitstatus_to_string (&thread->last_status);
+		= target_waitstatus_to_string (&thread->last_waitstatus);

  	      debug_printf ("Reporting thread %s as already stopped with %s\n",
  			    target_pid_to_str (entry->id),
@@ -3070,11 +3070,11 @@ queue_stop_reply_callback (struct 
inferior_list_entry *entry, void *arg)
  	      xfree (status_string);
  	    }

-	  gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
+	  gdb_assert (thread->last_waitstatus.kind != TARGET_WAITKIND_IGNORE);

  	  /* Pass the last stop reply back to GDB, but don't notify
  	     yet.  */
-	  queue_stop_reply (entry->id, &thread->last_status);
+	  queue_stop_reply (entry->id, &thread->last_waitstatus);
  	}
      }

@@ -3092,12 +3092,12 @@ gdb_wants_thread_stopped (struct 
inferior_list_entry *entry)

    thread->last_resume_kind = resume_stop;

-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+  if (thread->last_waitstatus.kind == TARGET_WAITKIND_IGNORE)
      {
        /* Most threads are stopped implicitly (all-stop); tag that with
  	 signal 0.  */
-      thread->last_status.kind = TARGET_WAITKIND_STOPPED;
-      thread->last_status.value.sig = GDB_SIGNAL_0;
+      thread->last_waitstatus.kind = TARGET_WAITKIND_STOPPED;
+      thread->last_waitstatus.value.sig = GDB_SIGNAL_0;
      }
  }

@@ -3138,15 +3138,15 @@ set_pending_status_callback (struct 
inferior_list_entry *entry)
  {
    struct thread_info *thread = (struct thread_info *) entry;

-  if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-      || (thread->last_status.value.sig != GDB_SIGNAL_0
+  if (thread->last_waitstatus.kind != TARGET_WAITKIND_STOPPED
+      || (thread->last_waitstatus.value.sig != GDB_SIGNAL_0
  	  /* A breakpoint, watchpoint or finished step from a previous
  	     GDB run isn't considered interesting for a new GDB run.
  	     If we left those pending, the new GDB could consider them
  	     random SIGTRAPs.  This leaves out real async traps.  We'd
  	     have to peek into the (target-specific) siginfo to
  	     distinguish those.  */
-	  && thread->last_status.value.sig != GDB_SIGNAL_TRAP))
+	  && thread->last_waitstatus.value.sig != GDB_SIGNAL_TRAP))
      thread->status_pending_p = 1;
  }

@@ -3229,8 +3229,8 @@ handle_status (char *own_buf)
  	  general_thread = thread->id;
  	  set_desired_thread (1);

-	  gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
-	  prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
+	  gdb_assert (tp->last_waitstatus.kind != TARGET_WAITKIND_IGNORE);
+	  prepare_resume_reply (own_buf, tp->entry.id, &tp->last_waitstatus);
  	}
        else
  	strcpy (own_buf, "W00");
@@ -3618,7 +3618,7 @@ captured_main (int argc, char *argv[])
      initialize_tracepoint ();
    initialize_notif ();

-  own_buf = (char *) xmalloc (PBUFSIZ + 1);
+  own_buffer = (char *) xmalloc (PBUFSIZ + 1);
    mem_buf = (unsigned char *) xmalloc (PBUFSIZ);

    if (pid == 0 && *next_arg != NULL)
@@ -3754,8 +3754,8 @@ captured_main (int argc, char *argv[])

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

  	  if (run_once)
@@ -3873,7 +3873,7 @@ process_serial_event (void)
    disable_async_io ();

    response_needed = 0;
-  packet_len = getpkt (own_buf);
+  packet_len = getpkt (own_buffer);
    if (packet_len <= 0)
      {
        remote_close ();
@@ -3883,22 +3883,22 @@ process_serial_event (void)
    response_needed = 1;

    i = 0;
-  ch = own_buf[i++];
+  ch = own_buffer[i++];
    switch (ch)
      {
      case 'q':
-      handle_query (own_buf, packet_len, &new_packet_len);
+      handle_query (own_buffer, packet_len, &new_packet_len);
        break;
      case 'Q':
-      handle_general_set (own_buf);
+      handle_general_set (own_buffer);
        break;
      case 'D':
-      require_running (own_buf);
+      require_running (own_buffer);

        if (multi_process)
  	{
  	  i++; /* skip ';' */
-	  pid = strtol (&own_buf[i], NULL, 16);
+	  pid = strtol (&own_buffer[i], NULL, 16);
  	}
        else
  	pid = ptid_get_pid (current_ptid);
@@ -3910,7 +3910,7 @@ process_serial_event (void)

  	  if (process == NULL)
  	    {
-	      write_enn (own_buf);
+	      write_enn (own_buffer);
  	      break;
  	    }

@@ -3946,18 +3946,18 @@ process_serial_event (void)
  	  resume_info.sig = 0;
  	  (*the_target->resume) (&resume_info, 1);

-	  write_ok (own_buf);
+	  write_ok (own_buffer);
  	  break; /* from switch/case */
  	}

        fprintf (stderr, "Detaching from process %d\n", pid);
        stop_tracing ();
        if (detach_inferior (pid) != 0)
-	write_enn (own_buf);
+	write_enn (own_buffer);
        else
  	{
  	  discard_queued_stop_replies (pid_to_ptid (pid));
-	  write_ok (own_buf);
+	  write_ok (own_buffer);

  	  if (extended_protocol || target_running ())
  	    {
@@ -3972,7 +3972,7 @@ process_serial_event (void)
  	    }
  	  else
  	    {
-	      putpkt (own_buf);
+	      putpkt (own_buffer);
  	      remote_close ();

  	      /* If we are attached, then we can exit.  Otherwise, we
@@ -3985,20 +3985,20 @@ process_serial_event (void)
        break;
      case '!':
        extended_protocol = 1;
-      write_ok (own_buf);
+      write_ok (own_buffer);
        break;
      case '?':
-      handle_status (own_buf);
+      handle_status (own_buffer);
        break;
      case 'H':
-      if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
+      if (own_buffer[1] == 'c' || own_buffer[1] == 'g' || own_buffer[1] 
== 's')
  	{
  	  ptid_t gdb_id, thread_id;
  	  int pid;

-	  require_running (own_buf);
+	  require_running (own_buffer);

-	  gdb_id = read_ptid (&own_buf[2], NULL);
+	  gdb_id = read_ptid (&own_buffer[2], NULL);

  	  pid = ptid_get_pid (gdb_id);

@@ -4015,7 +4015,7 @@ process_serial_event (void)
  						      &pid);
  	      if (!thread)
  		{
-		  write_enn (own_buf);
+		  write_enn (own_buffer);
  		  break;
  		}

@@ -4026,12 +4026,12 @@ process_serial_event (void)
  	      thread_id = gdb_id_to_thread_id (gdb_id);
  	      if (ptid_equal (thread_id, null_ptid))
  		{
-		  write_enn (own_buf);
+		  write_enn (own_buffer);
  		  break;
  		}
  	    }

-	  if (own_buf[1] == 'g')
+	  if (own_buffer[1] == 'g')
  	    {
  	      if (ptid_equal (thread_id, null_ptid))
  		{
@@ -4050,20 +4050,20 @@ process_serial_event (void)
  	      set_desired_thread (1);
  	      gdb_assert (current_thread != NULL);
  	    }
-	  else if (own_buf[1] == 'c')
+	  else if (own_buffer[1] == 'c')
  	    cont_thread = thread_id;

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

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

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

  	  if (!set_desired_thread (1))
-	    write_enn (own_buf);
+	    write_enn (own_buffer);
  	  else
  	    {
  	      regcache = get_thread_regcache (current_thread, 1);
-	      registers_from_string (regcache, &own_buf[1]);
-	      write_ok (own_buf);
+	      registers_from_string (regcache, &own_buffer[1]);
+	      write_ok (own_buffer);
  	    }
  	}
        break;
      case 'm':
-      require_running (own_buf);
-      decode_m_packet (&own_buf[1], &mem_addr, &len);
+      require_running (own_buffer);
+      decode_m_packet (&own_buffer[1], &mem_addr, &len);
        res = gdb_read_memory (mem_addr, mem_buf, len);
        if (res < 0)
-	write_enn (own_buf);
+	write_enn (own_buffer);
        else
-	bin2hex (mem_buf, own_buf, res);
+	bin2hex (mem_buf, own_buffer, res);
        break;
      case 'M':
-      require_running (own_buf);
-      decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
+      require_running (own_buffer);
+      decode_M_packet (&own_buffer[1], &mem_addr, &len, &mem_buf);
        if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
-	write_ok (own_buf);
+	write_ok (own_buffer);
        else
-	write_enn (own_buf);
+	write_enn (own_buffer);
        break;
      case 'X':
-      require_running (own_buf);
-      if (decode_X_packet (&own_buf[1], packet_len - 1,
+      require_running (own_buffer);
+      if (decode_X_packet (&own_buffer[1], packet_len - 1,
  			   &mem_addr, &len, &mem_buf) < 0
  	  || gdb_write_memory (mem_addr, mem_buf, len) != 0)
-	write_enn (own_buf);
+	write_enn (own_buffer);
        else
-	write_ok (own_buf);
+	write_ok (own_buffer);
        break;
      case 'C':
-      require_running (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running (own_buffer);
+      hex2bin (own_buffer + 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 (own_buffer, 0, signal);
        break;
      case 'S':
-      require_running (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running (own_buffer);
+      hex2bin (own_buffer + 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 (own_buffer, 1, signal);
        break;
      case 'c':
-      require_running (own_buf);
+      require_running (own_buffer);
        signal = 0;
-      myresume (own_buf, 0, signal);
+      myresume (own_buffer, 0, signal);
        break;
      case 's':
-      require_running (own_buf);
+      require_running (own_buffer);
        signal = 0;
-      myresume (own_buf, 1, signal);
+      myresume (own_buffer, 1, signal);
        break;
      case 'Z':  /* insert_ ... */
        /* Fallthrough.  */
@@ -4168,10 +4168,10 @@ process_serial_event (void)
  	char *dataptr;
  	ULONGEST addr;
  	int kind;
-	char type = own_buf[1];
+	char type = own_buffer[1];
  	int res;
  	const int insert = ch == 'Z';
-	char *p = &own_buf[3];
+	char *p = &own_buffer[3];

  	p = unpack_varlen_hex (p, &addr);
  	kind = strtol (p + 1, &dataptr, 16);
@@ -4198,12 +4198,12 @@ process_serial_event (void)
  	  res = delete_gdb_breakpoint (type, addr, kind);

  	if (res == 0)
-	  write_ok (own_buf);
+	  write_ok (own_buffer);
  	else if (res == 1)
  	  /* Unsupported.  */
-	  own_buf[0] = '\0';
+	  own_buffer[0] = '\0';
  	else
-	  write_enn (own_buf);
+	  write_enn (own_buffer);
  	break;
        }
      case 'k':
@@ -4231,20 +4231,20 @@ process_serial_event (void)
        {
  	ptid_t gdb_id, thread_id;

-	require_running (own_buf);
+	require_running (own_buffer);

-	gdb_id = read_ptid (&own_buf[1], NULL);
+	gdb_id = read_ptid (&own_buffer[1], NULL);
  	thread_id = gdb_id_to_thread_id (gdb_id);
  	if (ptid_equal (thread_id, null_ptid))
  	  {
-	    write_enn (own_buf);
+	    write_enn (own_buffer);
  	    break;
  	  }

  	if (mythread_alive (thread_id))
-	  write_ok (own_buf);
+	  write_ok (own_buffer);
  	else
-	  write_enn (own_buf);
+	  write_enn (own_buffer);
        }
        break;
      case 'R':
@@ -4287,26 +4287,26 @@ 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';
+	  own_buffer[0] = '\0';
  	  break;
  	}
      case 'v':
        /* Extended (long) request.  */
-      handle_v_requests (own_buf, packet_len, &new_packet_len);
+      handle_v_requests (own_buffer, packet_len, &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';
+      own_buffer[0] = '\0';
        break;
      }

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

    response_needed = 0;

@@ -4384,7 +4384,7 @@ handle_target_event (int err, gdb_client_data 
client_data)
  	     "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;
+	  current_thread->last_waitstatus = last_status;
  	}

        if (forward_event)
diff --git a/gdb/nat/linux-personality.h b/gdb/nat/linux-personality.h
index 009e614..5f7fa8b 100644
--- a/gdb/nat/linux-personality.h
+++ b/gdb/nat/linux-personality.h
@@ -26,6 +26,6 @@
     re-enable the inferior's address space randomization.  */

  extern struct cleanup *maybe_disable_address_space_randomization
-  (int disable_randomization);
+  (int disable_randomization_p);

  #endif /* ! NAT_LINUX_PERSONALITY_H */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] consolidate gdbserver global data
  2015-11-25 19:05 ` Stan Cox
  2015-12-17 21:06   ` [PATCH v2 1/2] " Stan Cox
@ 2015-12-17 21:15   ` Stan Cox
  2015-12-21 13:30     ` Pedro Alves
  1 sibling, 1 reply; 6+ messages in thread
From: Stan Cox @ 2015-12-17 21:15 UTC (permalink / raw)
  To: gdb-patches

This patch consolidates global data into two structures.  Data that is 
related to the client is defined in the client_state structure, 
analogous to the remote_state structure in gdb/remote.c.   Data that is 
related to the inferior running under gdbserver is defined in the 
server_status structure.  This delineation is to allow, as a future 
expansion, the ability to have multiple clients, for example gdb and 
strace, connected to the same inferior.  To maintain source 
compatibility, macros are defined so that global variable references do 
not have to be changed to be structure member references.  New access 
functions are:  new_client_state, which sets up a single client state 
and get_client_state which returns it  They are analogous to 
new_remote_state and get_remote_state in gdb/remote.c.   Going forward 
this infrastructure can be expanded so that multiple clients can be 
supported.

gdb/gdbserver/Changelog

     * server.h (struct server_state, struct client_state):  New.
     Move global data items here and remove the extern declarations.
     Add defines for struct members for source compatibility.

     * server.c (cont_thread, server_waiting, extended_protocol)
     (response_needed, exit_requested, run_once, multi_process)
     (report_fork_events, report_vfork_events, report_exec_events)
     (non_stop, swbreak_feature, hwbreak_feature, vCont_supported)
     (disable_randomization, program_argv, wrapper_argv, pass_signals)
     (program_signals, signal_pid, disable_packet_vCont)
     (disable_packet_Tthread, disable_packet_qC)
     (disable_packet_qfThreadInfo, last_status, last_ptid, own_buf)
     (mem_buf):  Moved to struct client_status, struct server_status
     (new_client_state): Set the client_state struct.
     (get_client_state): Return the client_state.
     (captured_main):  Call new_client_state.

     * inferiors.h (all_processes, all_threads, current_thread)  Move
     to client_status


diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 4d64250..25de573 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -22,11 +22,6 @@
  #include "gdbthread.h"
  #include "dll.h"

-struct inferior_list all_processes;
-struct inferior_list all_threads;
-
-struct thread_info *current_thread;
-
  #define get_thread(inf) ((struct thread_info *)(inf))

  void
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index d722616..d457a35 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -84,8 +84,6 @@ struct process_info
  struct process_info *current_process (void);
  struct process_info *get_thread_process (struct thread_info *);

-extern struct inferior_list all_processes;
-
  void add_inferior_to_list (struct inferior_list *list,
  			   struct inferior_list_entry *new_inferior);
  void for_each_inferior (struct inferior_list *list,
@@ -122,7 +120,6 @@ int one_inferior_p (struct inferior_list *list);
  #define ALL_PROCESSES(cur, tmp)					\
    ALL_INFERIORS_TYPE (struct process_info, &all_processes, cur, tmp)

-extern struct thread_info *current_thread;
  void remove_inferior (struct inferior_list *list,
  		      struct inferior_list_entry *entry);

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 1f0a977..12a18d0 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -5627,8 +5627,6 @@ linux_look_up_symbols (void)
  static void
  linux_request_interrupt (void)
  {
-  extern unsigned long signal_pid;
-
    /* Send a SIGINT to the process group.  This acts just like the user
       typed a ^C on the controlling terminal.  */
    kill (-signal_pid, SIGINT);
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index a00a9f5..3b1a763 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -860,14 +860,6 @@ initialize_async_io (void)
    unblock_async_io ();
  }

-/* 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
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index ec408d3..7e9addf 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -36,60 +36,6 @@
  #include "dll.h"
  #include "hostio.h"

-/* 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_argv, **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;

  #ifdef SIGTTOU
  /* A file descriptor for the controlling terminal.  */
@@ -107,21 +53,6 @@ restore_old_foreground_pgrp (void)
  }
  #endif

-/* 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.  */
-int disable_packet_vCont;
-int disable_packet_Tthread;
-int disable_packet_qC;
-int disable_packet_qfThreadInfo;
-
-/* Last status reported to GDB.  */
-static struct target_waitstatus last_status;
-static ptid_t last_ptid;
-
-static char *own_buffer;
-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.  */
@@ -143,6 +74,28 @@ static struct btrace_config current_btrace_conf;

  DEFINE_QUEUE_P (notif_event_p);

+static client_state *current_client_state;
+
+/* Add a new client state for FD or return if found */
+
+client_state *
+new_client_state ()
+{
+  current_client_state = XCNEW (client_state);
+  current_client_state->ss = XCNEW (server_state);
+  own_buffer = (char *) xmalloc (PBUFSIZ + 1);
+  return current_client_state;
+}
+
+
+/* Return the current client state */
+
+client_state *
+get_client_state (void)
+{
+  return current_client_state;
+}
+
  /* Put a stop reply to the stop reply queue.  */

  static void
@@ -3458,6 +3411,8 @@ captured_main (int argc, char *argv[])
    volatile int attach = 0;
    int was_running;

+  new_client_state ();
+
    while (*next_arg != NULL && **next_arg == '-')
      {
        if (strcmp (*next_arg, "--version") == 0)
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 18095f2..47bcab7 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -67,42 +67,6 @@ int vsnprintf(char *str, size_t size, const char 
*format, va_list ap);

  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 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;
@@ -133,4 +97,143 @@ extern void discard_queued_stop_replies (ptid_t ptid);
     as large as the largest register set supported by gdbserver.  */
  #define PBUFSIZ 16384

+
+/* 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
+{
+  /* 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_;
+  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 */
+  struct inferior_list all_processes_;
+  struct inferior_list all_threads_;
+  struct thread_info *current_thread_;
+};
+
+typedef struct server_state server_state;
+
+struct client_state
+{
+  /* 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_;
+
+  int disable_packet_vCont_;
+  int disable_packet_Tthread_;
+  int disable_packet_qC_;
+  int disable_packet_qfThreadInfo_;
+
+  char **program_argv_, **wrapper_argv_;
+
+  int pass_signals_[GDB_SIGNAL_LAST];
+  int program_signals_[GDB_SIGNAL_LAST];
+  int program_signals_p_;
+  char *own_buffer_;
+  struct server_state *ss;
+};
+
+typedef struct client_state client_state;
+
+struct client_state * get_client_state ();
+
+#define cont_thread (get_client_state()->ss->cont_thread_)
+#define general_thread (get_client_state()->ss->general_thread_)
+#define signal_pid (get_client_state()->ss->signal_pid_)
+#define last_status (get_client_state()->ss->last_status_)
+#define last_ptid (get_client_state()->ss->last_ptid_)
+#define mem_buf (get_client_state()->ss->mem_buf_)
+#define readchar_buf (get_client_state()->ss->readchar_buf_)
+#define readchar_bufcnt (get_client_state()->ss->readchar_bufcnt_)
+#define readchar_bufp (get_client_state()->ss->readchar_bufp_)
+#define all_processes (get_client_state()->ss->all_processes_)
+#define all_threads (get_client_state()->ss->all_threads_)
+#define current_thread (get_client_state()->ss->current_thread_)
+#define server_waiting (get_client_state()->server_waiting_)
+#define extended_protocol (get_client_state()->extended_protocol_)
+#define response_needed (get_client_state()->response_needed_)
+#define exit_requested (get_client_state()->exit_requested_)
+#define run_once (get_client_state()->run_once_)
+#define multi_process (get_client_state()->multi_process_)
+#define report_fork_events (get_client_state()->report_fork_events_)
+#define report_vfork_events (get_client_state()->report_vfork_events_)
+#define report_exec_events (get_client_state()->report_exec_events_)
+#define report_thread_events (get_client_state()->report_thread_events_)
+#define report_no_resumed (get_client_state()->report_no_resumed_)
+#define non_stop (get_client_state()->non_stop_)
+#define swbreak_feature (get_client_state()->swbreak_feature_)
+#define hwbreak_feature (get_client_state()->hwbreak_feature_)
+#define vCont_supported (get_client_state()->vCont_supported_)
+#define disable_randomization (get_client_state()->disable_randomization_)
+#define disable_packet_vCont (get_client_state()->disable_packet_vCont_)
+#define disable_packet_Tthread 
(get_client_state()->disable_packet_Tthread_)
+#define disable_packet_qC (get_client_state()->disable_packet_qC_)
+#define disable_packet_qfThreadInfo 
(get_client_state()->disable_packet_qfThreadInfo_)
+#define program_argv (get_client_state()->program_argv_)
+#define wrapper_argv (get_client_state()->wrapper_argv_)
+#define pass_signals (get_client_state()->pass_signals_)
+#define program_signals (get_client_state()->program_signals_)
+#define program_signals_p (get_client_state()->program_signals_p_)
+#define own_buffer (get_client_state()->own_buffer_)
+
  #endif /* SERVER_H */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] consolidate gdbserver global data
  2015-12-17 21:15   ` [PATCH v2 2/2] " Stan Cox
@ 2015-12-21 13:30     ` Pedro Alves
  2015-12-21 17:04       ` Stan Cox
  0 siblings, 1 reply; 6+ messages in thread
From: Pedro Alves @ 2015-12-21 13:30 UTC (permalink / raw)
  To: Stan Cox, gdb-patches

Hi Stan,

On 12/17/2015 09:15 PM, Stan Cox wrote:
> This patch consolidates global data into two structures.  Data that is 
> related to the client is defined in the client_state structure, 
> analogous to the remote_state structure in gdb/remote.c.   Data that is 
> related to the inferior running under gdbserver is defined in the 
> server_status structure.  This delineation is to allow, as a future 
> expansion, the ability to have multiple clients, for example gdb and 
> strace, connected to the same inferior.  To maintain source 
> compatibility, macros are defined so that global variable references do 
> not have to be changed to be structure member references.  New access 
> functions are:  new_client_state, which sets up a single client state 
> and get_client_state which returns it  They are analogous to 
> new_remote_state and get_remote_state in gdb/remote.c.   Going forward 
> this infrastructure can be expanded so that multiple clients can be 
> supported.

Sorry, I tried looking at this several times, but I always end up
very much confused on the client/server split.  :-/

Most things in server_state seem specific to the currently
connected _GDB/client_ to me.  E.g, the thread set with Hg.
Likewise readchar_buf.  Etc.

Can you give an example on how this will work out in the end
when you have multiple instances of these objects?

- When will we have multiple server_state objects?

- When will we have multiple client_state objects?

- What are the relations between those objects?

We should also end up with a concise comment at the top
of these structs definitions explaining what they are for.
struct client_state has no intro comment, afaics.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] consolidate gdbserver global data
  2015-12-21 13:30     ` Pedro Alves
@ 2015-12-21 17:04       ` Stan Cox
  0 siblings, 0 replies; 6+ messages in thread
From: Stan Cox @ 2015-12-21 17:04 UTC (permalink / raw)
  To: gdb-patches; +Cc: Pedro Alves


The thinking was that it would be like, not a perfect analogy, database 
normalization.  So, logically, there would be one server structure per 
inferior that contains those items that are common to all remote clients 
accessing that inferior.  Each server would have one or more associated 
client structures, one per remote client.  So the server_state is, 
roughly, the gdbserver view of things and the client_state is the remote 
gdb view of things.

So at a high level
			/ [client 1, fd 4]
  [server for inferior 1]
  	     	        \ [client 2, fd 9]

This is "inverted" in the current implementation model.  So there is a 
list of client structures that are "indexed" by the file descriptor 
corresponding to the client.  So in this example there is one server 
state that has two client states.  The file_desc is the client "key" and 
finding a client_state involves searching the list of clients (via 
client_state.next) for the client_state that matches that file_desc.

  client_states.first
  -> /* client 1 --- fd 4 */ struct client_state
     file_desc = 4,
     attached_to_client = 1,
     packet_type = 0,
     last_packet_type = 4,
      /* enum packet_types { other_packet, vContc, vConts, vContt,
		    vStopped, vRun, vAttach }; */
     pending = 0,
      /* enum pending_types {none_pending, pending_waitee,
              pending_cont_waiter,pending_step_waiter,pending_stop}; */
     server_waiting_ = 0,
     extended_protocol_ = 1,
     response_needed_ = 0,
     exit_requested_ = 0,
     run_once_ = 0,
     multi_process_ = 1,
     report_fork_events_ = 1,
     report_vfork_events_ = 1,
     non_stop_ = 1,
     swbreak_feature_ = 1,
     hwbreak_feature_ = 1,
     disable_randomization_ = 1,
     program_argv_ = 0x683840,
     wrapper_argv_ = 0x0,
     packet_length_ = 17,
     pass_signals_ =     {0 <repeats 14 times>,
     program_signals_ =     {1,
     program_signals_p_ = 1,
     in_buffer_ = 0x6838a0 "z0,7ffff7df0f57,", <incomplete sequence \327>,
     own_buffer_ = 0x6848e0 "OK",
     client_breakpoints = 0x6836a0,
     ss = 0x681430,
     next = 0x688920

  client_states.first.next
  -> /* client 2 --- fd 9 */ struct client_state
     ...
     ss = 0x681430,
     next = 0

  client_states.first.ss
  -> /* server -- ss = 0x681430 */ struct server_state
     attach_count_ = 2, /* number of clients for this server_state */
     cont_thread_ = {...}
     general_thread_ = {...}
     signal_pid_ = 32251,
     last_status_ = {
       kind = TARGET_WAITKIND_NO_RESUMED,
       value = {
          integer = 5,
          sig = GDB_SIGNAL_TRAP,
          related_pid = {...}
       ...
     last_status_exited = 0,
     last_ptid_ = {...}
     mem_buf_ = 0x67cc70 "..."
     readchar_buf_ =     "$z0,7ffff7df0f57,1#050"...,
     readchar_bufcnt_ = 0,
     readchar_bufp_ = 0x6814cd "0,fff#03b;"...,
     all_processes_ = { head = 0x683a80, tail = 0x683a80  },
     all_threads_ = { head = 0x683cb0, tail = 0x683cb0  },
     current_thread_ = 0x683cb0

  client_states.current_cs
  -> /* there is always a "current" client_state
        this points to the "current" client_state */

Example "queries"
1) What is client 1's in_buffer?
    - Find client 1's fd in the client list
    - client_state.in_buffer
2) What is client 2's last_status?
    - Find Client 2's fd in the client list
    - client_state.ss.last_status
3) What is the current client_state?
    -client_states.current_cs

Thanks for looking Pedro.  I'm wide open to any ways to improve this to 
make it easier to understand and use.




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-12-21 17:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-15 16:53 [PATCH] consolidate gdbserver global data Stan Cox
2015-11-25 19:05 ` Stan Cox
2015-12-17 21:06   ` [PATCH v2 1/2] " Stan Cox
2015-12-17 21:15   ` [PATCH v2 2/2] " Stan Cox
2015-12-21 13:30     ` Pedro Alves
2015-12-21 17:04       ` Stan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).