/* See the GDB User Guide for details of the GDB remote protocol. */
#include "defs.h"
-#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include "inferior.h"
+#include "infrun.h"
#include "bfd.h"
#include "symfile.h"
-#include "exceptions.h"
#include "target.h"
/*#include "terminal.h" */
#include "gdbcmd.h"
#include "remote-notif.h"
#include "regcache.h"
#include "value.h"
-#include "gdb_assert.h"
#include "observer.h"
#include "solib.h"
#include "cli/cli-decode.h"
static void remote_prepare_to_store (struct target_ops *self,
struct regcache *regcache);
-static void remote_open (char *name, int from_tty);
-
-static void extended_remote_open (char *name, int from_tty);
-
-static void remote_open_1 (char *, int, struct target_ops *, int extended_p);
+static void remote_open_1 (const char *, int, struct target_ops *,
+ int extended_p);
static void remote_close (struct target_ops *self);
static CORE_ADDR remote_address_masked (CORE_ADDR);
-static void print_packet (char *);
+static void print_packet (const char *);
static void compare_sections_command (char *, int);
static ptid_t remote_current_thread (ptid_t oldptid);
-static void remote_find_new_threads (void);
-
-static int putpkt_binary (char *buf, int cnt);
+static int putpkt_binary (const char *buf, int cnt);
static void check_binary_download (CORE_ADDR addr);
/* If auto, GDB auto-detects support for this packet or feature,
either through qSupported, or by trying the packet and looking
at the response. If true, GDB assumes the target supports this
- packet. If false, the packet is disabled. */
+ packet. If false, the packet is disabled. Configs that don't
+ have an associated command always have this set to auto. */
enum auto_boolean detect;
/* Does the target support this packet? */
config->name = name;
config->title = title;
- config->detect = AUTO_BOOLEAN_AUTO;
- config->support = PACKET_SUPPORT_UNKNOWN;
set_doc = xstrprintf ("Set use of remote protocol `%s' (%s) packet",
name, title);
show_doc = xstrprintf ("Show current use of remote "
PACKET_qTStatus,
PACKET_QPassSignals,
PACKET_QProgramSignals,
+ PACKET_qCRC,
PACKET_qSearch_memory,
PACKET_vAttach,
PACKET_vRun,
}
\f
-/* Return nonzero if the thread PTID is still alive on the remote
- system. */
+/* Return nonzero if this is the main thread that we made up ourselves
+ to model non-threaded targets as single-threaded. */
static int
-remote_thread_alive (struct target_ops *ops, ptid_t ptid)
+remote_thread_always_alive (struct target_ops *ops, ptid_t ptid)
{
struct remote_state *rs = get_remote_state ();
char *p, *endp;
multi-threading. */
return 1;
+ return 0;
+}
+
+/* Return nonzero if the thread PTID is still alive on the remote
+ system. */
+
+static int
+remote_thread_alive (struct target_ops *ops, ptid_t ptid)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *p, *endp;
+
+ /* Check if this is a thread that we made up ourselves to model
+ non-threaded targets as single-threaded. */
+ if (remote_thread_always_alive (ops, ptid))
+ return 1;
+
p = rs->buf;
endp = rs->buf + get_remote_packet_size ();
return resultcount;
}
+/* Fetch the next batch of threads from the remote. Returns -1 if the
+ qL packet is not supported, 0 on error and 1 on success. */
+
static int
remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
int *done, int *result_count, threadref *threadlist)
pack_threadlist_request (rs->buf, startflag, result_limit, nextthread);
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
-
if (*rs->buf == '\0')
- return 0;
- else
- *result_count =
- parse_threadlist_response (rs->buf + 2, result_limit,
- &rs->echo_nextthread, threadlist, done);
+ {
+ /* Packet not supported. */
+ return -1;
+ }
+
+ *result_count =
+ parse_threadlist_response (rs->buf + 2, result_limit,
+ &rs->echo_nextthread, threadlist, done);
if (!threadmatch (&rs->echo_nextthread, nextthread))
{
return result;
}
-/* This is the interface between remote and threads, remotes upper
- interface. */
-
-/* remote_find_new_threads retrieves the thread list and for each
- thread in the list, looks up the thread in GDB's internal list,
- 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. */
-
+/* Fetch the list of remote threads, with the qL packet, and call
+ STEPFUNCTION for each thread found. Stops iterating and returns 1
+ if STEPFUNCTION returns true. Stops iterating and returns 0 if the
+ STEPFUNCTION returns false. If the packet is not supported,
+ returns -1. */
static int
remote_threadlist_iterator (rmt_thread_action stepfunction, void *context,
warning (_("Remote fetch threadlist -infinite loop-."));
break;
}
- if (!remote_get_threadlist (startflag, &rs->nextthread,
- MAXTHREADLISTRESULTS,
- &done, &result_count, rs->resultthreadlist))
- {
- result = 0;
- break;
- }
+ result = remote_get_threadlist (startflag, &rs->nextthread,
+ MAXTHREADLISTRESULTS,
+ &done, &result_count,
+ rs->resultthreadlist);
+ if (result <= 0)
+ break;
/* Clear for later iterations. */
startflag = 0;
/* Setup to resume next batch of thread references, set nextthread. */
&rs->resultthreadlist[result_count - 1]);
i = 0;
while (result_count--)
- if (!(result = (*stepfunction) (&rs->resultthreadlist[i++], context)))
- break;
+ {
+ if (!(*stepfunction) (&rs->resultthreadlist[i++], context))
+ {
+ result = 0;
+ break;
+ }
+ }
}
return result;
}
+/* A thread found on the remote target. */
+
+typedef struct thread_item
+{
+ /* The thread's PTID. */
+ ptid_t ptid;
+
+ /* The thread's extra info. May be NULL. */
+ char *extra;
+
+ /* The core the thread was running on. -1 if not known. */
+ int core;
+} thread_item_t;
+DEF_VEC_O(thread_item_t);
+
+/* Context passed around to the various methods listing remote
+ threads. As new threads are found, they're added to the ITEMS
+ vector. */
+
+struct threads_listing_context
+{
+ /* The threads found on the remote target. */
+ VEC (thread_item_t) *items;
+};
+
+/* Discard the contents of the constructed thread listing context. */
+
+static void
+clear_threads_listing_context (void *p)
+{
+ struct threads_listing_context *context = p;
+ int i;
+ struct thread_item *item;
+
+ for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i)
+ xfree (item->extra);
+
+ VEC_free (thread_item_t, context->items);
+}
+
static int
-remote_newthread_step (threadref *ref, void *context)
+remote_newthread_step (threadref *ref, void *data)
{
+ struct threads_listing_context *context = data;
+ struct thread_item item;
int pid = ptid_get_pid (inferior_ptid);
- ptid_t ptid = ptid_build (pid, threadref_to_int (ref), 0);
- if (!in_thread_list (ptid))
- add_thread (ptid);
+ item.ptid = ptid_build (pid, threadref_to_int (ref), 0);
+ item.core = -1;
+ item.extra = NULL;
+
+ VEC_safe_push (thread_item_t, context->items, &item);
+
return 1; /* continue iterator */
}
return oldpid;
}
-/* Find new threads for info threads command.
- * Original version, using John Metzler's thread protocol.
- */
+/* List remote threads using the deprecated qL packet. */
-static void
-remote_find_new_threads (void)
+static int
+remote_get_threads_with_ql (struct target_ops *ops,
+ struct threads_listing_context *context)
{
- remote_threadlist_iterator (remote_newthread_step, 0,
- CRAZY_MAX_THREADS);
+ if (remote_threadlist_iterator (remote_newthread_step, context,
+ CRAZY_MAX_THREADS) >= 0)
+ return 1;
+
+ return 0;
}
#if defined(HAVE_LIBEXPAT)
-typedef struct thread_item
-{
- ptid_t ptid;
- char *extra;
- int core;
-} thread_item_t;
-DEF_VEC_O(thread_item_t);
-
-struct threads_parsing_context
-{
- VEC (thread_item_t) *items;
-};
-
static void
start_thread (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
void *user_data, VEC(gdb_xml_value_s) *attributes)
{
- struct threads_parsing_context *data = user_data;
+ struct threads_listing_context *data = user_data;
struct thread_item item;
char *id;
const struct gdb_xml_element *element,
void *user_data, const char *body_text)
{
- struct threads_parsing_context *data = user_data;
+ struct threads_listing_context *data = user_data;
if (body_text && *body_text)
VEC_last (thread_item_t, data->items)->extra = xstrdup (body_text);
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
-/* Discard the contents of the constructed thread info context. */
-
-static void
-clear_threads_parsing_context (void *p)
-{
- struct threads_parsing_context *context = p;
- int i;
- struct thread_item *item;
-
- for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i)
- xfree (item->extra);
-
- VEC_free (thread_item_t, context->items);
-}
-
#endif
-/*
- * Find all threads for info threads command.
- * Uses new thread protocol contributed by Cisco.
- * Falls back and attempts to use the older method (above)
- * if the target doesn't respond to the new method.
- */
+/* List remote threads using qXfer:threads:read. */
-static void
-remote_threads_info (struct target_ops *ops)
+static int
+remote_get_threads_with_qxfer (struct target_ops *ops,
+ struct threads_listing_context *context)
{
- struct remote_state *rs = get_remote_state ();
- char *bufp;
- ptid_t new_thread;
-
- if (rs->remote_desc == 0) /* paranoia */
- error (_("Command can only be used when connected to the remote target."));
-
#if defined(HAVE_LIBEXPAT)
if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
{
- char *xml = target_read_stralloc (¤t_target,
- TARGET_OBJECT_THREADS, NULL);
-
+ char *xml = target_read_stralloc (ops, TARGET_OBJECT_THREADS, NULL);
struct cleanup *back_to = make_cleanup (xfree, xml);
- if (xml && *xml)
+ if (xml != NULL && *xml != '\0')
{
- struct threads_parsing_context context;
-
- context.items = NULL;
- make_cleanup (clear_threads_parsing_context, &context);
-
- if (gdb_xml_parse_quick (_("threads"), "threads.dtd",
- threads_elements, xml, &context) == 0)
- {
- int i;
- struct thread_item *item;
-
- for (i = 0;
- VEC_iterate (thread_item_t, context.items, i, item);
- ++i)
- {
- if (!ptid_equal (item->ptid, null_ptid))
- {
- struct private_thread_info *info;
- /* In non-stop mode, we assume new found threads
- are running until proven otherwise with a
- stop reply. In all-stop, we can only get
- here if all threads are stopped. */
- int running = non_stop ? 1 : 0;
-
- remote_notice_new_inferior (item->ptid, running);
-
- info = demand_private_info (item->ptid);
- info->core = item->core;
- info->extra = item->extra;
- item->extra = NULL;
- }
- }
- }
+ gdb_xml_parse_quick (_("threads"), "threads.dtd",
+ threads_elements, xml, context);
}
do_cleanups (back_to);
- return;
+ return 1;
}
#endif
+ return 0;
+}
+
+/* List remote threads using qfThreadInfo/qsThreadInfo. */
+
+static int
+remote_get_threads_with_qthreadinfo (struct target_ops *ops,
+ struct threads_listing_context *context)
+{
+ struct remote_state *rs = get_remote_state ();
+
if (rs->use_threadinfo_query)
{
+ char *bufp;
+
putpkt ("qfThreadInfo");
getpkt (&rs->buf, &rs->buf_size, 0);
bufp = rs->buf;
if (bufp[0] != '\0') /* q packet recognized */
{
- struct cleanup *old_chain;
- char *saved_reply;
-
- /* remote_notice_new_inferior (in the loop below) may make
- new RSP calls, which clobber rs->buf. Work with a
- copy. */
- bufp = saved_reply = xstrdup (rs->buf);
- old_chain = make_cleanup (free_current_contents, &saved_reply);
-
while (*bufp++ == 'm') /* reply contains one or more TID */
{
do
{
- new_thread = read_ptid (bufp, &bufp);
- if (!ptid_equal (new_thread, null_ptid))
- {
- /* In non-stop mode, we assume new found threads
- are running until proven otherwise with a
- stop reply. In all-stop, we can only get
- here if all threads are stopped. */
- int running = non_stop ? 1 : 0;
+ struct thread_item item;
- remote_notice_new_inferior (new_thread, running);
- }
+ item.ptid = read_ptid (bufp, &bufp);
+ item.core = -1;
+ item.extra = NULL;
+
+ VEC_safe_push (thread_item_t, context->items, &item);
}
while (*bufp++ == ','); /* comma-separated list */
- free_current_contents (&saved_reply);
putpkt ("qsThreadInfo");
getpkt (&rs->buf, &rs->buf_size, 0);
- bufp = saved_reply = xstrdup (rs->buf);
+ bufp = rs->buf;
}
+ return 1;
+ }
+ else
+ {
+ /* Packet not recognized. */
+ rs->use_threadinfo_query = 0;
+ }
+ }
+
+ return 0;
+}
+
+/* Implement the to_update_thread_list function for the remote
+ targets. */
+
+static void
+remote_update_thread_list (struct target_ops *ops)
+{
+ struct remote_state *rs = get_remote_state ();
+ struct threads_listing_context context;
+ struct cleanup *old_chain;
+ int got_list = 0;
+
+ context.items = NULL;
+ old_chain = make_cleanup (clear_threads_listing_context, &context);
+
+ /* We have a few different mechanisms to fetch the thread list. Try
+ them all, starting with the most preferred one first, falling
+ back to older methods. */
+ if (remote_get_threads_with_qxfer (ops, &context)
+ || remote_get_threads_with_qthreadinfo (ops, &context)
+ || remote_get_threads_with_ql (ops, &context))
+ {
+ int i;
+ struct thread_item *item;
+ struct thread_info *tp, *tmp;
+
+ got_list = 1;
+
+ if (VEC_empty (thread_item_t, context.items)
+ && remote_thread_always_alive (ops, inferior_ptid))
+ {
+ /* Some targets don't really support threads, but still
+ reply an (empty) thread list in response to the thread
+ listing packets, instead of replying "packet not
+ supported". Exit early so we don't delete the main
+ thread. */
do_cleanups (old_chain);
- return; /* done */
+ return;
+ }
+
+ /* CONTEXT now holds the current thread list on the remote
+ target end. Delete GDB-side threads no longer found on the
+ target. */
+ ALL_NON_EXITED_THREADS_SAFE (tp, tmp)
+ {
+ for (i = 0;
+ VEC_iterate (thread_item_t, context.items, i, item);
+ ++i)
+ {
+ if (ptid_equal (item->ptid, tp->ptid))
+ break;
+ }
+
+ if (i == VEC_length (thread_item_t, context.items))
+ {
+ /* Not found. */
+ delete_thread (tp->ptid);
+ }
+ }
+
+ /* And now add threads we don't know about yet to our list. */
+ for (i = 0;
+ VEC_iterate (thread_item_t, context.items, i, item);
+ ++i)
+ {
+ if (!ptid_equal (item->ptid, null_ptid))
+ {
+ struct private_thread_info *info;
+ /* In non-stop mode, we assume new found threads are
+ running until proven otherwise with a stop reply. In
+ all-stop, we can only get here if all threads are
+ stopped. */
+ int running = non_stop ? 1 : 0;
+
+ remote_notice_new_inferior (item->ptid, running);
+
+ info = demand_private_info (item->ptid);
+ info->core = item->core;
+ info->extra = item->extra;
+ item->extra = NULL;
+ }
}
}
- /* Only qfThreadInfo is supported in non-stop mode. */
- if (non_stop)
- return;
+ if (!got_list)
+ {
+ /* If no thread listing method is supported, then query whether
+ each known thread is alive, one by one, with the T packet.
+ If the target doesn't support threads at all, then this is a
+ no-op. See remote_thread_alive. */
+ prune_threads ();
+ }
- /* Else fall back to old method based on jmetzler protocol. */
- rs->use_threadinfo_query = 0;
- remote_find_new_threads ();
- return;
+ do_cleanups (old_chain);
}
/*
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 (target);
+ remote_update_thread_list (target);
}
else if (packet_support (PACKET_QNonStop) == PACKET_ENABLE)
{
}
/* Fetch thread list. */
- target_find_new_threads ();
+ target_update_thread_list ();
/* Let the stub know that we want it to return the thread. */
set_continue_thread (minus_one_ptid);
up. */
rs->starting_up = 0;
- /* If breakpoints are global, insert them now. */
- if (gdbarch_has_global_breakpoints (target_gdbarch ())
- && breakpoints_always_inserted_mode ())
+ /* Maybe breakpoints are global and need to be inserted now. */
+ if (breakpoints_should_be_inserted_now ())
insert_breakpoints ();
}
NAME is the filename used for communication. */
static void
-remote_open (char *name, int from_tty)
+remote_open (const char *name, int from_tty)
{
remote_open_1 (name, from_tty, &remote_ops, 0);
}
remote gdb protocol. NAME is the filename used for communication. */
static void
-extended_remote_open (char *name, int from_tty)
+extended_remote_open (const char *name, int from_tty)
{
remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */);
}
-/* Generic code for opening a connection to a remote target. */
+/* Reset all packets back to "unknown support". Called when opening a
+ new connection to a remote target. */
static void
-init_all_packet_configs (void)
+reset_all_packet_configs_support (void)
{
int i;
remote_protocol_packets[i].support = PACKET_SUPPORT_UNKNOWN;
}
+/* Initialize all packet configs. */
+
+static void
+init_all_packet_configs (void)
+{
+ int i;
+
+ for (i = 0; i < PACKET_MAX; i++)
+ {
+ remote_protocol_packets[i].detect = AUTO_BOOLEAN_AUTO;
+ remote_protocol_packets[i].support = PACKET_SUPPORT_UNKNOWN;
+ }
+}
+
/* Symbol look-up. */
static void
}
static struct serial *
-remote_serial_open (char *name)
+remote_serial_open (const char *name)
{
static int udp_warning = 0;
}
static void
-remote_open_1 (char *name, int from_tty,
+remote_open_1 (const char *name, int from_tty,
struct target_ops *target, int extended_p)
{
struct remote_state *rs = get_remote_state ();
/* Reset the target state; these things will be queried either by
remote_query_supported or as they are needed. */
- init_all_packet_configs ();
+ reset_all_packet_configs_support ();
rs->cached_wait_status = 0;
rs->explicit_packet_size = 0;
rs->noack_mode = 0;
/* Same as remote_detach, but don't send the "D" packet; just disconnect. */
static void
-remote_disconnect (struct target_ops *target, char *args, int from_tty)
+remote_disconnect (struct target_ops *target, const char *args, int from_tty)
{
if (args)
error (_("Argument given to \"disconnect\" when remotely debugging."));
be chatty about it. */
static void
-extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
+extended_remote_attach_1 (struct target_ops *target, const char *args,
+ int from_tty)
{
struct remote_state *rs = get_remote_state ();
int pid;
struct thread_info *thread;
/* Get list of threads. */
- remote_threads_info (target);
+ remote_update_thread_list (target);
thread = first_thread_of_process (pid);
if (thread)
}
static void
-extended_remote_attach (struct target_ops *ops, char *args, int from_tty)
+extended_remote_attach (struct target_ops *ops, const char *args, int from_tty)
{
extended_remote_attach_1 (ops, args, from_tty);
}
+/* Implementation of the to_post_attach method. */
+
+static void
+extended_remote_post_attach (struct target_ops *ops, int pid)
+{
+ /* In certain cases GDB might not have had the chance to start
+ symbol lookup up until now. This could happen if the debugged
+ binary is not using shared libraries, the vsyscall page is not
+ present (on Linux) and the binary itself hadn't changed since the
+ debugging process was started. */
+ if (symfile_objfile != NULL)
+ remote_check_symbols();
+}
+
\f
/* Check for the availability of vCont. This function should also check
the response. */
{
struct thread_info *thread;
- ALL_THREADS (thread)
+ ALL_NON_EXITED_THREADS (thread)
if (ptid_match (thread->ptid, ptid)
&& !ptid_equal (inferior_ptid, thread->ptid)
- && thread->suspend.stop_signal != GDB_SIGNAL_0
- && signal_pass_state (thread->suspend.stop_signal))
+ && thread->suspend.stop_signal != GDB_SIGNAL_0)
{
p = append_resumption (p, endp, thread->ptid,
0, thread->suspend.stop_signal);
async_handle_remote_sigint (int sig)
{
signal (sig, async_handle_remote_sigint_twice);
- mark_async_signal_handler (async_sigint_remote_token);
+ /* Note we need to go through gdb_call_async_signal_handler in order
+ to wake up the event loop on Windows. */
+ gdb_call_async_signal_handler (async_sigint_remote_token, 0);
}
/* Signal handler for SIGINT, installed after SIGINT has already been
async_handle_remote_sigint_twice (int sig)
{
signal (sig, async_handle_remote_sigint);
- mark_async_signal_handler (async_sigint_remote_twice_token);
+ /* See note in async_handle_remote_sigint. */
+ gdb_call_async_signal_handler (async_sigint_remote_twice_token, 0);
}
/* Perform the real interruption of the target execution, in response
gdb_byte *myaddr, ULONGEST len, ULONGEST *xfered_len)
{
if (len == 0)
- return 0;
+ return TARGET_XFER_EOF;
if (get_traceframe_number () != -1)
{
stb = mem_fileopen ();
old_chain = make_cleanup_ui_file_delete (stb);
- fputstrn_unfiltered (buf, n, 0, stb);
+ fputstrn_unfiltered (buf, n, '\\', stb);
str = ui_file_xstrdup (stb, NULL);
do_cleanups (old_chain);
return str;
string notation. */
static void
-print_packet (char *buf)
+print_packet (const char *buf)
{
puts_filtered ("\"");
fputstr_filtered (buf, '"', gdb_stdout);
}
int
-putpkt (char *buf)
+putpkt (const char *buf)
{
return putpkt_binary (buf, strlen (buf));
}
to print the sent packet as a string. */
static int
-putpkt_binary (char *buf, int cnt)
+putpkt_binary (const char *buf, int cnt)
{
struct remote_state *rs = get_remote_state ();
int i;
running. This is not a problem in non-stop mode, because in that
case, the stub is always ready to process serial input. */
if (!non_stop && target_can_async_p () && rs->waiting_for_stop_reply)
- error (_("Cannot execute this command while the target is running."));
+ {
+ error (_("Cannot execute this command while the target is running.\n"
+ "Use the \"interrupt\" command to stop the target\n"
+ "and then try again."));
+ }
/* We're sending out a new packet. Make sure we don't look at a
stale cached response. */
char **argv;
argv = gdb_buildargv (args);
- back_to = make_cleanup ((void (*) (void *)) freeargv, argv);
+ back_to = make_cleanup_freeargv (argv);
for (i = 0; argv[i] != NULL; i++)
{
if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ())
if (packet_support (PACKET_Z0) != PACKET_DISABLE)
{
- CORE_ADDR addr = bp_tgt->placed_address;
+ CORE_ADDR addr = bp_tgt->reqstd_address;
struct remote_state *rs;
char *p, *endbuf;
int bpsize;
remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
- CORE_ADDR addr;
+ CORE_ADDR addr = bp_tgt->reqstd_address;
struct remote_state *rs;
char *p, *endbuf;
char *message;
+ int bpsize;
/* The length field should be set to the size of a breakpoint
instruction, even though we aren't inserting one ourselves. */
- gdbarch_remote_breakpoint_from_pc
- (gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+ gdbarch_remote_breakpoint_from_pc (gdbarch, &addr, &bpsize);
if (packet_support (PACKET_Z1) == PACKET_DISABLE)
return -1;
*(p++) = '1';
*(p++) = ',';
- addr = remote_address_masked (bp_tgt->placed_address);
+ addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
- xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size);
+ xsnprintf (p, endbuf - p, ",%x", bpsize);
if (remote_supports_cond_breakpoints (self))
remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
case PACKET_UNKNOWN:
return -1;
case PACKET_OK:
+ bp_tgt->placed_address = addr;
+ bp_tgt->placed_size = bpsize;
return 0;
}
internal_error (__FILE__, __LINE__,
unsigned long host_crc, target_crc;
char *tmp;
- /* Make sure the remote is pointing at the right process. */
- set_general_process ();
+ /* It doesn't make sense to use qCRC if the remote target is
+ connected but not running. */
+ if (target_has_execution && packet_support (PACKET_qCRC) != PACKET_DISABLE)
+ {
+ enum packet_result result;
- /* FIXME: assumes lma can fit into long. */
- xsnprintf (rs->buf, get_remote_packet_size (), "qCRC:%lx,%lx",
- (long) lma, (long) size);
- putpkt (rs->buf);
+ /* Make sure the remote is pointing at the right process. */
+ set_general_process ();
- /* Be clever; compute the host_crc before waiting for target
- reply. */
- host_crc = xcrc32 (data, size, 0xffffffff);
+ /* FIXME: assumes lma can fit into long. */
+ xsnprintf (rs->buf, get_remote_packet_size (), "qCRC:%lx,%lx",
+ (long) lma, (long) size);
+ putpkt (rs->buf);
- getpkt (&rs->buf, &rs->buf_size, 0);
- if (rs->buf[0] == 'E')
- return -1;
+ /* Be clever; compute the host_crc before waiting for target
+ reply. */
+ host_crc = xcrc32 (data, size, 0xffffffff);
- if (rs->buf[0] != 'C')
- error (_("remote target does not support this operation"));
+ getpkt (&rs->buf, &rs->buf_size, 0);
- for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
- target_crc = target_crc * 16 + fromhex (*tmp);
+ result = packet_ok (rs->buf,
+ &remote_protocol_packets[PACKET_qCRC]);
+ if (result == PACKET_ERROR)
+ return -1;
+ else if (result == PACKET_OK)
+ {
+ for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
+ target_crc = target_crc * 16 + fromhex (*tmp);
- return (host_crc == target_crc);
+ return (host_crc == target_crc);
+ }
+ }
+
+ return simple_verify_memory (ops, data, lma, size);
}
/* compare-sections command
int matched = 0;
int mismatched = 0;
int res;
+ int read_only = 0;
if (!exec_bfd)
error (_("command cannot be used without an exec file"));
/* Make sure the remote is pointing at the right process. */
set_general_process ();
+ if (args != NULL && strcmp (args, "-r") == 0)
+ {
+ read_only = 1;
+ args = NULL;
+ }
+
for (s = exec_bfd->sections; s; s = s->next)
{
if (!(s->flags & SEC_LOAD))
continue; /* Skip non-loadable section. */
+ if (read_only && (s->flags & SEC_READONLY) == 0)
+ continue; /* Skip writeable sections */
+
size = bfd_get_section_size (s);
if (size == 0)
continue; /* Skip zero-length section. */
do_cleanups (old_chain);
}
if (mismatched > 0)
- warning (_("One or more sections of the remote executable does not match\n\
+ warning (_("One or more sections of the target image does not match\n\
the loaded file\n"));
if (args && !matched)
printf_filtered (_("No loaded section named '%s'.\n"), args);
return TARGET_XFER_E_IO;
}
- /* Note: a zero OFFSET and LEN can be used to query the minimum
- buffer size. */
- if (offset == 0 && len == 0)
- return (get_remote_packet_size ());
/* Minimum outbuf size is get_remote_packet_size (). If LEN is not
large enough let the caller deal with it. */
if (len < get_remote_packet_size ())
}
static void
-remote_rcmd (struct target_ops *self, char *command,
+remote_rcmd (struct target_ops *self, const char *command,
struct ui_file *outbuf)
{
struct remote_state *rs = get_remote_state ();
error (_("\"monitor\" command ``%s'' is too long."), command);
/* Encode the actual command. */
- bin2hex ((gdb_byte *) command, p, strlen (command));
+ bin2hex ((const gdb_byte *) command, p, strlen (command));
if (putpkt (rs->buf) < 0)
error (_("Communication problem with target."));
static void
remote_command (char *args, int from_tty)
{
- help_list (remote_cmdlist, "remote ", -1, gdb_stdout);
+ help_list (remote_cmdlist, "remote ", all_commands, gdb_stdout);
}
static int
/* Implementation of to_load. */
static void
-remote_load (struct target_ops *self, char *name, int from_tty)
+remote_load (struct target_ops *self, const char *name, int from_tty)
{
generic_load (name, from_tty);
}
remote_ops.to_pass_signals = remote_pass_signals;
remote_ops.to_program_signals = remote_program_signals;
remote_ops.to_thread_alive = remote_thread_alive;
- remote_ops.to_find_new_threads = remote_threads_info;
+ remote_ops.to_update_thread_list = remote_update_thread_list;
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_extra_thread_info = remote_threads_extra_info;
remote_ops.to_get_ada_task_ptid = remote_get_ada_task_ptid;
extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
extended_remote_ops.to_detach = extended_remote_detach;
extended_remote_ops.to_attach = extended_remote_attach;
+ extended_remote_ops.to_post_attach = extended_remote_post_attach;
extended_remote_ops.to_kill = extended_remote_kill;
extended_remote_ops.to_supports_disable_randomization
= extended_remote_supports_disable_randomization;
static void
set_remote_cmd (char *args, int from_tty)
{
- help_list (remote_set_cmdlist, "set remote ", -1, gdb_stdout);
+ help_list (remote_set_cmdlist, "set remote ", all_commands, gdb_stdout);
}
static void
add_cmd ("compare-sections", class_obscure, compare_sections_command, _("\
Compare section data on target to the exec file.\n\
-Argument is a single section name (default: all loaded sections)."),
+Argument is a single section name (default: all loaded sections).\n\
+To compare only read-only loaded sections, specify the -r option."),
&cmdlist);
add_cmd ("packet", class_maintenance, packet_command, _("\
NULL, /* FIXME: i18n: */
&setlist, &showlist);
+ init_all_packet_configs ();
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_X],
"X", "binary-download", 1);
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
"qXfer:btrace", "read-btrace", 0);
+ /* Assert that we've registered commands for all packet configs. */
+ {
+ int i;
+
+ for (i = 0; i < PACKET_MAX; i++)
+ {
+ /* Ideally all configs would have a command associated. Some
+ still don't though. */
+ int excepted;
+
+ switch (i)
+ {
+ case PACKET_QNonStop:
+ case PACKET_multiprocess_feature:
+ case PACKET_EnableDisableTracepoints_feature:
+ case PACKET_tracenz_feature:
+ case PACKET_DisconnectedTracing_feature:
+ case PACKET_augmented_libraries_svr4_read_feature:
+ case PACKET_qCRC:
+ /* Additions to this list need to be well justified:
+ pre-existing packets are OK; new packets are not. */
+ excepted = 1;
+ break;
+ default:
+ excepted = 0;
+ break;
+ }
+
+ /* This catches both forgetting to add a config command, and
+ forgetting to remove a packet from the exception list. */
+ gdb_assert (excepted == (remote_protocol_packets[i].name == NULL));
+ }
+ }
+
/* 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