#include "remote-fileio.h"
#include "gdb/fileio.h"
+#include "gdb_stat.h"
#include "memory-map.h"
static void interrupt_query (void);
-static void set_thread (int, int);
+static void set_general_thread (struct ptid ptid);
+static void set_continue_thread (struct ptid ptid);
static int remote_thread_alive (ptid_t);
static void init_extended_remote_ops (void);
-static void remote_stop (void);
+static void remote_stop (ptid_t);
static int ishex (int ch, int *val);
static void remote_find_new_threads (void);
-static void record_currthread (int currthread);
+static void record_currthread (ptid_t currthread);
static int fromhex (int a);
void _initialize_remote (void);
-/* Controls if async mode is permitted. */
-static int remote_async_permitted = 0;
-
-static int remote_async_permitted_set = 0;
-
-static void
-set_maintenance_remote_async_permitted (char *args, int from_tty,
- struct cmd_list_element *c)
-{
- if (target_has_execution)
- {
- remote_async_permitted_set = remote_async_permitted; /* revert */
- error (_("Cannot change this setting while the inferior is running."));
- }
-
- remote_async_permitted = remote_async_permitted_set;
-}
-
-static void
-show_maintenance_remote_async_permitted (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
-{
- fprintf_filtered (file, _("\
-Controlling the remote inferior in asynchronous mode is %s.\n"),
- value);
-}
-
/* For "remote". */
static struct cmd_list_element *remote_cmdlist;
skip calling getpkt. This flag is set when BUF contains a
stop reply packet and the target is not waiting. */
int cached_wait_status;
+
+ /* True, if in no ack mode. That is, neither GDB nor the stub will
+ expect acks from each other. The connection is assumed to be
+ reliable. */
+ int noack_mode;
};
/* This data could be associated with a target, but we do not always
long regnum; /* GDB's internal register number. */
LONGEST pnum; /* Remote protocol register number. */
int in_g_packet; /* Always part of G packet. */
- /* long size in bytes; == register_size (current_gdbarch, regnum);
+ /* long size in bytes; == register_size (target_gdbarch, regnum);
at present. */
- /* char *name; == gdbarch_register_name (current_gdbarch, regnum);
+ /* char *name; == gdbarch_register_name (target_gdbarch, regnum);
at present. */
};
static struct remote_arch_state *
get_remote_arch_state (void)
{
- return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
+ return gdbarch_data (target_gdbarch, remote_gdbarch_data_handle);
}
/* Fetch the global remote target state. */
static struct packet_reg *
packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
{
- if (regnum < 0 && regnum >= gdbarch_num_regs (current_gdbarch))
+ if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch))
return NULL;
else
{
packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
{
int i;
- for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+ for (i = 0; i < gdbarch_num_regs (target_gdbarch); i++)
{
struct packet_reg *r = &rsa->regs[i];
if (r->pnum == pnum)
PACKET_qSearch_memory,
PACKET_vAttach,
PACKET_vRun,
+ PACKET_QStartNoAckMode,
PACKET_MAX
};
\f
+static ptid_t magic_null_ptid;
+static ptid_t not_sent_ptid;
+static ptid_t any_thread_ptid;
+
+/* These are the threads which we last sent to the remote system. The
+ TID member will be -1 for all or -2 for not sent yet. */
+
+static ptid_t general_thread;
+static ptid_t continue_thread;
-/* These are the threads which we last sent to the remote system.
- -1 for all or -2 for not sent yet. */
-static int general_thread;
-static int continue_thread;
/* Call this function as a result of
1) A halt indication (T packet) containing a thread id
*/
static void
-record_currthread (int currthread)
+record_currthread (ptid_t currthread)
{
general_thread = currthread;
/* If this is a new thread, add it to GDB's thread list.
If we leave it up to WFI to do this, bad things will happen. */
- if (!in_thread_list (pid_to_ptid (currthread)))
- add_thread (pid_to_ptid (currthread));
+ if (!in_thread_list (currthread))
+ {
+ if (ptid_equal (pid_to_ptid (ptid_get_pid (currthread)), inferior_ptid))
+ {
+ /* inferior_ptid has no thread member yet. This can happen
+ with the vAttach -> remote_wait,"TAAthread:" path if the
+ stub doesn't support qC. This is the first stop reported
+ after an attach, so this is the main thread. Update the
+ ptid in the thread list. */
+ struct thread_info *th = find_thread_pid (inferior_ptid);
+ inferior_ptid = th->ptid = currthread;
+ }
+ else if (ptid_equal (magic_null_ptid, inferior_ptid))
+ {
+ /* inferior_ptid is not set yet. This can happen with the
+ vRun -> remote_wait,"TAAthread:" path if the stub
+ doesn't support qC. This is the first stop reported
+ after an attach, so this is the main thread. Update the
+ ptid in the thread list. */
+ struct thread_info *th = find_thread_pid (inferior_ptid);
+ inferior_ptid = th->ptid = currthread;
+ }
+ else
+ /* This is really a new thread. Add it. */
+ add_thread (currthread);
+ }
}
static char *last_pass_packet;
}
}
-#define MAGIC_NULL_PID 42000
-
+/* If PTID is MAGIC_NULL_PTID, don't set any thread. If PTID is
+ MINUS_ONE_PTID, set the thread to -1, so the stub returns the
+ thread. If GEN is set, set the general thread, if not, then set
+ the step/continue thread. */
static void
-set_thread (int th, int gen)
+set_thread (struct ptid ptid, int gen)
{
struct remote_state *rs = get_remote_state ();
+ ptid_t state = gen ? general_thread : continue_thread;
char *buf = rs->buf;
- int state = gen ? general_thread : continue_thread;
+ char *endbuf = rs->buf + get_remote_packet_size ();
- if (state == th)
+ if (ptid_equal (state, ptid))
return;
- buf[0] = 'H';
- buf[1] = gen ? 'g' : 'c';
- if (th == MAGIC_NULL_PID)
+ *buf++ = 'H';
+ *buf++ = gen ? 'g' : 'c';
+ if (ptid_equal (ptid, magic_null_ptid))
+ xsnprintf (buf, endbuf - buf, "0");
+ else if (ptid_equal (ptid, any_thread_ptid))
+ xsnprintf (buf, endbuf - buf, "0");
+ else if (ptid_equal (ptid, minus_one_ptid))
+ xsnprintf (buf, endbuf - buf, "-1");
+ else
{
- buf[2] = '0';
- buf[3] = '\0';
+ int tid = ptid_get_tid (ptid);
+ if (tid < 0)
+ xsnprintf (buf, endbuf - buf, "-%x", -tid);
+ else
+ xsnprintf (buf, endbuf - buf, "%x", tid);
}
- else if (th < 0)
- xsnprintf (&buf[2], get_remote_packet_size () - 2, "-%x", -th);
- else
- xsnprintf (&buf[2], get_remote_packet_size () - 2, "%x", th);
- putpkt (buf);
+ putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
if (gen)
- general_thread = th;
+ general_thread = ptid;
else
- continue_thread = th;
+ continue_thread = ptid;
+}
+
+static void
+set_general_thread (struct ptid ptid)
+{
+ set_thread (ptid, 1);
+}
+
+static void
+set_continue_thread (struct ptid ptid)
+{
+ set_thread (ptid, 0);
}
+
\f
-/* Return nonzero if the thread TH is still alive on the remote system. */
+/* Return nonzero if the thread PTID is still alive on the remote
+ system. */
static int
remote_thread_alive (ptid_t ptid)
{
struct remote_state *rs = get_remote_state ();
- int tid = PIDGET (ptid);
+ int tid = ptid_get_tid (ptid);
+
+ if (ptid_equal (ptid, magic_null_ptid))
+ /* The main thread is always alive. */
+ return 1;
+
+ if (ptid_get_pid (ptid) != 0 && ptid_get_tid (ptid) == 0)
+ /* The main thread is always alive. This can happen after a
+ vAttach, if the remote side doesn't support
+ multi-threading. */
+ return 1;
if (tid < 0)
xsnprintf (rs->buf, get_remote_packet_size (), "T-%08x", -tid);
/* remote_find_new_threads retrieves the thread list and for each
thread in the list, looks up the thread in GDB's internal list,
- ading the thread if it does not already exist. This involves
+ adding the thread if it does not already exist. This involves
getting partial thread lists from the remote target so, polling the
quit_flag is required. */
static int
remote_newthread_step (threadref *ref, void *context)
{
- ptid_t ptid;
-
- ptid = pid_to_ptid (threadref_to_int (ref));
+ int pid = ptid_get_pid (inferior_ptid);
+ ptid_t ptid = ptid_build (pid, 0, threadref_to_int (ref));
if (!in_thread_list (ptid))
add_thread (ptid);
remote_current_thread (ptid_t oldpid)
{
struct remote_state *rs = get_remote_state ();
+ char *p = rs->buf;
+ int tid;
+ int pid;
putpkt ("qC");
getpkt (&rs->buf, &rs->buf_size, 0);
if (rs->buf[0] == 'Q' && rs->buf[1] == 'C')
- /* Use strtoul here, so we'll correctly parse values whose highest
- bit is set. The protocol carries them as a simple series of
- hex digits; in the absence of a sign, strtol will see such
- values as positive numbers out of range for signed 'long', and
- return LONG_MAX to indicate an overflow. */
- return pid_to_ptid (strtoul (&rs->buf[2], NULL, 16));
+ {
+ /* Use strtoul here, so we'll correctly parse values whose
+ highest bit is set. The protocol carries them as a simple
+ series of hex digits; in the absence of a sign, strtol will
+ see such values as positive numbers out of range for signed
+ 'long', and return LONG_MAX to indicate an overflow. */
+ tid = strtoul (&rs->buf[2], NULL, 16);
+ pid = ptid_get_pid (oldpid);
+ return ptid_build (pid, 0, tid);
+ }
else
return oldpid;
}
{
remote_threadlist_iterator (remote_newthread_step, 0,
CRAZY_MAX_THREADS);
- if (PIDGET (inferior_ptid) == MAGIC_NULL_PID) /* ack ack ack */
- inferior_ptid = remote_current_thread (inferior_ptid);
}
/*
struct remote_state *rs = get_remote_state ();
char *bufp;
int tid;
+ int pid;
+ ptid_t new_thread;
if (remote_desc == 0) /* paranoia */
error (_("Command can only be used when connected to the remote target."));
positive numbers out of range for signed 'long',
and return LONG_MAX to indicate an overflow. */
tid = strtoul (bufp, &bufp, 16);
- if (tid != 0 && !in_thread_list (pid_to_ptid (tid)))
- add_thread (pid_to_ptid (tid));
+ pid = ptid_get_pid (inferior_ptid);
+ new_thread = ptid_build (pid, 0, tid);
+ if (tid != 0 && !in_thread_list (new_thread))
+ add_thread (new_thread);
}
while (*bufp++ == ','); /* comma-separated list */
putpkt ("qsThreadInfo");
internal_error (__FILE__, __LINE__,
_("remote_threads_extra_info"));
+ if (ptid_equal (tp->ptid, magic_null_ptid)
+ || (ptid_get_pid (tp->ptid) != 0 && ptid_get_tid (tp->ptid) == 0))
+ /* This is the main thread which was added by GDB. The remote
+ server doesn't know about it. */
+ return NULL;
+
if (use_threadextra_query)
{
- xsnprintf (rs->buf, get_remote_packet_size (), "qThreadExtraInfo,%x",
- PIDGET (tp->ptid));
+ xsnprintf (rs->buf, get_remote_packet_size (), "qThreadExtraInfo,%lx",
+ ptid_get_tid (tp->ptid));
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
if (rs->buf[0] != 0)
use_threadextra_query = 0;
set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
| TAG_MOREDISPLAY | TAG_DISPLAY;
- int_to_threadref (&id, PIDGET (tp->ptid));
+ int_to_threadref (&id, ptid_get_tid (tp->ptid));
if (remote_get_threadinfo (&id, set, &threadinfo))
if (threadinfo.active)
{
immediate_quit++; /* Allow user to interrupt it. */
- /* Ack any packet which the remote side has already sent. */
- serial_write (remote_desc, "+", 1);
-
/* Check whether the target is running now. */
putpkt ("?");
getpkt (&rs->buf, &rs->buf_size, 0);
strcpy (wait_status, rs->buf);
}
+ /* Start afresh. */
+ init_thread_list ();
+
/* Let the stub know that we want it to return the thread. */
- set_thread (-1, 0);
+ set_continue_thread (minus_one_ptid);
/* Without this, some commands which require an active target
(such as kill) won't work. This variable serves (at least)
These functions should be split out into seperate variables,
especially since GDB will someday have a notion of debugging
several processes. */
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+ inferior_ptid = magic_null_ptid;
/* Now, if we have thread information, update inferior_ptid. */
inferior_ptid = remote_current_thread (inferior_ptid);
+ /* Always add the main thread. */
+ add_thread_silent (inferior_ptid);
+
get_offsets (); /* Get text, data & bss offsets. */
/* Use the previously fetched status. */
/* If this is a function address, return the start of code
instead of any data function descriptor. */
- sym_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+ sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
sym_addr,
¤t_target);
PACKET_qXfer_spu_write },
{ "QPassSignals", PACKET_DISABLE, remote_supported_packet,
PACKET_QPassSignals },
+ { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
+ PACKET_QStartNoAckMode },
};
static void
remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended_p)
{
struct remote_state *rs = get_remote_state ();
+ struct packet_config *noack_config;
+
if (name == 0)
error (_("To open a remote debug connection, you need to specify what\n"
"serial device is attached to the remote system\n"
"(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.)."));
/* See FIXME above. */
- if (!remote_async_permitted)
+ if (!target_async_permitted)
wait_forever_enabled_p = 1;
/* If we're connected to a running target, target_preopen will kill it.
remote_query_supported or as they are needed. */
init_all_packet_configs ();
rs->explicit_packet_size = 0;
+ rs->noack_mode = 0;
- general_thread = -2;
- continue_thread = -2;
+ general_thread = not_sent_ptid;
+ continue_thread = not_sent_ptid;
/* Probe for ability to use "ThreadInfo" query, as required. */
use_threadinfo_query = 1;
use_threadextra_query = 1;
+ /* Ack any packet which the remote side has already sent. */
+ serial_write (remote_desc, "+", 1);
+
/* The first packet we send to the target is the optional "supported
packets" request. If the target can answer this, it will tell us
which later probes to skip. */
remote_query_supported ();
+ /* Next, we possibly activate noack mode.
+
+ If the QStartNoAckMode packet configuration is set to AUTO,
+ enable noack mode if the stub reported a wish for it with
+ qSupported.
+
+ If set to TRUE, then enable noack mode even if the stub didn't
+ report it in qSupported. If the stub doesn't reply OK, the
+ session ends with an error.
+
+ If FALSE, then don't activate noack mode, regardless of what the
+ stub claimed should be the default with qSupported. */
+
+ noack_config = &remote_protocol_packets[PACKET_QStartNoAckMode];
+
+ if (noack_config->detect == AUTO_BOOLEAN_TRUE
+ || (noack_config->detect == AUTO_BOOLEAN_AUTO
+ && noack_config->support == PACKET_ENABLE))
+ {
+ putpkt ("QStartNoAckMode");
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ if (packet_ok (rs->buf, noack_config) == PACKET_OK)
+ rs->noack_mode = 1;
+ }
+
/* Next, if the target can specify a description, read it. We do
this before anything involving memory or registers. */
target_find_description ();
- if (remote_async_permitted)
+ if (target_async_permitted)
{
/* With this target we start out by owning the terminal. */
remote_async_terminal_ours_p = 1;
if (ex.reason < 0)
{
pop_target ();
- if (remote_async_permitted)
+ if (target_async_permitted)
wait_forever_enabled_p = 1;
throw_exception (ex);
}
}
- if (remote_async_permitted)
+ if (target_async_permitted)
wait_forever_enabled_p = 1;
if (extended_p)
target_mark_running (target);
inferior_ptid = pid_to_ptid (pid);
+
+ /* Now, if we have thread information, update inferior_ptid. */
+ inferior_ptid = remote_current_thread (inferior_ptid);
+
+ /* Now, add the main thread to the thread list. */
+ add_thread_silent (inferior_ptid);
+
attach_flag = 1;
/* Next, if the target can specify a description, read it. We do
/* Resume the remote inferior by using a "vCont" packet. The thread
to be resumed is PTID; STEP and SIGGNAL indicate whether the
- resumed thread should be single-stepped and/or signalled. If PTID's
- PID is -1, then all threads are resumed; the thread to be stepped and/or
- signalled is given in the global INFERIOR_PTID. This function returns
- non-zero iff it resumes the inferior.
+ resumed thread should be single-stepped and/or signalled. If PTID
+ equals minus_one_ptid, then all threads are resumed; the thread to
+ be stepped and/or signalled is given in the global INFERIOR_PTID.
+ This function returns non-zero iff it resumes the inferior.
This function issues a strict subset of all possible vCont commands at the
moment. */
remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
- int pid = PIDGET (ptid);
char *outbuf;
struct cleanup *old_cleanup;
about overflowing BUF. Should there be a generic
"multi-part-packet" packet? */
- if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)
+ if (ptid_equal (ptid, magic_null_ptid))
{
- /* MAGIC_NULL_PTID means that we don't have any active threads, so we
- don't have any PID numbers the inferior will understand. Make sure
- to only send forms that do not specify a PID. */
+ /* MAGIC_NULL_PTID means that we don't have any active threads,
+ so we don't have any TID numbers the inferior will
+ understand. Make sure to only send forms that do not specify
+ a TID. */
if (step && siggnal != TARGET_SIGNAL_0)
outbuf = xstrprintf ("vCont;S%02x", siggnal);
else if (step)
else
outbuf = xstrprintf ("vCont;c");
}
- else if (pid == -1)
+ else if (ptid_equal (ptid, minus_one_ptid))
{
/* Resume all threads, with preference for INFERIOR_PTID. */
+ int tid = ptid_get_tid (inferior_ptid);
if (step && siggnal != TARGET_SIGNAL_0)
- outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal,
- PIDGET (inferior_ptid));
+ outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal, tid);
else if (step)
- outbuf = xstrprintf ("vCont;s:%x;c", PIDGET (inferior_ptid));
+ outbuf = xstrprintf ("vCont;s:%x;c", tid);
else if (siggnal != TARGET_SIGNAL_0)
- outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal,
- PIDGET (inferior_ptid));
+ outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal, tid);
else
outbuf = xstrprintf ("vCont;c");
}
else
{
/* Scheduler locking; resume only PTID. */
+ int tid = ptid_get_tid (ptid);
if (step && siggnal != TARGET_SIGNAL_0)
- outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, pid);
+ outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, tid);
else if (step)
- outbuf = xstrprintf ("vCont;s:%x", pid);
+ outbuf = xstrprintf ("vCont;s:%x", tid);
else if (siggnal != TARGET_SIGNAL_0)
- outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, pid);
+ outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, tid);
else
- outbuf = xstrprintf ("vCont;c:%x", pid);
+ outbuf = xstrprintf ("vCont;c:%x", tid);
}
gdb_assert (outbuf && strlen (outbuf) < get_remote_packet_size ());
{
struct remote_state *rs = get_remote_state ();
char *buf;
- int pid = PIDGET (ptid);
last_sent_signal = siggnal;
last_sent_step = step;
if (remote_vcont_resume (ptid, step, siggnal))
goto done;
- /* All other supported resume packets do use Hc, so call set_thread. */
- if (pid == -1)
- set_thread (0, 0); /* Run any thread. */
+ /* All other supported resume packets do use Hc, so set the continue
+ thread. */
+ if (ptid_equal (ptid, minus_one_ptid))
+ set_continue_thread (any_thread_ptid);
else
- set_thread (pid, 0); /* Run this thread. */
+ set_continue_thread (ptid);
buf = rs->buf;
if (siggnal != TARGET_SIGNAL_0)
NOT asynchronously. */
if (target_can_async_p ())
target_async (inferior_event_handler, 0);
- /* Tell the world that the target is now executing. */
- /* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
- this? Instead, should the client of target just assume (for
- async targets) that the target is going to start executing? Is
- this information already found in the continuation block? */
- if (target_is_async_p ())
- target_executing = 1;
}
\f
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
- target_stop ();
+ target_stop (inferior_ptid);
}
/* Perform interrupt, if the first attempt did not succeed. Just give
interrupt is requested, either by the command line or the GUI, we
will eventually end up here. */
static void
-remote_stop (void)
+remote_stop (ptid_t ptid)
{
/* Send a break or a ^C, depending on user preference. */
if (remote_debug)
static void
remote_terminal_inferior (void)
{
- if (!remote_async_permitted)
+ if (!target_async_permitted)
/* Nothing to do. */
return;
static void
remote_terminal_ours (void)
{
- if (!remote_async_permitted)
+ if (!target_async_permitted)
/* Nothing to do. */
return;
}
/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would.
- Returns "pid", which in the case of a multi-threaded
- remote OS, is the thread-id. */
+ storing status in STATUS just as `wait' would. */
static ptid_t
remote_wait (ptid_t ptid, struct target_waitstatus *status)
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
ULONGEST thread_num = -1;
+ ULONGEST process_num = -1;
ULONGEST addr;
int solibs_changed = 0;
if (strncmp (p, "thread", p1 - p) == 0)
{
p_temp = unpack_varlen_hex (++p1, &thread_num);
- record_currthread (thread_num);
p = p_temp;
}
else if ((strncmp (p, "watch", p1 - p) == 0)
phex_nz (pnum, 0), p, buf);
fieldsize = hex2bin (p, regs,
- register_size (current_gdbarch,
+ register_size (target_gdbarch,
reg->regnum));
p += 2 * fieldsize;
- if (fieldsize < register_size (current_gdbarch,
+ if (fieldsize < register_size (target_gdbarch,
reg->regnum))
warning (_("Remote reply is too short: %s"), buf);
regcache_raw_supply (get_current_regcache (),
got_status:
if (thread_num != -1)
{
- return pid_to_ptid (thread_num);
+ ptid_t ptid;
+ ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, thread_num);
+ record_currthread (ptid);
+ return ptid;
}
+
return inferior_ptid;
}
struct remote_arch_state *rsa = get_remote_arch_state ();
int i;
- set_thread (PIDGET (inferior_ptid), 1);
+ set_general_thread (inferior_ptid);
if (regnum >= 0)
{
struct remote_arch_state *rsa = get_remote_arch_state ();
int i;
- set_thread (PIDGET (inferior_ptid), 1);
+ set_general_thread (inferior_ptid);
if (regnum >= 0)
{
int address_size = remote_address_size;
/* If "remoteaddresssize" was not set, default to target address size. */
if (!address_size)
- address_size = gdbarch_addr_bit (current_gdbarch);
+ address_size = gdbarch_addr_bit (target_gdbarch);
if (address_size > 0
&& address_size < (sizeof (ULONGEST) * 8))
if (serial_write (remote_desc, buf2, p - buf2))
perror_with_name (_("putpkt: write failed"));
+ /* If this is a no acks version of the remote protocol, send the
+ packet and move on. */
+ if (rs->noack_mode)
+ break;
+
/* Read until either a timeout occurs (-2) or '+' is read. */
while (1)
{
}
#endif
}
+ return 0;
}
/* Come here after finding the start of a frame when we expected an
long bc;
int c;
char *buf = *buf_p;
+ struct remote_state *rs = get_remote_state ();
csum = 0;
bc = 0;
return -1;
}
+ /* Don't recompute the checksum; with no ack packets we
+ don't have any way to indicate a packet retransmission
+ is necessary. */
+ if (rs->noack_mode)
+ return bc;
+
pktcsum = (fromhex (check_0) << 4) | fromhex (check_1);
if (csum == pktcsum)
return bc;
fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
fprintf_unfiltered (gdb_stdlog, "\n");
}
- serial_write (remote_desc, "+", 1);
+
+ /* Skip the ack char if we're in no-ack mode. */
+ if (!rs->noack_mode)
+ serial_write (remote_desc, "+", 1);
return val;
}
/* Try the whole thing again. */
retry:
- serial_write (remote_desc, "-", 1);
+ /* Skip the nack char if we're in no-ack mode. */
+ if (!rs->noack_mode)
+ serial_write (remote_desc, "-", 1);
}
/* We have tried hard enough, and just can't receive the packet.
Give up. */
printf_unfiltered (_("Ignoring packet error, continuing...\n"));
- serial_write (remote_desc, "+", 1);
+
+ /* Skip the ack char if we're in no-ack mode. */
+ if (!rs->noack_mode)
+ serial_write (remote_desc, "+", 1);
return -1;
}
\f
/* Assume that the target has been restarted. Set inferior_ptid
so that bits of core GDB realizes there's something here, e.g.,
so that the user can say "kill" again. */
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+ inferior_ptid = remote_current_thread (magic_null_ptid);
+ add_thread_silent (inferior_ptid);
}
else
{
/* Now mark the inferior as running before we do anything else. */
attach_flag = 0;
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+ inferior_ptid = magic_null_ptid;
+
+ add_thread_silent (inferior_ptid);
+
target_mark_running (&extended_remote_ops);
/* Get updated offsets, if the stub uses qOffsets. */
if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
{
- CORE_ADDR addr;
+ CORE_ADDR addr = bp_tgt->placed_address;
struct remote_state *rs;
char *p;
+ int bpsize;
- gdbarch_breakpoint_from_pc
- (current_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+ gdbarch_breakpoint_from_pc (target_gdbarch, &addr, &bpsize);
rs = get_remote_state ();
p = rs->buf;
*(p++) = 'Z';
*(p++) = '0';
*(p++) = ',';
- addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address);
+ addr = (ULONGEST) remote_address_masked (addr);
p += hexnumstr (p, addr);
- sprintf (p, ",%d", bp_tgt->placed_size);
+ sprintf (p, ",%d", bpsize);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
case PACKET_ERROR:
return -1;
case PACKET_OK:
+ bp_tgt->placed_address = addr;
+ bp_tgt->placed_size = bpsize;
return 0;
case PACKET_UNKNOWN:
break;
instruction, even though we aren't inserting one ourselves. */
gdbarch_breakpoint_from_pc
- (current_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+ (target_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE)
return -1;
int sample_thread = SAMPLE_THREAD;
printf_filtered (_("Remote threadset test\n"));
- set_thread (sample_thread, 1);
+ set_general_thread (sample_thread);
}
threadalive_test (char *cmd, int tty)
{
int sample_thread = SAMPLE_THREAD;
+ int pid = ptid_get_pid (inferior_ptid);
+ ptid_t ptid = ptid_build (pid, 0, sample_thread);
- if (remote_thread_alive (pid_to_ptid (sample_thread)))
+ if (remote_thread_alive (ptid))
printf_filtered ("PASS: Thread alive test\n");
else
printf_filtered ("FAIL: Thread alive test\n");
static char *
remote_pid_to_str (ptid_t ptid)
{
- static char buf[32];
+ static char buf[64];
- xsnprintf (buf, sizeof buf, "Thread %d", ptid_get_pid (ptid));
- return buf;
+ if (ptid_equal (magic_null_ptid, ptid))
+ {
+ xsnprintf (buf, sizeof buf, "Thread <main>");
+ return buf;
+ }
+ else if (ptid_get_tid (ptid) != 0)
+ {
+ xsnprintf (buf, sizeof buf, "Thread %ld",
+ ptid_get_tid (ptid));
+ return buf;
+ }
+
+ return normal_pid_to_str (ptid);
}
/* Get the address of the thread local variable in OBJFILE which is
strcpy (p, "qGetTLSAddr:");
p += strlen (p);
- p += hexnumstr (p, PIDGET (ptid));
+ p += hexnumstr (p, ptid_get_tid (ptid));
*p++ = ',';
p += hexnumstr (p, offset);
*p++ = ',';
remote_read_description (struct target_ops *target)
{
struct remote_g_packet_data *data
- = gdbarch_data (current_gdbarch, remote_g_packet_data_handle);
+ = gdbarch_data (target_gdbarch, remote_g_packet_data_handle);
if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
{
int ret, bytes_read;
char *attachment_tmp;
- if (remote_protocol_packets[which_packet].support == PACKET_DISABLE)
+ if (!remote_desc
+ || remote_protocol_packets[which_packet].support == PACKET_DISABLE)
{
*remote_errno = FILEIO_ENOSYS;
return -1;
remote_hostio_close (fd, &remote_errno);
}
+
+static void *
+remote_bfd_iovec_open (struct bfd *abfd, void *open_closure)
+{
+ const char *filename = bfd_get_filename (abfd);
+ int fd, remote_errno;
+ int *stream;
+
+ gdb_assert (remote_filename_p (filename));
+
+ fd = remote_hostio_open (filename + 7, FILEIO_O_RDONLY, 0, &remote_errno);
+ if (fd == -1)
+ {
+ errno = remote_fileio_errno_to_host (remote_errno);
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ stream = xmalloc (sizeof (int));
+ *stream = fd;
+ return stream;
+}
+
+static int
+remote_bfd_iovec_close (struct bfd *abfd, void *stream)
+{
+ int fd = *(int *)stream;
+ int remote_errno;
+
+ xfree (stream);
+
+ /* Ignore errors on close; these may happen if the remote
+ connection was already torn down. */
+ remote_hostio_close (fd, &remote_errno);
+
+ return 1;
+}
+
+static file_ptr
+remote_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
+ file_ptr nbytes, file_ptr offset)
+{
+ int fd = *(int *)stream;
+ int remote_errno;
+ file_ptr pos, bytes;
+
+ pos = 0;
+ while (nbytes > pos)
+ {
+ bytes = remote_hostio_pread (fd, (char *)buf + pos, nbytes - pos,
+ offset + pos, &remote_errno);
+ if (bytes == 0)
+ /* Success, but no bytes, means end-of-file. */
+ break;
+ if (bytes == -1)
+ {
+ errno = remote_fileio_errno_to_host (remote_errno);
+ bfd_set_error (bfd_error_system_call);
+ return -1;
+ }
+
+ pos += bytes;
+ }
+
+ return pos;
+}
+
+static int
+remote_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
+{
+ /* FIXME: We should probably implement remote_hostio_stat. */
+ sb->st_size = INT_MAX;
+ return 0;
+}
+
+int
+remote_filename_p (const char *filename)
+{
+ return strncmp (filename, "remote:", 7) == 0;
+}
+
+bfd *
+remote_bfd_open (const char *remote_file, const char *target)
+{
+ return bfd_openr_iovec (remote_file, target,
+ remote_bfd_iovec_open, NULL,
+ remote_bfd_iovec_pread,
+ remote_bfd_iovec_close,
+ remote_bfd_iovec_stat);
+}
+
void
remote_file_put (const char *local_file, const char *remote_file, int from_tty)
{
static int
remote_can_async_p (void)
{
- if (!remote_async_permitted)
+ if (!target_async_permitted)
/* We only enable async when the user specifically asks for it. */
return 0;
static int
remote_is_async_p (void)
{
- if (!remote_async_permitted)
+ if (!target_async_permitted)
/* We only enable async when the user specifically asks for it. */
return 0;
add_packet_config_cmd (&remote_protocol_packets[PACKET_vRun],
"vRun", "run", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_QStartNoAckMode],
+ "QStartNoAckMode", "noack", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
Show the remote pathname for \"run\""), NULL, NULL, NULL,
&remote_set_cmdlist, &remote_show_cmdlist);
- add_setshow_boolean_cmd ("remote-async", class_maintenance,
- &remote_async_permitted_set, _("\
-Set whether gdb controls the remote inferior in asynchronous mode."), _("\
-Show whether gdb controls the remote inferior in asynchronous mode."), _("\
-Tells gdb whether to control the remote inferior in asynchronous mode."),
- set_maintenance_remote_async_permitted,
- show_maintenance_remote_async_permitted,
- &maintenance_set_cmdlist,
- &maintenance_show_cmdlist);
-
-
/* Eventually initialize fileio. See fileio.c */
initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
+
+ /* Take advantage of the fact that the LWP field is not used, to tag
+ special ptids with it set to != 0. */
+ magic_null_ptid = ptid_build (0, 1, -1);
+ not_sent_ptid = ptid_build (0, 1, -2);
+ any_thread_ptid = ptid_build (0, 1, 0);
}