static void remote_prepare_to_store (struct regcache *regcache);
-static void remote_fetch_registers (struct regcache *regcache, int regno);
-
-static void remote_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
static void remote_open (char *name, int from_tty);
static void extended_remote_open (char *name, int from_tty);
static void remote_close (int quitting);
-static void remote_store_registers (struct regcache *regcache, int regno);
-
static void remote_mourn (struct target_ops *ops);
static void extended_remote_restart (void);
static int readchar (int timeout);
-static ptid_t remote_wait (ptid_t ptid,
- struct target_waitstatus *status);
-
-static void remote_kill (void);
+static void remote_kill (struct target_ops *ops);
static int tohex (int nib);
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 get_offsets (void);
static void skip_frame (void);
PACKET_vRun,
PACKET_QStartNoAckMode,
PACKET_vKill,
+ PACKET_qXfer_siginfo_read,
+ PACKET_qXfer_siginfo_write,
+ PACKET_qAttached,
PACKET_MAX
};
static ptid_t general_thread;
static ptid_t continue_thread;
+/* Find out if the stub attached to PID (and hence GDB should offer to
+ detach instead of killing it when bailing out). */
+
+static int
+remote_query_attached (int pid)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ if (remote_protocol_packets[PACKET_qAttached].support == PACKET_DISABLE)
+ return 0;
+
+ if (remote_multi_process_p (rs))
+ sprintf (rs->buf, "qAttached:%x", pid);
+ else
+ sprintf (rs->buf, "qAttached");
+
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+
+ switch (packet_ok (rs->buf,
+ &remote_protocol_packets[PACKET_qAttached]) == PACKET_OK)
+ {
+ case PACKET_OK:
+ if (strcmp (rs->buf, "1") == 0)
+ return 1;
+ break;
+ case PACKET_ERROR:
+ warning (_("Remote failure reply: %s"), rs->buf);
+ break;
+ case PACKET_UNKNOWN:
+ break;
+ }
+
+ return 0;
+}
+
+/* Add PID to GDB's inferior table. Since we can be connected to a
+ remote system before before knowing about any inferior, mark the
+ target with execution when we find the first inferior. If ATTACHED
+ is 1, then we had just attached to this inferior. If it is 0, then
+ we just created this inferior. If it is -1, then try querying the
+ remote stub to find out if it had attached to the inferior or
+ not. */
+
+static struct inferior *
+remote_add_inferior (int pid, int attached)
+{
+ struct remote_state *rs = get_remote_state ();
+ struct inferior *inf;
+
+ /* Check whether this process we're learning about is to be
+ considered attached, or if is to be considered to have been
+ spawned by the stub. */
+ if (attached == -1)
+ attached = remote_query_attached (pid);
+
+ inf = add_inferior (pid);
+
+ inf->attach_flag = attached;
+
+ /* This may be the first inferior we hear about. */
+ if (!target_has_execution)
+ {
+ if (rs->extended)
+ target_mark_running (&extended_remote_ops);
+ else
+ target_mark_running (&remote_ops);
+ }
+
+ return inf;
+}
+
+/* Add thread PTID to GDB's thread list. Tag it as executing/running
+ according to RUNNING. */
+
+static void
+remote_add_thread (ptid_t ptid, int running)
+{
+ add_thread (ptid);
+
+ set_executing (ptid, running);
+ set_running (ptid, running);
+}
+
+/* Come here when we learn about a thread id from the remote target.
+ It may be the first time we hear about such thread, so take the
+ opportunity to add it to GDB's thread list. In case this is the
+ first time we're noticing its corresponding inferior, add it to
+ GDB's inferior list as well. */
+
static void
-notice_new_inferiors (ptid_t currthread)
+remote_notice_new_inferior (ptid_t currthread, int running)
{
+ struct remote_state *rs = get_remote_state ();
+
/* 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. */
{
/* We're seeing an event on a thread id we knew had exited.
This has to be a new thread reusing the old id. Add it. */
- add_thread (currthread);
+ remote_add_thread (currthread, running);
return;
}
if (!in_thread_list (currthread))
{
+ struct inferior *inf = NULL;
+
if (ptid_equal (pid_to_ptid (ptid_get_pid (currthread)), inferior_ptid))
{
/* inferior_ptid has no thread member yet. This can happen
may not know about it yet. Add it before adding its child
thread, so notifications are emitted in a sensible order. */
if (!in_inferior_list (ptid_get_pid (currthread)))
- add_inferior (ptid_get_pid (currthread));
+ inf = remote_add_inferior (ptid_get_pid (currthread), -1);
/* This is really a new thread. Add it. */
- add_thread (currthread);
+ remote_add_thread (currthread, running);
+
+ /* If we found a new inferior, let the common code do whatever
+ it needs to with it (e.g., read shared libraries, insert
+ breakpoints). */
+ if (inf != NULL)
+ notice_new_inferior (currthread, running, 0);
}
}
/* We're just invalidating the local thread mirror. */
return;
- notice_new_inferiors (currthread);
+ remote_notice_new_inferior (currthread, 0);
}
static char *last_pass_packet;
system. */
static int
-remote_thread_alive (ptid_t ptid)
+remote_thread_alive (struct target_ops *ops, ptid_t ptid)
{
struct remote_state *rs = get_remote_state ();
int tid = ptid_get_tid (ptid);
*/
static void
-remote_threads_info (void)
+remote_threads_info (struct target_ops *ops)
{
struct remote_state *rs = get_remote_state ();
char *bufp;
do
{
new_thread = read_ptid (bufp, &bufp);
- if (!ptid_equal (new_thread, null_ptid)
- && (!in_thread_list (new_thread)
- || is_exited (new_thread)))
+ if (!ptid_equal (new_thread, null_ptid))
{
- /* When connected to a multi-process aware stub,
- "info threads" may show up threads of
- inferiors we didn't know about yet. Add them
- now, and before adding any of its child
- threads, so notifications are emitted in a
- sensible order. */
- if (!in_inferior_list (ptid_get_pid (new_thread)))
- add_inferior (ptid_get_pid (new_thread));
-
- add_thread (new_thread);
-
/* In non-stop mode, we assume new found threads
- are running until we proven otherwise with a
+ are running until proven otherwise with a
stop reply. In all-stop, we can only get
here if all threads are stopped. */
- set_executing (new_thread, non_stop ? 1 : 0);
- set_running (new_thread, non_stop ? 1 : 0);
+ int running = non_stop ? 1 : 0;
+
+ remote_notice_new_inferior (new_thread, running);
}
}
while (*bufp++ == ','); /* comma-separated list */
controlling. We default to adding them in the running state.
The '?' query below will then tell us about which threads are
stopped. */
- remote_threads_info ();
+ remote_threads_info (args->target);
}
else if (rs->non_stop_aware)
{
}
else
{
- if (args->extended_p)
- target_mark_running (args->target);
-
/* Save the reply for later. */
wait_status = alloca (strlen (rs->buf) + 1);
strcpy (wait_status, rs->buf);
/* Now, if we have thread information, update inferior_ptid. */
inferior_ptid = remote_current_thread (inferior_ptid);
- add_inferior (ptid_get_pid (inferior_ptid));
+ remote_add_inferior (ptid_get_pid (inferior_ptid), -1);
/* Always add the main thread. */
add_thread_silent (inferior_ptid);
PACKET_QStartNoAckMode },
{ "multiprocess", PACKET_DISABLE, remote_multi_process_feature, -1 },
{ "QNonStop", PACKET_DISABLE, remote_non_stop_feature, -1 },
+ { "qXfer:siginfo:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_siginfo_read },
+ { "qXfer:siginfo:write", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_siginfo_write },
};
static void
int pid;
char *dummy;
char *wait_status = NULL;
- struct inferior *inf;
if (!args)
error_no_arg (_("process-id to attach"));
error (_("Attaching to %s failed"),
target_pid_to_str (pid_to_ptid (pid)));
- 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);
- inf = add_inferior (pid);
- inf->attach_flag = 1;
+ remote_add_inferior (pid, 1);
if (non_stop)
/* Get list of threads. */
- remote_threads_info ();
+ remote_threads_info (target);
else
/* Add the main thread to the thread list. */
add_thread_silent (inferior_ptid);
static int last_sent_step;
static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *buf;
}
else
{
- if (query ("Interrupted while waiting for the program.\n\
-Give up (and stop debugging it)? "))
+ if (query (_("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? ")))
{
pop_target ();
deprecated_throw_reason (RETURN_QUIT);
if (status->kind != TARGET_WAITKIND_EXITED
&& status->kind != TARGET_WAITKIND_SIGNALLED)
{
- notice_new_inferiors (ptid);
-
/* Expedited registers. */
if (stop_reply->regcache)
{
remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p;
remote_watch_data_address = stop_reply->watch_data_address;
+
+ remote_notice_new_inferior (ptid, 0);
}
stop_reply_xfree (stop_reply);
STATUS just as `wait' would. */
static ptid_t
-remote_wait (ptid_t ptid, struct target_waitstatus *status)
+remote_wait (struct target_ops *ops,
+ ptid_t ptid, struct target_waitstatus *status)
{
ptid_t event_ptid;
}
static void
-remote_fetch_registers (struct regcache *regcache, int regnum)
+remote_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
of the register cache buffer. FIXME: ignores errors. */
static void
-remote_store_registers (struct regcache *regcache, int regnum)
+remote_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
FORMAT and the remaining arguments, then gets the reply. Returns
whether the packet was a success, a failure, or unknown. */
-enum packet_result
+static enum packet_result
remote_send_printf (const char *format, ...)
{
struct remote_state *rs = get_remote_state ();
\f
static void
-remote_kill (void)
+remote_kill (struct target_ops *ops)
{
/* Use catch_errors so the user can quit from gdb even when we
aren't on speaking terms with the remote system. */
}
static void
-extended_remote_kill (void)
+extended_remote_kill (struct target_ops *ops)
{
int res;
int pid = ptid_get_pid (inferior_ptid);
/* Now, if we have thread information, update inferior_ptid. */
inferior_ptid = remote_current_thread (inferior_ptid);
- add_inferior (ptid_get_pid (inferior_ptid));
+ remote_add_inferior (ptid_get_pid (inferior_ptid), 0);
add_thread_silent (inferior_ptid);
- target_mark_running (&extended_remote_ops);
-
/* Get updated offsets, if the stub uses qOffsets. */
get_offsets ();
}
[PACKET_qXfer_spu_write]);
}
+ /* Handle extra signal info using qxfer packets. */
+ if (object == TARGET_OBJECT_SIGNAL_INFO)
+ {
+ if (readbuf)
+ return remote_read_qxfer (ops, "siginfo", annex, readbuf, offset, len,
+ &remote_protocol_packets
+ [PACKET_qXfer_siginfo_read]);
+ else
+ return remote_write_qxfer (ops, "siginfo", annex, writebuf, offset, len,
+ &remote_protocol_packets
+ [PACKET_qXfer_siginfo_write]);
+ }
+
/* Only handle flash writes. */
if (writebuf != NULL)
{
buffer. */
static char *
-remote_pid_to_str (ptid_t ptid)
+remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static char buf[64];
struct remote_state *rs = get_remote_state ();
stored at OFFSET within the thread local storage for thread PTID. */
static CORE_ADDR
-remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
+remote_get_thread_local_address (struct target_ops *ops,
+ ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
{
if (remote_protocol_packets[PACKET_qGetTLSAddr].support != PACKET_DISABLE)
{
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_osdata],
"qXfer:osdata:read", "osdata", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_siginfo_read],
+ "qXfer:siginfo:read", "read-siginfo-object", 0);
+
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_siginfo_write],
+ "qXfer:siginfo:write", "write-siginfo-object", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
"qGetTLSAddr", "get-thread-local-storage-address",
0);
add_packet_config_cmd (&remote_protocol_packets[PACKET_vKill],
"vKill", "kill", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qAttached],
+ "qAttached", "query-attached", 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