static void print_packet (char *);
-static unsigned long crc32 (unsigned char *, int, unsigned int);
-
static void compare_sections_command (char *, int);
static void packet_command (char *, int);
static int remote_read_description_p (struct target_ops *target);
+static void remote_console_output (char *msg);
+
/* The non-stop remote protocol provisions for one pending stop reply.
This is where we keep it until it is acknowledged. */
do /* Loop on reply from remote stub. */
{
char *buf;
+
QUIT; /* allow user to bail out with ^C */
getpkt (buf_p, sizeof_buf, 0);
buf = *buf_p;
- if (buf[0] == 0)
- error (_("Target does not support this command."));
- else if (buf[0] == 'E')
+ if (buf[0] == 'E')
trace_error (buf);
- else if (buf[0] == 'O' &&
- buf[1] != 'K')
+ else if (strncmp (buf, "qRelocInsn:", strlen ("qRelocInsn:")) == 0)
+ {
+ ULONGEST ul;
+ CORE_ADDR from, to, org_to;
+ char *p, *pp;
+ int adjusted_size = 0;
+ volatile struct gdb_exception ex;
+
+ p = buf + strlen ("qRelocInsn:");
+ pp = unpack_varlen_hex (p, &ul);
+ if (*pp != ';')
+ error (_("invalid qRelocInsn packet: %s\n"), buf);
+ from = ul;
+
+ p = pp + 1;
+ pp = unpack_varlen_hex (p, &ul);
+ to = ul;
+
+ org_to = to;
+
+ TRY_CATCH (ex, RETURN_MASK_ALL)
+ {
+ gdbarch_relocate_instruction (target_gdbarch, &to, from);
+ }
+ if (ex.reason >= 0)
+ {
+ adjusted_size = to - org_to;
+
+ sprintf (buf, "qRelocInsn:%x", adjusted_size);
+ putpkt (buf);
+ }
+ else if (ex.reason < 0 && ex.error == MEMORY_ERROR)
+ {
+ /* Propagate memory errors silently back to the target.
+ The stub may have limited the range of addresses we
+ can write to, for example. */
+ putpkt ("E01");
+ }
+ else
+ {
+ /* Something unexpectedly bad happened. Be verbose so
+ we can tell what, and propagate the error back to the
+ stub, so it doesn't get stuck waiting for a
+ response. */
+ exception_fprintf (gdb_stderr, ex,
+ _("warning: relocating instruction: "));
+ putpkt ("E01");
+ }
+ }
+ else if (buf[0] == 'O' && buf[1] != 'K')
remote_console_output (buf + 1); /* 'O' message from stub */
else
return buf; /* here's the actual reply */
else
{
struct packet_reg *r = &rsa->regs[regnum];
+
gdb_assert (r->regnum == regnum);
return r;
}
packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
{
int i;
+
for (i = 0; i < gdbarch_num_regs (target_gdbarch); i++)
{
struct packet_reg *r = &rsa->regs[i];
+
if (r->pnum == pnum)
return r;
}
{
int fixed_p = config->fixed_p;
long size = config->size;
+
if (args == NULL)
error (_("Argument required (integer, `fixed' or `limited')."));
else if (strcmp (args, "hard") == 0
else
{
char *end;
+
size = strtoul (args, &end, 0);
if (args == end)
error (_("Invalid %s (bad syntax)."), config->name);
get_memory_read_packet_size (void)
{
long size = get_memory_packet_size (&memory_read_packet_config);
+
/* FIXME: cagney/1999-11-07: Functions like getpkt() need to get an
extra buffer size argument before the memory read size can be
increased beyond this. */
show_packet_config_cmd (struct packet_config *config)
{
char *support = "internal-error";
+
switch (config->support)
{
case PACKET_ENABLE:
if (legacy)
{
char *legacy_name;
+
legacy_name = xstrprintf ("%s-packet", name);
add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
&remote_set_cmdlist);
PACKET_qXfer_spu_write,
PACKET_qXfer_osdata,
PACKET_qXfer_threads,
+ PACKET_qGetTIBAddr,
PACKET_qGetTLSAddr,
PACKET_qSupported,
PACKET_QPassSignals,
PACKET_FastTracepoints,
PACKET_bc,
PACKET_bs,
+ PACKET_TracepointSource,
PACKET_MAX
};
struct cmd_list_element *c)
{
int i;
+
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
{
remote_protocol_packets[PACKET_Z0 + i].detect = remote_Z_packet_detect;
const char *value)
{
int i;
+
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
{
show_packet_config_cmd (&remote_protocol_packets[PACKET_Z0 + i]);
}
}
+static void
+remote_notice_signals (ptid_t ptid)
+{
+ /* Update the remote on signals to silently pass, if they've
+ changed. */
+ remote_pass_signals ();
+}
+
/* 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
struct threads_parsing_context *data = user_data;
if (body_text && *body_text)
- VEC_last (thread_item_t, data->items)->extra = strdup (body_text);
+ VEC_last (thread_item_t, data->items)->extra = xstrdup (body_text);
}
const struct gdb_xml_attribute thread_attributes[] = {
{ 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
/*
{
struct gdb_xml_parser *parser;
struct threads_parsing_context context;
- struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+ struct cleanup *clear_parsing_context;
context.items = 0;
+ /* Note: this parser cleanup is already guarded by BACK_TO
+ above. */
parser = gdb_xml_create_parser_and_cleanup (_("threads"),
threads_elements,
&context);
gdb_xml_use_dtd (parser, "threads.dtd");
+ clear_parsing_context
+ = make_cleanup (clear_threads_parsing_context, &context);
+
if (gdb_xml_parse (parser, xml) == 0)
{
int i;
info = demand_private_info (item->ptid);
info->core = item->core;
info->extra = item->extra;
- item->extra = 0;
+ item->extra = NULL;
}
- xfree (item->extra);
}
}
- VEC_free (thread_item_t, context.items);
+ do_cleanups (clear_parsing_context);
}
do_cleanups (back_to);
if (remote_protocol_packets[PACKET_qXfer_threads].support == PACKET_ENABLE)
{
struct thread_info *info = find_thread_ptid (tp->ptid);
+
if (info && info->private)
return info->private->extra;
else
/* In non-stop mode, any cached wait status will be stored in
the stop reply queue. */
gdb_assert (wait_status == NULL);
+
+ /* Update the remote on signals to silently pass, or more
+ importantly, which to not ignore, in case a previous session
+ had set some different set of signals to be ignored. */
+ remote_pass_signals ();
}
/* If we connected to a live target, do some additional setup. */
/* Possibly the target has been engaged in a trace run started
previously; find out where things are at. */
- if (rs->disconnected_tracing)
+ if (remote_get_trace_status (current_trace_status ()) != -1)
{
struct uploaded_tp *uploaded_tps = NULL;
struct uploaded_tsv *uploaded_tsvs = NULL;
- remote_get_trace_status (current_trace_status ());
if (current_trace_status ()->running)
printf_filtered (_("Trace is already running on the target.\n"));
init_all_packet_configs (void)
{
int i;
+
for (i = 0; i < PACKET_MAX; i++)
update_packet_config (&remote_protocol_packets[i]);
}
enum packet_support support, const char *value)
{
struct remote_state *rs = get_remote_state ();
+
rs->multi_process_aware = (support == PACKET_ENABLE);
}
enum packet_support support, const char *value)
{
struct remote_state *rs = get_remote_state ();
+
rs->non_stop_aware = (support == PACKET_ENABLE);
}
const char *value)
{
struct remote_state *rs = get_remote_state ();
+
rs->cond_tracepoints = (support == PACKET_ENABLE);
}
const char *value)
{
struct remote_state *rs = get_remote_state ();
+
rs->fast_tracepoints = (support == PACKET_ENABLE);
}
const char *value)
{
struct remote_state *rs = get_remote_state ();
+
rs->disconnected_tracing = (support == PACKET_ENABLE);
}
PACKET_bc },
{ "ReverseStep", PACKET_DISABLE, remote_supported_packet,
PACKET_bs },
+ { "TracepointSource", PACKET_DISABLE, remote_supported_packet,
+ PACKET_TracepointSource },
};
+static char *remote_support_xml;
+
+/* Register string appended to "xmlRegisters=" in qSupported query. */
+
+void
+register_remote_support_xml (const char *xml)
+{
+#if defined(HAVE_LIBEXPAT)
+ if (remote_support_xml == NULL)
+ remote_support_xml = concat ("xmlRegisters=", xml, (char *) NULL);
+ else
+ {
+ char *copy = xstrdup (remote_support_xml + 13);
+ char *p = strtok (copy, ",");
+
+ do
+ {
+ if (strcmp (p, xml) == 0)
+ {
+ /* already there */
+ xfree (copy);
+ return;
+ }
+ }
+ while ((p = strtok (NULL, ",")) != NULL);
+ xfree (copy);
+
+ remote_support_xml = reconcat (remote_support_xml,
+ remote_support_xml, ",", xml,
+ (char *) NULL);
+ }
+#endif
+}
+
+static char *
+remote_query_supported_append (char *msg, const char *append)
+{
+ if (msg)
+ return reconcat (msg, msg, ";", append, (char *) NULL);
+ else
+ return xstrdup (append);
+}
+
static void
remote_query_supported (void)
{
rs->buf[0] = 0;
if (remote_protocol_packets[PACKET_qSupported].support != PACKET_DISABLE)
{
- const char *qsupported = gdbarch_qsupported (target_gdbarch);
- if (qsupported)
- {
- char *q;
- if (rs->extended)
- q = concat ("qSupported:multiprocess+;", qsupported, NULL);
- else
- q = concat ("qSupported:", qsupported, NULL);
- putpkt (q);
- xfree (q);
- }
- else
- {
- if (rs->extended)
- putpkt ("qSupported:multiprocess+");
- else
- putpkt ("qSupported");
- }
+ char *q = NULL;
+ struct cleanup *old_chain = make_cleanup (free_current_contents, &q);
+
+ if (rs->extended)
+ q = remote_query_supported_append (q, "multiprocess+");
+
+ if (remote_support_xml)
+ q = remote_query_supported_append (q, remote_support_xml);
+
+ q = remote_query_supported_append (q, "qRelocInsn+");
+
+ q = reconcat (q, "qSupported:", q, (char *) NULL);
+ putpkt (q);
+
+ do_cleanups (old_chain);
getpkt (&rs->buf, &rs->buf_size, 0);
bin2hex (const gdb_byte *bin, char *hex, int count)
{
int i;
+
/* May use a length, or a nul-terminated string as input. */
if (count == 0)
count = strlen ((char *) bin);
remote_async_terminal_ours_p = 1;
}
-void
+static void
remote_console_output (char *msg)
{
char *p;
{
char tb[2];
char c = fromhex (p[0]) * 16 + fromhex (p[1]);
+
tb[0] = c;
tb[1] = 0;
fputs_unfiltered (tb, gdb_stdtarg);
stop_reply_xmalloc (void)
{
struct stop_reply *r = XMALLOC (struct stop_reply);
+
r->next = NULL;
return r;
}
do_stop_reply_xfree (void *arg)
{
struct stop_reply *r = arg;
+
stop_reply_xfree (r);
}
else if (strncmp (p, "core", p1 - p) == 0)
{
ULONGEST c;
+
p = unpack_varlen_hex (++p1, &c);
event->core = c;
}
if (reg == NULL)
error (_("Remote sent bad register number %s: %s\n\
Packet: '%s'\n"),
- phex_nz (pnum, 0), p, buf);
+ hex_string (pnum), p, buf);
cached_reg.num = reg->regnum;
"process:", sizeof ("process:") - 1) == 0)
{
ULONGEST upid;
+
p += sizeof ("process:") - 1;
unpack_varlen_hex (p, &upid);
pid = upid;
struct target_waitstatus *status)
{
ptid_t ptid;
- struct thread_info *info;
*status = stop_reply->ws;
ptid = stop_reply->ptid;
p += 2;
}
- {
- int i;
- for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
- {
- struct packet_reg *r = &rsa->regs[i];
- if (r->in_g_packet)
- {
- if (r->offset * 2 >= strlen (rs->buf))
- /* This shouldn't happen - we adjusted in_g_packet above. */
- internal_error (__FILE__, __LINE__,
- "unexpected end of 'g' packet reply");
- else if (rs->buf[r->offset * 2] == 'x')
- {
- gdb_assert (r->offset * 2 < strlen (rs->buf));
- /* The register isn't available, mark it as such (at
- the same time setting the value to zero). */
- regcache_raw_supply (regcache, r->regnum, NULL);
- }
- else
- regcache_raw_supply (regcache, r->regnum,
- regs + r->offset);
- }
- }
- }
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
+ {
+ struct packet_reg *r = &rsa->regs[i];
+
+ if (r->in_g_packet)
+ {
+ if (r->offset * 2 >= strlen (rs->buf))
+ /* This shouldn't happen - we adjusted in_g_packet above. */
+ internal_error (__FILE__, __LINE__,
+ "unexpected end of 'g' packet reply");
+ else if (rs->buf[r->offset * 2] == 'x')
+ {
+ gdb_assert (r->offset * 2 < strlen (rs->buf));
+ /* The register isn't available, mark it as such (at
+ the same time setting the value to zero). */
+ regcache_raw_supply (regcache, r->regnum, NULL);
+ }
+ else
+ regcache_raw_supply (regcache, r->regnum,
+ regs + r->offset);
+ }
+ }
}
static void
if (regnum >= 0)
{
struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum);
+
gdb_assert (reg != NULL);
/* If this register might be in the 'g' packet, try that first -
local buffer. */
{
int i;
+
regs = alloca (rsa->sizeof_g_packet);
memset (regs, 0, rsa->sizeof_g_packet);
for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
{
struct packet_reg *r = &rsa->regs[i];
+
if (r->in_g_packet)
regcache_raw_collect (regcache, r->regnum, regs + r->offset);
}
if (regnum >= 0)
{
struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum);
+
gdb_assert (reg != NULL);
/* Always prefer to store registers using the 'P' packet if
hexnumstr (char *buf, ULONGEST num)
{
int len = hexnumlen (num);
+
return hexnumnstr (buf, num, len);
}
remote_address_masked (CORE_ADDR addr)
{
int address_size = remote_address_size;
+
/* If "remoteaddresssize" was not set, default to target address size. */
if (!address_size)
address_size = gdbarch_addr_bit (target_gdbarch);
/* Only create a mask when that mask can safely be constructed
in a ULONGEST variable. */
ULONGEST mask = 1;
+
mask = (mask << address_size) - 1;
addr &= mask;
}
{
struct cleanup *old_chain;
struct stop_reply *reply = stop_reply_xmalloc ();
+
old_chain = make_cleanup (do_stop_reply_xfree, reply);
remote_parse_stop_reply (buf + 5, reply);
{
struct remote_state *rs = get_remote_state ();
int max_size = get_remote_packet_size ();
-
va_list ap;
+
va_start (ap, format);
rs->buf[0] = '\0';
restore_remote_timeout (void *p)
{
int value = *(int *)p;
+
remote_timeout = value;
}
int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
int saved_remote_timeout = remote_timeout;
enum packet_result ret;
-
struct cleanup *back_to = make_cleanup (restore_remote_timeout,
&saved_remote_timeout);
+
remote_timeout = remote_flash_timeout;
ret = remote_send_printf ("vFlashErase:%s,%s",
case '*': /* Run length encoding. */
{
int repeat;
- csum += c;
+ csum += c;
c = readchar (remote_timeout);
csum += c;
repeat = c - ' ' + 3; /* Compute repeat count. */
remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
{
int rc = 0;
+
if (remote_stopped_by_watchpoint ())
{
*addr_p = remote_watch_data_address;
{0, 0};
static unsigned long
-crc32 (unsigned char *buf, int len, unsigned int crc)
+crc32 (const unsigned char *buf, int len, unsigned int crc)
{
if (!crc32_table[1])
{
return crc;
}
+/* Verify memory using the "qCRC:" request. */
+
+static int
+remote_verify_memory (struct target_ops *ops,
+ const gdb_byte *data, CORE_ADDR lma, ULONGEST size)
+{
+ struct remote_state *rs = get_remote_state ();
+ unsigned long host_crc, target_crc;
+ char *tmp;
+
+ /* FIXME: assumes lma can fit into long. */
+ xsnprintf (rs->buf, get_remote_packet_size (), "qCRC:%lx,%lx",
+ (long) lma, (long) size);
+ putpkt (rs->buf);
+
+ /* Be clever; compute the host_crc before waiting for target
+ reply. */
+ host_crc = crc32 (data, size, 0xffffffff);
+
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ if (rs->buf[0] == 'E')
+ return -1;
+
+ if (rs->buf[0] != 'C')
+ error (_("remote target does not support this operation"));
+
+ for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
+ target_crc = target_crc * 16 + fromhex (*tmp);
+
+ return (host_crc == target_crc);
+}
+
/* compare-sections command
With no arguments, compares each loadable section in the exec bfd
with the same memory range on the target, and reports mismatches.
- Useful for verifying the image on the target against the exec file.
- Depends on the target understanding the new "qCRC:" request. */
-
-/* FIXME: cagney/1999-10-26: This command should be broken down into a
- target method (target verify memory) and generic version of the
- actual command. This will allow other high-level code (especially
- generic_load()) to make use of this target functionality. */
+ Useful for verifying the image on the target against the exec file. */
static void
compare_sections_command (char *args, int from_tty)
{
- struct remote_state *rs = get_remote_state ();
asection *s;
- unsigned long host_crc, target_crc;
struct cleanup *old_chain;
- char *tmp;
char *sectdata;
const char *sectname;
bfd_size_type size;
bfd_vma lma;
int matched = 0;
int mismatched = 0;
+ int res;
if (!exec_bfd)
error (_("command cannot be used without an exec file"));
- if (!current_target.to_shortname ||
- strcmp (current_target.to_shortname, "remote") != 0)
- error (_("command can only be used with remote target"));
for (s = exec_bfd->sections; s; s = s->next)
{
matched = 1; /* do this section */
lma = s->lma;
- /* FIXME: assumes lma can fit into long. */
- xsnprintf (rs->buf, get_remote_packet_size (), "qCRC:%lx,%lx",
- (long) lma, (long) size);
- putpkt (rs->buf);
- /* Be clever; compute the host_crc before waiting for target
- reply. */
sectdata = xmalloc (size);
old_chain = make_cleanup (xfree, sectdata);
bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
- host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
- getpkt (&rs->buf, &rs->buf_size, 0);
- if (rs->buf[0] == 'E')
+ res = target_verify_memory (sectdata, lma, size);
+
+ if (res == -1)
error (_("target memory fault, section %s, range %s -- %s"), sectname,
paddress (target_gdbarch, lma),
paddress (target_gdbarch, lma + size));
- if (rs->buf[0] != 'C')
- error (_("remote target does not support this operation"));
-
- for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
- target_crc = target_crc * 16 + fromhex (*tmp);
printf_filtered ("Section %s, range %s -- %s: ", sectname,
paddress (target_gdbarch, lma),
paddress (target_gdbarch, lma + size));
- if (host_crc == target_crc)
+ if (res)
printf_filtered ("matched.\n");
else
{
if (object == TARGET_OBJECT_MEMORY)
{
int xfered;
+
errno = 0;
/* If the remote target is connected but not running, we should
for (p = buf; p[0] != '\0' && p[1] != '\0'; p += 2)
{
char c = (fromhex (p[0]) << 4) + fromhex (p[1]);
+
fputc_unfiltered (c, outbuf);
}
break;
if (text)
{
struct cleanup *back_to = make_cleanup (xfree, text);
+
result = parse_memory_map (text);
do_cleanups (back_to);
}
return 0;
}
+/* Provide thread local base, i.e. Thread Information Block address.
+ Returns 1 if ptid is found and thread_local_base is non zero. */
+
+int
+remote_get_tib_address (ptid_t ptid, CORE_ADDR *addr)
+{
+ if (remote_protocol_packets[PACKET_qGetTIBAddr].support != PACKET_DISABLE)
+ {
+ struct remote_state *rs = get_remote_state ();
+ char *p = rs->buf;
+ char *endp = rs->buf + get_remote_packet_size ();
+ enum packet_result result;
+
+ strcpy (p, "qGetTIBAddr:");
+ p += strlen (p);
+ p = write_ptid (p, endp, ptid);
+ *p++ = '\0';
+
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ result = packet_ok (rs->buf,
+ &remote_protocol_packets[PACKET_qGetTIBAddr]);
+ if (result == PACKET_OK)
+ {
+ ULONGEST result;
+
+ unpack_varlen_hex (rs->buf, &result);
+ if (addr)
+ *addr = (CORE_ADDR) result;
+ return 1;
+ }
+ else if (result == PACKET_UNKNOWN)
+ error (_("Remote target doesn't support qGetTIBAddr packet"));
+ else
+ error (_("Remote target failed to process qGetTIBAddr request"));
+ }
+ else
+ error (_("qGetTIBAddr not supported or disabled on this target"));
+ /* Not reached. */
+ return 0;
+}
+
/* Support for inferring a target description based on the current
architecture and the size of a 'g' packet. While the 'g' packet
can have any size (since optional registers can be left off the
remote_supports_multi_process (void)
{
struct remote_state *rs = get_remote_state ();
+
return remote_multi_process_p (rs);
}
remote_supports_cond_tracepoints (void)
{
struct remote_state *rs = get_remote_state ();
+
return rs->cond_tracepoints;
}
remote_supports_fast_tracepoints (void)
{
struct remote_state *rs = get_remote_state ();
+
return rs->fast_tracepoints;
}
static void
-remote_trace_init ()
+remote_trace_init (void)
{
putpkt ("QTinit");
remote_get_noisy_reply (&target_buf, &target_buf_size);
- if (strcmp (target_buf, "OK"))
+ if (strcmp (target_buf, "OK") != 0)
error (_("Target does not support this command."));
}
xfree (actions_list);
}
+/* Recursive routine to walk through command list including loops, and
+ download packets for each command. */
+
+static void
+remote_download_command_source (int num, ULONGEST addr,
+ struct command_line *cmds)
+{
+ struct remote_state *rs = get_remote_state ();
+ struct command_line *cmd;
+
+ for (cmd = cmds; cmd; cmd = cmd->next)
+ {
+ QUIT; /* allow user to bail out with ^C */
+ strcpy (rs->buf, "QTDPsrc:");
+ encode_source_string (num, addr, "cmd", cmd->line,
+ rs->buf + strlen (rs->buf),
+ rs->buf_size - strlen (rs->buf));
+ putpkt (rs->buf);
+ remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ warning (_("Target does not support source download."));
+
+ if (cmd->control_type == while_control
+ || cmd->control_type == while_stepping_control)
+ {
+ remote_download_command_source (num, addr, *cmd->body_list);
+
+ QUIT; /* allow user to bail out with ^C */
+ strcpy (rs->buf, "QTDPsrc:");
+ encode_source_string (num, addr, "cmd", "end",
+ rs->buf + strlen (rs->buf),
+ rs->buf_size - strlen (rs->buf));
+ putpkt (rs->buf);
+ remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ warning (_("Target does not support source download."));
+ }
+ }
+}
+
static void
remote_download_tracepoint (struct breakpoint *t)
{
struct bp_location *loc;
CORE_ADDR tpaddr;
- char tmp[40];
+ char addrbuf[40];
char buf[2048];
char **tdp_actions;
char **stepping_actions;
(void) make_cleanup (free_actions_list_cleanup_wrapper, stepping_actions);
tpaddr = loc->address;
- sprintf_vma (tmp, (loc ? tpaddr : 0));
+ sprintf_vma (addrbuf, tpaddr);
sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
- tmp, /* address */
+ addrbuf, /* address */
(t->enable_state == bp_enabled ? 'E' : 'D'),
t->step_count, t->pass_count);
/* Fast tracepoints are mostly handled by the target, but we can
warning (_("Target does not support conditional tracepoints, ignoring tp %d cond"), t->number);
}
- if (t->actions || *default_collect)
+ if (t->commands || *default_collect)
strcat (buf, "-");
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support tracepoints."));
- if (!t->actions && !*default_collect)
- continue;
-
/* do_single_steps (t); */
if (tdp_actions)
{
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%c",
- t->number, tmp, /* address */
+ t->number, addrbuf, /* address */
tdp_actions[ndx],
((tdp_actions[ndx + 1] || stepping_actions)
? '-' : 0));
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%s%s",
- t->number, tmp, /* address */
+ t->number, addrbuf, /* address */
((ndx == 0) ? "S" : ""),
stepping_actions[ndx],
(stepping_actions[ndx + 1] ? "-" : ""));
error (_("Error on target while setting tracepoints."));
}
}
+
+ if (remote_protocol_packets[PACKET_TracepointSource].support == PACKET_ENABLE)
+ {
+ if (t->addr_string)
+ {
+ strcpy (buf, "QTDPsrc:");
+ encode_source_string (t->number, loc->address,
+ "at", t->addr_string, buf + strlen (buf),
+ 2048 - strlen (buf));
+
+ putpkt (buf);
+ remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ warning (_("Target does not support source download."));
+ }
+ if (t->cond_string)
+ {
+ strcpy (buf, "QTDPsrc:");
+ encode_source_string (t->number, loc->address,
+ "cond", t->cond_string, buf + strlen (buf),
+ 2048 - strlen (buf));
+ putpkt (buf);
+ remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ warning (_("Target does not support source download."));
+ }
+ remote_download_command_source (t->number, loc->address,
+ breakpoint_commands (t));
+ }
+
do_cleanups (old_chain);
}
}
*p++ = '\0';
putpkt (rs->buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (*target_buf == '\0')
+ error (_("Target does not support this command."));
+ if (strcmp (target_buf, "OK") != 0)
+ error (_("Error on target while downloading trace state variable."));
}
static void
-remote_trace_set_readonly_regions ()
+remote_trace_set_readonly_regions (void)
{
asection *s;
bfd_size_type size;
}
static void
-remote_trace_start ()
+remote_trace_start (void)
{
putpkt ("QTStart");
remote_get_noisy_reply (&target_buf, &target_buf_size);
- if (strcmp (target_buf, "OK"))
+ if (*target_buf == '\0')
+ error (_("Target does not support this command."));
+ if (strcmp (target_buf, "OK") != 0)
error (_("Bogus reply from target: %s"), target_buf);
}
static int
remote_get_trace_status (struct trace_status *ts)
{
- char *p, *p1, *p_temp;
- ULONGEST val;
+ char *p;
/* FIXME we need to get register block size some other way */
extern int trace_regblock_size;
+
trace_regblock_size = get_remote_arch_state ()->sizeof_g_packet;
putpkt ("qTStatus");
- getpkt (&target_buf, &target_buf_size, 0);
- /* FIXME should handle more variety of replies */
-
- p = target_buf;
+ p = remote_get_noisy_reply (&target_buf, &target_buf_size);
/* If the remote target doesn't do tracing, flag it. */
if (*p == '\0')
}
static void
-remote_trace_stop ()
+remote_trace_stop (void)
{
putpkt ("QTStop");
remote_get_noisy_reply (&target_buf, &target_buf_size);
- if (strcmp (target_buf, "OK"))
+ if (*target_buf == '\0')
+ error (_("Target does not support this command."));
+ if (strcmp (target_buf, "OK") != 0)
error (_("Bogus reply from target: %s"), target_buf);
}
putpkt (rs->buf);
reply = remote_get_noisy_reply (&(rs->buf), &sizeof_pkt);
+ if (*reply == '\0')
+ error (_("Target does not support this command."));
while (reply && *reply)
switch (*reply)
{
case 'F':
- if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
- error (_("Target failed to find requested trace frame."));
+ p = ++reply;
+ target_frameno = (int) strtol (p, &reply, 16);
+ if (reply == p)
+ error (_("Unable to parse trace frame number"));
+ if (target_frameno == -1)
+ return -1;
break;
case 'T':
- if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
- error (_("Target failed to find requested trace frame."));
+ p = ++reply;
+ target_tracept = (int) strtol (p, &reply, 16);
+ if (reply == p)
+ error (_("Unable to parse tracepoint number"));
break;
case 'O': /* "OK"? */
if (reply[1] == 'K' && reply[2] == '\0')
}
static int
-remote_save_trace_data (char *filename)
+remote_save_trace_data (const char *filename)
{
struct remote_state *rs = get_remote_state ();
char *p, *reply;
p += 2 * bin2hex ((gdb_byte *) filename, p, 0);
*p++ = '\0';
putpkt (rs->buf);
- remote_get_noisy_reply (&target_buf, &target_buf_size);
+ reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (*reply != '\0')
+ error (_("Target does not support this command."));
+ if (strcmp (reply, "OK") != 0)
+ error (_("Bogus reply from target: %s"), reply);
return 0;
}
{
struct remote_state *rs = get_remote_state ();
- sprintf (rs->buf, "QTDisconnected:%x", val);
- putpkt (rs->buf);
- remote_get_noisy_reply (&target_buf, &target_buf_size);
- if (strcmp (target_buf, "OK"))
- error (_("Target does not support this command."));
+ if (rs->disconnected_tracing)
+ {
+ char *reply;
+
+ sprintf (rs->buf, "QTDisconnected:%x", val);
+ putpkt (rs->buf);
+ reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (*reply == '\0')
+ error (_("Target does not support this command."));
+ if (strcmp (reply, "OK") != 0)
+ error (_("Bogus reply from target: %s"), reply);
+ }
+ else if (val)
+ warning (_("Target does not support disconnected tracing."));
}
static int
remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
{
struct thread_info *info = find_thread_ptid (ptid);
+
if (info && info->private)
return info->private->core;
return -1;
remote_set_circular_trace_buffer (int val)
{
struct remote_state *rs = get_remote_state ();
+ char *reply;
sprintf (rs->buf, "QTBuffer:circular:%x", val);
putpkt (rs->buf);
- remote_get_noisy_reply (&target_buf, &target_buf_size);
- if (strcmp (target_buf, "OK"))
+ reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (*reply == '\0')
error (_("Target does not support this command."));
+ if (strcmp (reply, "OK") != 0)
+ error (_("Bogus reply from target: %s"), reply);
}
static void
remote_ops.to_kill = remote_kill;
remote_ops.to_load = generic_load;
remote_ops.to_mourn_inferior = remote_mourn;
+ remote_ops.to_notice_signals = remote_notice_signals;
remote_ops.to_thread_alive = remote_thread_alive;
remote_ops.to_find_new_threads = remote_threads_info;
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_set_disconnected_tracing = remote_set_disconnected_tracing;
remote_ops.to_set_circular_trace_buffer = remote_set_circular_trace_buffer;
remote_ops.to_core_of_thread = remote_core_of_thread;
+ remote_ops.to_verify_memory = remote_verify_memory;
+ remote_ops.to_get_tib_address = remote_get_tib_address;
}
/* Set up the extended remote vector by making a copy of the standard
remote_async_mask (int new_mask)
{
int curr_mask = remote_async_mask_value;
+
remote_async_mask_value = new_mask;
return curr_mask;
}
{
struct cleanup *option_chain
= make_cleanup_ui_out_tuple_begin_end (uiout, "option");
+
ui_out_field_string (uiout, "name", list->name);
ui_out_text (uiout, ": ");
if (list->type == show_cmd)
"qGetTLSAddr", "get-thread-local-storage-address",
0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTIBAddr],
+ "qGetTIBAddr", "get-thread-information-block-address",
+ 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_bc],
"bc", "reverse-continue", 0);
add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
"FastTracepoints", "fast-tracepoints", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_TracepointSource],
+ "TracepointSource", "TracepointSource", 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