@@ -385,6 +385,9 @@ delete_file_handler (gdb_fildes_t fd)
;
prev_ptr->next_file = file_ptr->next_file;
}
+
+ struct multi_client_states *client_states = get_client_states();
+ client_states->delete_client_state (fd);
free (file_ptr);
}
@@ -108,7 +108,7 @@ post_fork_inferior (int pid, const char *program)
startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED,
&last_status, &last_ptid);
current_thread->last_resume_kind = resume_stop;
- current_thread->last_status = last_status;
+ current_thread->last_waitstatus = last_status;
signal_pid = pid;
target_post_create_inferior ();
fprintf (stderr, "Process %s created; pid = %d\n", program, pid);
@@ -39,7 +39,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;
@@ -73,8 +73,6 @@ struct thread_info
struct btrace_target_info *btrace;
};
-extern std::list<thread_info *> all_threads;
-
void remove_thread (struct thread_info *thread);
struct thread_info *add_thread (ptid_t ptid, void *target_data);
@@ -29,8 +29,6 @@
#include <sys/stat.h>
#include "fileio.h"
-extern int remote_debug;
-
struct fd_list
{
int fd;
@@ -22,10 +22,6 @@
#include "gdbthread.h"
#include "dll.h"
-std::list<process_info *> all_processes;
-std::list<thread_info *> all_threads;
-
-struct thread_info *current_thread;
/* The current working directory used to start the inferior. */
static const char *current_inferior_cwd = NULL;
@@ -94,7 +90,7 @@ add_thread (ptid_t thread_id, void *target_data)
new_thread->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;
all_threads.push_back (new_thread);
@@ -81,8 +81,6 @@ pid_of (const process_info *proc)
struct process_info *current_process (void);
struct process_info *get_thread_process (const struct thread_info *);
-extern std::list<process_info *> all_processes;
-
/* Invoke FUNC for each process. */
template <typename Func>
@@ -123,8 +121,6 @@ find_process (Func func)
return NULL;
}
-extern struct thread_info *current_thread;
-
/* Return the first process in the processes list. */
struct process_info *get_first_process (void);
@@ -545,7 +545,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. If the fork/clone parent is stepping over a breakpoint,
@@ -723,7 +723,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;
/* Update syscall state in the new lwp, effectively mid-syscall
too. */
event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY;
@@ -994,14 +994,14 @@ linux_ptrace_fun ()
static int
linux_create_inferior (const char *program,
- const std::vector<char *> &program_args)
+ const std::vector<char *> &p_program_args)
{
struct lwp_info *new_lwp;
int pid;
ptid_t ptid;
struct cleanup *restore_personality
= maybe_disable_address_space_randomization (disable_randomization);
- std::string str_program_args = stringify_argv (program_args);
+ std::string str_program_args = stringify_argv (p_program_args);
pid = fork_inferior (program,
str_program_args.c_str (),
@@ -1441,13 +1441,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))
@@ -1741,7 +1741,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);
@@ -1803,7 +1803,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;
@@ -2478,7 +2478,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)))
@@ -2657,7 +2657,7 @@ resume_stopped_resumed_lwps (thread_info *thread)
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 = 0;
@@ -2899,7 +2899,7 @@ count_events_callback (thread_info *thread, 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)++;
@@ -2913,7 +2913,7 @@ select_singlestep_lwp_callback (thread_info
*thread, void *data)
{
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;
@@ -2932,7 +2932,7 @@ select_event_lwp_callback (thread_info *thread,
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;
@@ -4661,7 +4661,7 @@ linux_set_resume_request (thread_info *thread,
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",
@@ -5101,7 +5101,7 @@ linux_resume_one_thread (thread_info *thread, 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;
}
@@ -5124,8 +5124,8 @@ linux_resume_one_thread (thread_info *thread, void
*arg)
/* If this is the same signal we were previously stopped by,
make sure to queue its siginfo. */
- 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, &info) == 0)
info_p = &info;
@@ -5148,7 +5148,7 @@ linux_resume_one_thread (thread_info *thread, void
*arg)
debug_printf ("leaving LWP %ld stopped\n", lwpid_of (thread));
}
- thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+ thread->last_waitstatus.kind = TARGET_WAITKIND_IGNORE;
lwp->resume = NULL;
return 0;
}
@@ -5251,7 +5251,7 @@ proceed_one_lwp (thread_info *thread, 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",
@@ -302,7 +302,7 @@ struct lwp_info
enum target_waitkind syscall_state;
/* 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
@@ -103,7 +103,6 @@ struct sym_cache
struct sym_cache *next;
};
-int remote_debug = 0;
struct ui_file *gdb_stdlog;
static int remote_is_stdio = 0;
@@ -115,17 +114,19 @@ static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
extern int using_threads;
extern int debug_threads;
-/* If true, then GDB has requested noack mode. */
-int noack_mode = 0;
-/* If true, then we tell GDB to use noack mode by default. */
-int transport_is_reliable = 0;
-
#ifdef USE_WIN32API
# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
#endif
int
+get_remote_desc (void)
+{
+ return remote_desc;
+}
+
+
+int
gdb_connected (void)
{
return remote_desc != INVALID_DESCRIPTOR;
@@ -167,6 +168,9 @@ handle_accept_event (int err, gdb_client_data
client_data)
if (remote_desc == -1)
perror_with_name ("Accept failed");
+ struct multi_client_states *client_states = get_client_states();
+ client_states->set_client_state (remote_desc);
+
/* Enable TCP keep alive process. */
tmp = 1;
setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
@@ -841,14 +845,6 @@ initialize_async_io (void)
#endif
}
-/* Internal buffer used by readchar.
- These are global to readchar because reschedule_remote needs to be
- able to tell whether the buffer is empty. */
-
-static unsigned char readchar_buf[BUFSIZ];
-static int readchar_bufcnt = 0;
-static unsigned char *readchar_bufp;
-
/* Returns next char from remote GDB. -1 if error. */
static int
@@ -1459,14 +1455,14 @@ look_up_one_symbol (const char *name, CORE_ADDR
*addrp, int may_ask_gdb)
return 0;
/* Send the request. */
- strcpy (own_buf, "qSymbol:");
- bin2hex ((const gdb_byte *) name, own_buf + strlen ("qSymbol:"),
+ strcpy (own_buffer, "qSymbol:");
+ bin2hex ((const gdb_byte *) name, own_buffer + strlen ("qSymbol:"),
strlen (name));
- if (putpkt (own_buf) < 0)
+ if (putpkt (own_buffer) < 0)
return -1;
/* FIXME: Eventually add buffer overflow checking (to getpkt?) */
- len = getpkt (own_buf);
+ len = getpkt (own_buffer);
if (len < 0)
return -1;
@@ -1477,45 +1473,45 @@ look_up_one_symbol (const char *name, CORE_ADDR
*addrp, int may_ask_gdb)
while it figures out the address of the symbol. */
while (1)
{
- if (own_buf[0] == 'm')
+ if (own_buffer[0] == 'm')
{
CORE_ADDR mem_addr;
- unsigned char *mem_buf;
+ unsigned char *mem_buffer;
unsigned int mem_len;
- decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
- mem_buf = (unsigned char *) xmalloc (mem_len);
- if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
- bin2hex (mem_buf, own_buf, mem_len);
+ decode_m_packet (&own_buffer[1], &mem_addr, &mem_len);
+ mem_buffer = (unsigned char *) xmalloc (mem_len);
+ if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+ bin2hex (mem_buffer, own_buffer, mem_len);
else
- write_enn (own_buf);
- free (mem_buf);
- if (putpkt (own_buf) < 0)
+ write_enn (own_buffer);
+ free (mem_buffer);
+ if (putpkt (own_buffer) < 0)
return -1;
}
- else if (own_buf[0] == 'v')
+ else if (own_buffer[0] == 'v')
{
int new_len = -1;
- handle_v_requests (own_buf, len, &new_len);
+ handle_v_requests (own_buffer, len, &new_len);
if (new_len != -1)
- putpkt_binary (own_buf, new_len);
+ putpkt_binary (own_buffer, new_len);
else
- putpkt (own_buf);
+ putpkt (own_buffer);
}
else
break;
- len = getpkt (own_buf);
+ len = getpkt (own_buffer);
if (len < 0)
return -1;
}
- if (!startswith (own_buf, "qSymbol:"))
+ if (!startswith (own_buffer, "qSymbol:"))
{
- warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf);
+ warning ("Malformed response to qSymbol, ignoring: %s\n",
own_buffer);
return -1;
}
- p = own_buf + strlen ("qSymbol:");
+ p = own_buffer + strlen ("qSymbol:");
q = p;
while (*q && *q != ':')
q++;
@@ -1555,13 +1551,13 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR
oldloc)
ULONGEST written = 0;
/* Send the request. */
- sprintf (own_buf, "qRelocInsn:%s;%s", paddress (oldloc),
+ sprintf (own_buffer, "qRelocInsn:%s;%s", paddress (oldloc),
paddress (*to));
- if (putpkt (own_buf) < 0)
+ if (putpkt (own_buffer) < 0)
return -1;
/* FIXME: Eventually add buffer overflow checking (to getpkt?) */
- len = getpkt (own_buf);
+ len = getpkt (own_buffer);
if (len < 0)
return -1;
@@ -1569,61 +1565,61 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR
oldloc)
wait for the qRelocInsn "response". That requires re-entering
the main loop. For now, this is an adequate approximation; allow
GDB to access memory. */
- while (own_buf[0] == 'm' || own_buf[0] == 'M' || own_buf[0] == 'X')
+ while (own_buffer[0] == 'm' || own_buffer[0] == 'M' || own_buffer[0]
== 'X')
{
CORE_ADDR mem_addr;
- unsigned char *mem_buf = NULL;
+ unsigned char *mem_buffer = NULL;
unsigned int mem_len;
- if (own_buf[0] == 'm')
+ if (own_buffer[0] == 'm')
{
- decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
- mem_buf = (unsigned char *) xmalloc (mem_len);
- if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
- bin2hex (mem_buf, own_buf, mem_len);
+ decode_m_packet (&own_buffer[1], &mem_addr, &mem_len);
+ mem_buffer = (unsigned char *) xmalloc (mem_len);
+ if (read_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+ bin2hex (mem_buffer, own_buffer, mem_len);
else
- write_enn (own_buf);
+ write_enn (own_buffer);
}
- else if (own_buf[0] == 'X')
+ else if (own_buffer[0] == 'X')
{
- if (decode_X_packet (&own_buf[1], len - 1, &mem_addr,
- &mem_len, &mem_buf) < 0
- || write_inferior_memory (mem_addr, mem_buf, mem_len) != 0)
- write_enn (own_buf);
+ if (decode_X_packet (&own_buffer[1], len - 1, &mem_addr,
+ &mem_len, &mem_buffer) < 0
+ || write_inferior_memory (mem_addr, mem_buffer, mem_len) != 0)
+ write_enn (own_buffer);
else
- write_ok (own_buf);
+ write_ok (own_buffer);
}
else
{
- decode_M_packet (&own_buf[1], &mem_addr, &mem_len, &mem_buf);
- if (write_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
- write_ok (own_buf);
+ decode_M_packet (&own_buffer[1], &mem_addr, &mem_len, &mem_buffer);
+ if (write_inferior_memory (mem_addr, mem_buffer, mem_len) == 0)
+ write_ok (own_buffer);
else
- write_enn (own_buf);
+ write_enn (own_buffer);
}
- free (mem_buf);
- if (putpkt (own_buf) < 0)
+ free (mem_buffer);
+ if (putpkt (own_buffer) < 0)
return -1;
- len = getpkt (own_buf);
+ len = getpkt (own_buffer);
if (len < 0)
return -1;
}
- if (own_buf[0] == 'E')
+ if (own_buffer[0] == 'E')
{
warning ("An error occurred while relocating an instruction: %s\n",
- own_buf);
+ own_buffer);
return -1;
}
- if (!startswith (own_buf, "qRelocInsn:"))
+ if (!startswith (own_buffer, "qRelocInsn:"))
{
warning ("Malformed response to qRelocInsn, ignoring: %s\n",
- own_buf);
+ own_buffer);
return -1;
}
- unpack_varlen_hex (own_buf + strlen ("qRelocInsn:"), &written);
+ unpack_varlen_hex (own_buffer + strlen ("qRelocInsn:"), &written);
*to += written;
return 0;
@@ -19,10 +19,7 @@
#ifndef REMOTE_UTILS_H
#define REMOTE_UTILS_H
-extern int remote_debug;
-extern int noack_mode;
-extern int transport_is_reliable;
-
+int get_remote_desc (void);
int gdb_connected (void);
#define STDIO_CONNECTION_NAME "stdio"
@@ -66,63 +66,6 @@ static gdb_environ our_environ;
int startup_with_shell = 1;
-/* The thread set with an `Hc' packet. `Hc' is deprecated in favor of
- `vCont'. Note the multi-process extensions made `vCont' a
- requirement, so `Hc pPID.TID' is pretty much undefined. So
- CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for
- resuming all threads of the process (again, `Hc' isn't used for
- multi-process), or a specific thread ptid_t. */
-ptid_t cont_thread;
-
-/* The thread set with an `Hg' packet. */
-ptid_t general_thread;
-
-int server_waiting;
-
-static int extended_protocol;
-static int response_needed;
-static int exit_requested;
-
-/* --once: Exit after the first connection has closed. */
-int run_once;
-
-int multi_process;
-int report_fork_events;
-int report_vfork_events;
-int report_exec_events;
-int report_thread_events;
-
-/* Whether to report TARGET_WAITKING_NO_RESUMED events. */
-static int report_no_resumed;
-
-int non_stop;
-int swbreak_feature;
-int hwbreak_feature;
-
-/* True if the "vContSupported" feature is active. In that case, GDB
- wants us to report whether single step is supported in the reply to
- "vCont?" packet. */
-static int vCont_supported;
-
-/* Whether we should attempt to disable the operating system's address
- space randomization feature before starting an inferior. */
-int disable_randomization = 1;
-
-static char *program_name = NULL;
-static std::vector<char *> program_args;
-static std::string wrapper_argv;
-
-int pass_signals[GDB_SIGNAL_LAST];
-int program_signals[GDB_SIGNAL_LAST];
-int program_signals_p;
-
-/* The PID of the originally created or attached inferior. Used to
- send signals to the process when GDB sends us an asynchronous interrupt
- (user hitting Control-C in the client), and to wait for the child to
exit
- when no longer debugging it. */
-
-unsigned long signal_pid;
-
/* Set if you want to disable optional thread related packets support
in gdbserver, for the sake of testing GDB against stubs that don't
support them. */
@@ -131,13 +74,6 @@ int disable_packet_Tthread;
int disable_packet_qC;
int disable_packet_qfThreadInfo;
-/* Last status reported to GDB. */
-struct target_waitstatus last_status;
-ptid_t last_ptid;
-
-char *own_buf;
-static unsigned char *mem_buf;
-
/* A sub-class of 'struct notif_event' for stop, holding information
relative to a single stop reply. We keep a queue of these to
push to GDB in non-stop mode. */
@@ -159,6 +95,159 @@ static struct btrace_config current_btrace_conf;
DEFINE_QUEUE_P (notif_event_p);
+static struct multi_client_states client_states;
+
+
+multi_client_states*
+get_client_states (void)
+{
+ return &client_states;
+}
+
+
+client_state*
+get_client_state (void)
+{
+ return client_states.get_client_state();
+}
+
+
+client_state::client_state (gdb_fildes_t fd, client_state *csidx)
+{
+ file_desc = fd;
+ attached_to_client = csidx->attached_to_client;
+ // nonstop_pending = csidx->nonstop_pending;
+ catch_syscalls = csidx->catch_syscalls;
+ extended_protocol_ = csidx->extended_protocol_;
+ response_needed_ = csidx->response_needed_;
+ exit_requested_ = csidx->exit_requested_;
+ run_once_ = csidx->run_once_;
+ multi_process_ = csidx->multi_process_;
+ report_fork_events_ = csidx->report_fork_events_;
+ report_vfork_events_ = csidx->report_vfork_events_;
+ report_exec_events_ = csidx->report_exec_events_;
+ report_thread_events_ = csidx->report_thread_events_;
+ report_no_resumed_ = csidx->report_no_resumed_;
+ non_stop_ = csidx->non_stop_;
+ swbreak_feature_ = csidx->swbreak_feature_;
+ hwbreak_feature_ = csidx->hwbreak_feature_;
+ vCont_supported_ = csidx->vCont_supported_;
+ disable_randomization_ = csidx->disable_randomization_;
+ program_name_ = csidx->program_name_;
+ program_args_ = csidx->program_args_;
+ wrapper_argv_ = csidx->wrapper_argv_;
+ remote_debug_ = csidx->remote_debug_;
+ noack_mode_ = csidx->noack_mode_;
+ transport_is_reliable_ = csidx->transport_is_reliable_;
+ ss = new (server_state);
+ ss->mem_buf_ = csidx->ss->mem_buf_;
+ ss->readchar_bufcnt_ = 0;
+ packet_type = other_packet;
+ last_packet_type = other_packet;
+ // pending = none_pending;
+ notify_buffer_ = NULL;
+ own_buffer_ = (char*) xmalloc (PBUFSIZ + 1);
+ ss->attach_count_ = 0;
+ ss->cont_thread_ = null_ptid;
+ ss->general_thread_ = null_ptid;
+ ss->signal_pid_ = 0;
+ ss->last_ptid_ = null_ptid;
+ ss->last_status_.kind = TARGET_WAITKIND_IGNORE;
+ if (csidx->file_desc < 0)
+ {
+ ss->all_processes_ = all_processes;
+ ss->all_threads_ = all_threads;
+ ss->current_thread_ = current_thread;
+ }
+ else
+ ss->current_thread_ = NULL;
+}
+
+
+/* Add a new client state for FD or return if found */
+
+client_state *
+multi_client_states::set_client_state (gdb_fildes_t fd)
+{
+/* States:
+ * fd = -1 add initial client state
+ * fd = F add client state for fd F
+ */
+
+ client_state *csidx, *cs;
+
+ /* add/return initial client state */
+ if (fd == -1)
+ {
+ if (client_states.cs.empty())
+ {
+ client_states.cs[fd] = new (client_state);
+ client_states.cs[fd]->ss = new (server_state);
+ client_states.cs[fd]->file_desc = fd;
+ }
+ client_states.current_cs = client_states.cs[fd];
+ return client_states.cs[fd];
+ }
+
+ /* add/return client state for fd F */
+
+ std::map<gdb_fildes_t,client_state*>::iterator it;
+ it = client_states.cs.find(fd);
+ if (it != client_states.cs.end())
+ {
+ client_states.current_cs = it->second;
+ return it->second;
+ }
+ else
+ csidx = client_states.cs.rbegin()->second;
+
+ /* add client state S for fd F */
+ client_states.cs[fd] = cs = new client_state (fd, csidx);
+ cs->file_desc = fd;
+ client_states.set_current_client (cs);
+ return cs;
+}
+
+
+/* Remove the client state corresponding to fd */
+
+void
+multi_client_states::delete_client_state (gdb_fildes_t fd)
+{
+ client_state *cs, *previous_cs = NULL;
+ std::map<gdb_fildes_t,client_state*>::iterator it;
+
+ for (it = client_states.cs.begin(); it != client_states.cs.end(); ++it)
+ {
+ server_state *ss= NULL;
+
+ cs = it->second;
+
+ if (it->first == fd)
+ {
+ client_states.current_cs = previous_cs;
+ extended_protocol = cs->extended_protocol_;
+ run_once = cs->run_once_;
+ non_stop = cs->non_stop_;
+ if (cs->notify_buffer_)
+ xfree (cs->notify_buffer_);
+ free (cs->own_buffer_);
+ delete (cs->ss);
+ delete (cs);
+ client_states.cs.erase (fd);
+ }
+ previous_cs = cs;
+ }
+}
+
+
+#if 0
+static int
+queue_stop_reply_callback (thread_info *thread, void *arg);
+#endif
+
+/**********************************/
+
/* Put a stop reply to the stop reply queue. */
static void
@@ -308,14 +397,12 @@ 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;
}
-extern int remote_debug;
-
/* Decode a qXfer read request. Return 0 if everything looks OK,
or -1 otherwise. */
@@ -639,6 +726,7 @@ handle_general_set (char *own_buf)
}
else
VEC_safe_push (int, process->syscalls_to_catch, ANY_SYSCALL);
+ client_states.current_cs->catch_syscalls = 1;
}
write_ok (own_buf);
@@ -1831,20 +1919,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;
}
@@ -1856,7 +1944,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;
}
@@ -1867,7 +1955,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;
}
}
@@ -1905,20 +1993,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;
}
@@ -1929,7 +2017,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;
}
}
@@ -2717,9 +2805,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->id;
- prepare_resume_reply (own_buf, last_ptid, &last_status);
+ prepare_resume_reply (own_buffer, last_ptid, &last_status);
return 1;
}
return 0;
@@ -2861,7 +2949,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);
@@ -2871,7 +2959,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;
}
@@ -2879,14 +2967,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
@@ -3229,7 +3317,7 @@ queue_stop_reply_callback (thread_info *thread)
struct vstop_notif *new_notif = XNEW (struct vstop_notif);
new_notif->ptid = thread->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 (¬if_stop,
@@ -3241,19 +3329,19 @@ queue_stop_reply_callback (thread_info *thread)
{
if (debug_threads)
{
- std::string status_string
- = target_waitstatus_to_string (&thread->last_status);
+ std::string status_string
+ = target_waitstatus_to_string (&thread->last_waitstatus);
debug_printf ("Reporting thread %s as already stopped with %s\n",
target_pid_to_str (thread->id),
status_string.c_str ());
}
- 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 (thread->id, &thread->last_status);
+ queue_stop_reply (thread->id, &thread->last_waitstatus);
}
}
}
@@ -3267,12 +3355,12 @@ gdb_wants_thread_stopped (thread_info *thread)
{
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;
}
}
@@ -3299,15 +3387,15 @@ clear_pending_status_callback (thread_info *thread)
static void
set_pending_status_callback (thread_info *thread)
{
- 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;
}
@@ -3329,8 +3417,8 @@ handle_status (char *own_buf)
{
for_each_thread (queue_stop_reply_callback);
- /* The first is sent immediatly. OK is sent if there is no
- stopped thread, which is the same handling of the vStopped
+ /* The first is sent immediately. OK is sent if there is no
+ stopped thread, which is the same handling as the vStopped
packet (by design). */
notif_write_event (¬if_stop, own_buf);
}
@@ -3383,8 +3471,8 @@ handle_status (char *own_buf)
general_thread = thread->id;
set_desired_thread ();
- gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
- prepare_resume_reply (own_buf, tp->id, &tp->last_status);
+ gdb_assert (tp->last_waitstatus.kind != TARGET_WAITKIND_IGNORE);
+ prepare_resume_reply (own_buf, tp->id, &tp->last_waitstatus);
}
else
strcpy (own_buf, "W00");
@@ -3567,6 +3655,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();
+ client_states.set_client_state (remote_desc);
bool selftest = false;
const char *selftest_filter = NULL;
@@ -3678,15 +3771,15 @@ captured_main (int argc, char *argv[])
break;
}
else if (strcmp (*next_arg, "--disable-randomization") == 0)
- disable_randomization = 1;
+ disable_randomization_arg = 1;
else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
- disable_randomization = 0;
+ disable_randomization_arg = 0;
else if (strcmp (*next_arg, "--startup-with-shell") == 0)
startup_with_shell = true;
else if (strcmp (*next_arg, "--no-startup-with-shell") == 0)
startup_with_shell = false;
else if (strcmp (*next_arg, "--once") == 0)
- run_once = 1;
+ run_once_arg = 1;
else if (strcmp (*next_arg, "--selftest") == 0)
selftest = true;
else if (startswith (*next_arg, "--selftest="))
@@ -3704,6 +3797,9 @@ captured_main (int argc, char *argv[])
continue;
}
+ run_once = run_once_arg;
+ disable_randomization = disable_randomization_arg;
+
if (port == NULL)
{
port = *next_arg;
@@ -3765,7 +3861,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 (selftest)
@@ -3824,10 +3920,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;
@@ -3907,8 +3999,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)
@@ -4010,12 +4102,13 @@ process_serial_event (void)
unsigned char sig;
int packet_len;
int new_packet_len = -1;
+ client_state *cs = get_client_state();
disable_async_io ();
response_needed = 0;
- packet_len = getpkt (own_buf);
- if (packet_len <= 0)
+ packet_length = getpkt (own_buffer);
+ if (packet_length <= 0)
{
remote_close ();
/* Force an event loop break. */
@@ -4023,31 +4116,31 @@ process_serial_event (void)
}
response_needed = 1;
- char ch = own_buf[0];
+ char ch = own_buffer[0];
switch (ch)
{
case 'q':
- handle_query (own_buf, packet_len, &new_packet_len);
+ handle_query (own_buffer, packet_length, &new_packet_len);
break;
case 'Q':
- handle_general_set (own_buf);
+ handle_general_set (own_buffer);
break;
case 'D':
- handle_detach (own_buf);
+ handle_detach (own_buffer);
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')
{
- require_running_or_break (own_buf);
+ require_running_or_break (own_buffer);
- ptid_t thread_id = read_ptid (&own_buf[2], NULL);
+ ptid_t thread_id = read_ptid (&own_buffer[2], NULL);
if (thread_id == null_ptid || thread_id == minus_one_ptid)
thread_id = null_ptid;
@@ -4058,7 +4151,7 @@ process_serial_event (void)
if (thread == NULL)
{
- write_enn (own_buf);
+ write_enn (own_buffer);
break;
}
@@ -4069,12 +4162,12 @@ process_serial_event (void)
/* The ptid represents a lwp/tid. */
if (find_thread_ptid (thread_id) == NULL)
{
- 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))
{
@@ -4093,20 +4186,20 @@ process_serial_event (void)
set_desired_thread ();
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_or_break (own_buf);
+ require_running_or_break (own_buffer);
if (current_traceframe >= 0)
{
struct regcache *regcache
@@ -4114,9 +4207,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
@@ -4124,85 +4217,85 @@ process_serial_event (void)
struct regcache *regcache;
if (!set_desired_thread ())
- 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_or_break (own_buf);
+ require_running_or_break (own_buffer);
if (current_traceframe >= 0)
- write_enn (own_buf);
+ write_enn (own_buffer);
else
{
struct regcache *regcache;
if (!set_desired_thread ())
- 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_or_break (own_buf);
- decode_m_packet (&own_buf[1], &mem_addr, &len);
+ require_running_or_break (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_or_break (own_buf);
- decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
+ require_running_or_break (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_or_break (own_buf);
- if (decode_X_packet (&own_buf[1], packet_len - 1,
+ require_running_or_break (own_buffer);
+ if (decode_X_packet (&own_buffer[1], packet_length - 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_or_break (own_buf);
- hex2bin (own_buf + 1, &sig, 1);
+ require_running_or_break (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_or_break (own_buf);
- hex2bin (own_buf + 1, &sig, 1);
+ require_running_or_break (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_or_break (own_buf);
+ require_running_or_break (own_buffer);
signal = 0;
- myresume (own_buf, 0, signal);
+ myresume (own_buffer, 0, signal);
break;
case 's':
- require_running_or_break (own_buf);
+ require_running_or_break (own_buffer);
signal = 0;
- myresume (own_buf, 1, signal);
+ myresume (own_buffer, 1, signal);
break;
case 'Z': /* insert_ ... */
/* Fallthrough. */
@@ -4211,12 +4304,12 @@ 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';
- const char *p = &own_buf[3];
+ char *p = &own_buffer[3];
- p = unpack_varlen_hex (p, &addr);
+ p = (char*)unpack_varlen_hex (p, &addr);
kind = strtol (p + 1, &dataptr, 16);
if (insert)
@@ -4242,12 +4335,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':
@@ -4274,19 +4367,19 @@ process_serial_event (void)
case 'T':
{
- require_running_or_break (own_buf);
+ require_running_or_break (own_buffer);
- ptid_t thread_id = read_ptid (&own_buf[1], NULL);
+ ptid_t thread_id = read_ptid (&own_buffer[1], NULL);
if (find_thread_ptid (thread_id) == NULL)
{
- 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':
@@ -4330,26 +4423,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_length, &new_packet_len);
break;
default:
/* It is a request we don't understand. Respond with an empty
packet so that gdb knows that we don't support this
request. */
- own_buf[0] = '\0';
+ 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;
@@ -4427,7 +4520,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)
@@ -60,52 +60,19 @@ int vsnprintf(char *str, size_t size, const char
*format, va_list ap);
#include "gdb_signals.h"
#include "target.h"
#include "mem-break.h"
-#include "gdbthread.h"
-#include "inferiors.h"
#include "environ.h"
+#include <list>
+#include <map>
/* Target-specific functions */
void initialize_low ();
-/* Public variables in server.c */
-
-extern ptid_t cont_thread;
-extern ptid_t general_thread;
-
-extern int server_waiting;
-extern int pass_signals[];
-extern int program_signals[];
-extern int program_signals_p;
-
extern int disable_packet_vCont;
extern int disable_packet_Tthread;
extern int disable_packet_qC;
extern int disable_packet_qfThreadInfo;
-extern char *own_buf;
-
-extern int run_once;
-extern int multi_process;
-extern int report_fork_events;
-extern int report_vfork_events;
-extern int report_exec_events;
-extern int report_thread_events;
-extern int non_stop;
-
-/* True if the "swbreak+" feature is active. In that case, GDB wants
- us to report whether a trap is explained by a software breakpoint
- and for the server to handle PC adjustment if necessary on this
- target. Only enabled if the target supports it. */
-extern int swbreak_feature;
-
-/* True if the "hwbreak+" feature is active. In that case, GDB wants
- us to report whether a trap is explained by a hardware breakpoint.
- Only enabled if the target supports it. */
-extern int hwbreak_feature;
-
-extern int disable_randomization;
-
#if USE_WIN32API
#include <winsock2.h>
typedef SOCKET gdb_fildes_t;
@@ -158,8 +125,204 @@ extern void post_fork_inferior (int pid, const
char *program);
/* Get the gdb_environ being used in the current session. */
extern gdb_environ *get_environ ();
-extern target_waitstatus last_status;
extern ptid_t last_ptid;
extern unsigned long signal_pid;
#endif /* SERVER_H */
+
+/* Description of the remote protocol state for the currently
+ connected target. This is per-target state, and independent of the
+ selected architecture. */
+
+struct server_state
+{
+ int attach_count_;
+ /* From server.c */
+ /* The thread set with an `Hc' packet. `Hc' is deprecated in favor of
+ `vCont'. Note the multi-process extensions made `vCont' a
+ requirement, so `Hc pPID.TID' is pretty much undefined. So
+ CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for
+ resuming all threads of the process (again, `Hc' isn't used for
+ multi-process), or a specific thread ptid_t. */
+ ptid_t cont_thread_;
+ /* The thread set with an `Hg' packet. */
+ ptid_t general_thread_;
+ /* The PID of the originally created or attached inferior. Used to
+ send signals to the process when GDB sends us an asynchronous
interrupt
+ (user hitting Control-C in the client), and to wait for the child
to exit
+ when no longer debugging it. */
+
+ unsigned long signal_pid_;
+ /* Last status reported to GDB. */
+ struct target_waitstatus last_status_;
+ /* Was last status an exit status? (sticky if yes) */
+ int last_status_exited;
+ ptid_t last_ptid_;
+ unsigned char *mem_buf_;
+
+ /* from remote-utils.c */
+ /* Internal buffer used by readchar.
+ These are global to readchar because reschedule_remote needs to be
+ able to tell whether the buffer is empty. */
+ unsigned char readchar_buf_[BUFSIZ];
+ int readchar_bufcnt_;
+ unsigned char *readchar_bufp_;
+ /* from inferiors.c */
+ std::list<process_info *> all_processes_;
+ std::list<thread_info *> all_threads_;
+
+ struct thread_info *current_thread_;
+};
+
+typedef struct server_state server_state;
+
+
+enum packet_types { other_packet, vContc, vConts, vContt, vRun,
vAttach, Hg, g_or_m, vStopped };
+typedef enum packet_types packet_types;
+
+enum exit_types { no_exit, have_exit, sent_exit };
+typedef enum exit_types exit_types;
+
+
+struct client_state
+{
+ gdb_fildes_t file_desc;
+ int attached_to_client;
+ int packet_type;
+ int last_packet_type;
+ int pending;
+ int nonstop_pending;
+ int catch_syscalls;
+ ptid_t last_cont_ptid;
+ ptid_t new_general_thread;
+ struct target_waitstatus last_cont_waitstatus;
+
+ /* From server.c */
+ int server_waiting_;
+
+ int extended_protocol_;
+ int response_needed_;
+ int exit_requested_;
+
+ /* --once: Exit after the first connection has closed. */
+ int run_once_;
+
+ int multi_process_;
+ int report_fork_events_;
+ int report_vfork_events_;
+ int report_exec_events_;
+ int report_thread_events_;
+ /* Whether to report TARGET_WAITKING_NO_RESUMED events. */
+ int report_no_resumed_;
+ int non_stop_;
+ /* True if the "swbreak+" feature is active. In that case, GDB wants
+ us to report whether a trap is explained by a software breakpoint
+ and for the server to handle PC adjustment if necessary on this
+ target. Only enabled if the target supports it. */
+ int swbreak_feature_;
+ /* True if the "hwbreak+" feature is active. In that case, GDB wants
+ us to report whether a trap is explained by a hardware breakpoint.
+ Only enabled if the target supports it. */
+ int hwbreak_feature_;
+
+ /* True if the "vContSupported" feature is active. In that case, GDB
+ wants us to report whether single step is supported in the reply to
+ "vCont?" packet. */
+ int vCont_supported_;
+
+ /* Whether we should attempt to disable the operating system's address
+ space randomization feature before starting an inferior. */
+ int disable_randomization_;
+
+ char *program_name_ = NULL;
+ std::vector<char *> program_args_;
+ std::string wrapper_argv_;
+
+ int packet_length_;
+
+ int pass_signals_[GDB_SIGNAL_LAST];
+ int program_signals_[GDB_SIGNAL_LAST];
+ int program_signals_p_;
+
+ char *notify_buffer_;
+ /* Renamed from own_buf to avoid macro name conflict with a common
local variable name */
+ char *own_buffer_;
+
+ /* from remote-utils.c */
+ int remote_debug_;
+ /* If true, then GDB has requested noack mode. */
+ int noack_mode_;
+ /* If true, then we tell GDB to use noack mode by default. */
+ int transport_is_reliable_;
+
+ server_state *ss;
+
+ client_state () {};
+ client_state (gdb_fildes_t, client_state*);
+};
+
+typedef struct client_state client_state;
+
+
+struct multi_client_states
+{
+public:
+ std::map<gdb_fildes_t,client_state*> cs;
+ client_state *current_cs;
+
+ client_state* get_client_state (void) { return current_cs; }
+ void set_current_client (client_state* p_cs) { current_cs = p_cs; }
+
+ client_state * set_client_state (gdb_fildes_t);
+ void free_client_state (client_state *cs);
+ void delete_client_state (gdb_fildes_t fd);
+};
+
+client_state* get_client_state (void);
+struct multi_client_states * get_client_states (void);
+
+
+#define attach_count (get_client_state()->ss->attach_count_)
+#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 wrapper_argv (get_client_state()->wrapper_argv_)
+#define program_name (get_client_state()->program_name_)
+#define program_args (get_client_state()->program_args_)
+#define packet_length (get_client_state()->packet_length_)
+#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 notify_buffer (get_client_state()->notify_buffer_)
+#define own_buffer (get_client_state()->own_buffer_)
+#define remote_debug (get_client_state()->remote_debug_)
+#define noack_mode (get_client_state()->noack_mode_)
+#define transport_is_reliable (get_client_state()->transport_is_reliable_)
+
+#include "gdbthread.h"
+#include "inferiors.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 */