/* True if the stub reports support for static tracepoints. */
int static_tracepoints;
+ /* True if the stub reports support for installing tracepoint while
+ tracing. */
+ int install_in_trace;
+
/* True if the stub can continue running a trace while GDB is
disconnected. */
int disconnected_tracing;
tracepoints while a trace experiment is running. */
int enable_disable_tracepoints;
+ /* True if the stub can collect strings using tracenz bytecode. */
+ int string_tracing;
+
/* Nonzero if the user has pressed Ctrl-C, but the target hasn't
responded to that. */
int ctrlc_pending_p;
PACKET_ConditionalTracepoints,
PACKET_FastTracepoints,
PACKET_StaticTracepoints,
+ PACKET_InstallInTrace,
PACKET_bc,
PACKET_bs,
PACKET_TracepointSource,
PACKET_QAllow,
PACKET_qXfer_fdpic,
+ PACKET_QDisableRandomization,
PACKET_MAX
};
rs->static_tracepoints = (support == PACKET_ENABLE);
}
+static void
+remote_install_in_trace_feature (const struct protocol_feature *feature,
+ enum packet_support support,
+ const char *value)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ rs->install_in_trace = (support == PACKET_ENABLE);
+}
+
static void
remote_disconnected_tracing_feature (const struct protocol_feature *feature,
enum packet_support support,
rs->enable_disable_tracepoints = (support == PACKET_ENABLE);
}
+static void
+remote_string_tracing_feature (const struct protocol_feature *feature,
+ enum packet_support support,
+ const char *value)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ rs->string_tracing = (support == PACKET_ENABLE);
+}
+
static struct protocol_feature remote_protocol_features[] = {
{ "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
{ "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
PACKET_FastTracepoints },
{ "StaticTracepoints", PACKET_DISABLE, remote_static_tracepoint_feature,
PACKET_StaticTracepoints },
+ {"InstallInTrace", PACKET_DISABLE, remote_install_in_trace_feature,
+ PACKET_InstallInTrace},
{ "DisconnectedTracing", PACKET_DISABLE, remote_disconnected_tracing_feature,
-1 },
{ "ReverseContinue", PACKET_DISABLE, remote_supported_packet,
remote_enable_disable_tracepoint_feature, -1 },
{ "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_fdpic },
+ { "QDisableRandomization", PACKET_DISABLE, remote_supported_packet,
+ PACKET_QDisableRandomization },
+ { "tracenz", PACKET_DISABLE,
+ remote_string_tracing_feature, -1 },
};
static char *remote_support_xml;
tb[1] = 0;
fputs_unfiltered (tb, gdb_stdtarg);
}
- gdb_flush (gdb_stdtarg);
- }
+ gdb_flush (gdb_stdtarg);
+}
typedef struct cached_reg
{
struct target_waitstatus ws;
+ /* Expedited registers. This makes remote debugging a bit more
+ efficient for those targets that provide critical registers as
+ part of their normal status mechanism (as another roundtrip to
+ fetch them is avoided). */
VEC(cached_reg_t) *regcache;
int stopped_by_watchpoint_p;
if (todo <= 0)
internal_error (__FILE__, __LINE__,
- _("minumum packet size too small to write data"));
+ _("minimum packet size too small to write data"));
/* If we already need another packet, then try to align the end
of this packet to a useful boundary. */
extended_remote_mourn_1 (ops);
}
+static int
+extended_remote_supports_disable_randomization (void)
+{
+ return (remote_protocol_packets[PACKET_QDisableRandomization].support
+ == PACKET_ENABLE);
+}
+
+static void
+extended_remote_disable_randomization (int val)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *reply;
+
+ sprintf (rs->buf, "QDisableRandomization:%x", val);
+ putpkt (rs->buf);
+ reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (*reply == '\0')
+ error (_("Target does not support QDisableRandomization."));
+ if (strcmp (reply, "OK") != 0)
+ error (_("Bogus QDisableRandomization reply from target: %s"), reply);
+}
+
static int
extended_remote_run (char *args)
{
if (target_can_async_p ())
target_async (inferior_event_handler, 0);
+ /* Disable address space randomization if requested (and supported). */
+ if (extended_remote_supports_disable_randomization ())
+ extended_remote_disable_randomization (disable_randomization);
+
/* Now restart the remote server. */
if (extended_remote_run (args) == -1)
{
return 1;
}
+static int
+remote_supports_disable_randomization (void)
+{
+ /* Only supported in extended mode. */
+ return 0;
+}
+
static int
remote_supports_multi_process (void)
{
return rs->static_tracepoints;
}
+static int
+remote_supports_install_in_trace (void)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ return rs->install_in_trace;
+}
+
static int
remote_supports_enable_disable_tracepoint (void)
{
return rs->enable_disable_tracepoints;
}
+static int
+remote_supports_string_tracing (void)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ return rs->string_tracing;
+}
+
static void
remote_trace_init (void)
{
}
static void
-remote_download_tracepoint (struct breakpoint *b)
+remote_download_tracepoint (struct bp_location *loc)
{
- struct bp_location *loc;
+
CORE_ADDR tpaddr;
char addrbuf[40];
char buf[2048];
struct agent_expr *aexpr;
struct cleanup *aexpr_chain = NULL;
char *pkt;
+ struct breakpoint *b = loc->owner;
struct tracepoint *t = (struct tracepoint *) b;
- /* Iterate over all the tracepoint locations. It's up to the target to
- notice multiple tracepoint packets with the same number but different
- addresses, and treat them as multiple locations. */
- for (loc = b->loc; loc; loc = loc->next)
- {
- encode_actions (b, loc, &tdp_actions, &stepping_actions);
- old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
- tdp_actions);
- (void) make_cleanup (free_actions_list_cleanup_wrapper,
- stepping_actions);
-
- tpaddr = loc->address;
- sprintf_vma (addrbuf, tpaddr);
- sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", b->number,
- addrbuf, /* address */
- (b->enable_state == bp_enabled ? 'E' : 'D'),
- t->step_count, t->pass_count);
- /* Fast tracepoints are mostly handled by the target, but we can
- tell the target how big of an instruction block should be moved
- around. */
- if (b->type == bp_fast_tracepoint)
+ encode_actions (loc->owner, loc, &tdp_actions, &stepping_actions);
+ old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
+ tdp_actions);
+ (void) make_cleanup (free_actions_list_cleanup_wrapper,
+ stepping_actions);
+
+ tpaddr = loc->address;
+ sprintf_vma (addrbuf, tpaddr);
+ sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", b->number,
+ addrbuf, /* address */
+ (b->enable_state == bp_enabled ? 'E' : 'D'),
+ t->step_count, t->pass_count);
+ /* Fast tracepoints are mostly handled by the target, but we can
+ tell the target how big of an instruction block should be moved
+ around. */
+ if (b->type == bp_fast_tracepoint)
+ {
+ /* Only test for support at download time; we may not know
+ target capabilities at definition time. */
+ if (remote_supports_fast_tracepoints ())
{
- /* Only test for support at download time; we may not know
- target capabilities at definition time. */
- if (remote_supports_fast_tracepoints ())
- {
- int isize;
+ int isize;
- if (gdbarch_fast_tracepoint_valid_at (target_gdbarch,
- tpaddr, &isize, NULL))
- sprintf (buf + strlen (buf), ":F%x", isize);
- else
- /* If it passed validation at definition but fails now,
- something is very wrong. */
- internal_error (__FILE__, __LINE__,
- _("Fast tracepoint not "
- "valid during download"));
- }
+ if (gdbarch_fast_tracepoint_valid_at (target_gdbarch,
+ tpaddr, &isize, NULL))
+ sprintf (buf + strlen (buf), ":F%x", isize);
else
- /* Fast tracepoints are functionally identical to regular
- tracepoints, so don't take lack of support as a reason to
- give up on the trace run. */
- warning (_("Target does not support fast tracepoints, "
- "downloading %d as regular tracepoint"), b->number);
+ /* If it passed validation at definition but fails now,
+ something is very wrong. */
+ internal_error (__FILE__, __LINE__,
+ _("Fast tracepoint not "
+ "valid during download"));
}
- else if (b->type == bp_static_tracepoint)
+ else
+ /* Fast tracepoints are functionally identical to regular
+ tracepoints, so don't take lack of support as a reason to
+ give up on the trace run. */
+ warning (_("Target does not support fast tracepoints, "
+ "downloading %d as regular tracepoint"), b->number);
+ }
+ else if (b->type == bp_static_tracepoint)
+ {
+ /* Only test for support at download time; we may not know
+ target capabilities at definition time. */
+ if (remote_supports_static_tracepoints ())
{
- /* Only test for support at download time; we may not know
- target capabilities at definition time. */
- if (remote_supports_static_tracepoints ())
- {
- struct static_tracepoint_marker marker;
+ struct static_tracepoint_marker marker;
- if (target_static_tracepoint_marker_at (tpaddr, &marker))
- strcat (buf, ":S");
- else
- error (_("Static tracepoint not valid during download"));
- }
+ if (target_static_tracepoint_marker_at (tpaddr, &marker))
+ strcat (buf, ":S");
else
- /* Fast tracepoints are functionally identical to regular
- tracepoints, so don't take lack of support as a reason
- to give up on the trace run. */
- error (_("Target does not support static tracepoints"));
+ error (_("Static tracepoint not valid during download"));
}
- /* If the tracepoint has a conditional, make it into an agent
- expression and append to the definition. */
- if (loc->cond)
+ else
+ /* Fast tracepoints are functionally identical to regular
+ tracepoints, so don't take lack of support as a reason
+ to give up on the trace run. */
+ error (_("Target does not support static tracepoints"));
+ }
+ /* If the tracepoint has a conditional, make it into an agent
+ expression and append to the definition. */
+ if (loc->cond)
+ {
+ /* Only test support at download time, we may not know target
+ capabilities at definition time. */
+ if (remote_supports_cond_tracepoints ())
{
- /* Only test support at download time, we may not know target
- capabilities at definition time. */
- if (remote_supports_cond_tracepoints ())
- {
- aexpr = gen_eval_for_expr (tpaddr, loc->cond);
- aexpr_chain = make_cleanup_free_agent_expr (aexpr);
- sprintf (buf + strlen (buf), ":X%x,", aexpr->len);
- pkt = buf + strlen (buf);
- for (ndx = 0; ndx < aexpr->len; ++ndx)
- pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
- *pkt = '\0';
- do_cleanups (aexpr_chain);
- }
- else
- warning (_("Target does not support conditional tracepoints, "
- "ignoring tp %d cond"), b->number);
+ aexpr = gen_eval_for_expr (tpaddr, loc->cond);
+ aexpr_chain = make_cleanup_free_agent_expr (aexpr);
+ sprintf (buf + strlen (buf), ":X%x,", aexpr->len);
+ pkt = buf + strlen (buf);
+ for (ndx = 0; ndx < aexpr->len; ++ndx)
+ pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
+ *pkt = '\0';
+ do_cleanups (aexpr_chain);
}
+ else
+ warning (_("Target does not support conditional tracepoints, "
+ "ignoring tp %d cond"), b->number);
+ }
if (b->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."));
+ strcat (buf, "-");
+ putpkt (buf);
+ remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ error (_("Target does not support tracepoints."));
- /* do_single_steps (t); */
- if (tdp_actions)
+ /* do_single_steps (t); */
+ if (tdp_actions)
+ {
+ for (ndx = 0; tdp_actions[ndx]; ndx++)
{
- for (ndx = 0; tdp_actions[ndx]; ndx++)
- {
- QUIT; /* Allow user to bail out with ^C. */
- sprintf (buf, "QTDP:-%x:%s:%s%c",
- b->number, addrbuf, /* address */
- tdp_actions[ndx],
- ((tdp_actions[ndx + 1] || stepping_actions)
- ? '-' : 0));
- putpkt (buf);
- remote_get_noisy_reply (&target_buf,
- &target_buf_size);
- if (strcmp (target_buf, "OK"))
- error (_("Error on target while setting tracepoints."));
- }
+ QUIT; /* Allow user to bail out with ^C. */
+ sprintf (buf, "QTDP:-%x:%s:%s%c",
+ b->number, addrbuf, /* address */
+ tdp_actions[ndx],
+ ((tdp_actions[ndx + 1] || stepping_actions)
+ ? '-' : 0));
+ putpkt (buf);
+ remote_get_noisy_reply (&target_buf,
+ &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ error (_("Error on target while setting tracepoints."));
}
- if (stepping_actions)
+ }
+ if (stepping_actions)
+ {
+ for (ndx = 0; stepping_actions[ndx]; ndx++)
{
- for (ndx = 0; stepping_actions[ndx]; ndx++)
- {
- QUIT; /* Allow user to bail out with ^C. */
- sprintf (buf, "QTDP:-%x:%s:%s%s%s",
- b->number, addrbuf, /* address */
- ((ndx == 0) ? "S" : ""),
- stepping_actions[ndx],
- (stepping_actions[ndx + 1] ? "-" : ""));
- putpkt (buf);
- remote_get_noisy_reply (&target_buf,
- &target_buf_size);
- if (strcmp (target_buf, "OK"))
- error (_("Error on target while setting tracepoints."));
- }
+ QUIT; /* Allow user to bail out with ^C. */
+ sprintf (buf, "QTDP:-%x:%s:%s%s%s",
+ b->number, addrbuf, /* address */
+ ((ndx == 0) ? "S" : ""),
+ stepping_actions[ndx],
+ (stepping_actions[ndx + 1] ? "-" : ""));
+ putpkt (buf);
+ remote_get_noisy_reply (&target_buf,
+ &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ error (_("Error on target while setting tracepoints."));
}
+ }
- if (remote_protocol_packets[PACKET_TracepointSource].support
- == PACKET_ENABLE)
+ if (remote_protocol_packets[PACKET_TracepointSource].support
+ == PACKET_ENABLE)
+ {
+ if (b->addr_string)
{
- if (b->addr_string)
- {
- strcpy (buf, "QTDPsrc:");
- encode_source_string (b->number, loc->address,
- "at", b->addr_string, buf + strlen (buf),
- 2048 - strlen (buf));
+ strcpy (buf, "QTDPsrc:");
+ encode_source_string (b->number, loc->address,
+ "at", b->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 (b->cond_string)
- {
- strcpy (buf, "QTDPsrc:");
- encode_source_string (b->number, loc->address,
- "cond", b->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 (b->number, loc->address,
- breakpoint_commands (b));
+ putpkt (buf);
+ remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (strcmp (target_buf, "OK"))
+ warning (_("Target does not support source download."));
}
-
- do_cleanups (old_chain);
+ if (b->cond_string)
+ {
+ strcpy (buf, "QTDPsrc:");
+ encode_source_string (b->number, loc->address,
+ "cond", b->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 (b->number, loc->address,
+ breakpoint_commands (b));
}
+
+ do_cleanups (old_chain);
}
+static int
+remote_can_download_tracepoint (void)
+{
+ struct trace_status *ts = current_trace_status ();
+ int status = remote_get_trace_status (ts);
+
+ if (status == -1 || !ts->running_known || !ts->running)
+ return 0;
+
+ /* If we are in a tracing experiment, but remote stub doesn't support
+ installing tracepoint in trace, we have to return. */
+ if (!remote_supports_install_in_trace ())
+ return 0;
+
+ return 1;
+}
+
+
static void
remote_download_trace_state_variable (struct trace_state_variable *tsv)
{
*p++ = '\0';
putpkt (rs->buf);
reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
- if (*reply != '\0')
+ if (*reply == '\0')
error (_("Target does not support this command."));
if (strcmp (reply, "OK") != 0)
error (_("Bogus reply from target: %s"), reply);
return NULL;
}
+/* Handle the qTMinFTPILen packet. Returns the minimum length of
+ instruction on which a fast tracepoint may be placed. Returns -1
+ if the packet is not supported, and 0 if the minimum instruction
+ length is unknown. */
+
+static int
+remote_get_min_fast_tracepoint_insn_len (void)
+{
+ struct remote_state *rs = get_remote_state ();
+ char *reply;
+
+ sprintf (rs->buf, "qTMinFTPILen");
+ putpkt (rs->buf);
+ reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+ if (*reply == '\0')
+ return -1;
+ else
+ {
+ ULONGEST min_insn_len;
+
+ unpack_varlen_hex (reply, &min_insn_len);
+
+ return (int) min_insn_len;
+ }
+}
+
static void
init_remote_ops (void)
{
remote_ops.to_terminal_ours = remote_terminal_ours;
remote_ops.to_supports_non_stop = remote_supports_non_stop;
remote_ops.to_supports_multi_process = remote_supports_multi_process;
+ remote_ops.to_supports_disable_randomization
+ = remote_supports_disable_randomization;
remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
+ remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
remote_ops.to_trace_init = remote_trace_init;
remote_ops.to_download_tracepoint = remote_download_tracepoint;
+ remote_ops.to_can_download_tracepoint = remote_can_download_tracepoint;
remote_ops.to_download_trace_state_variable
= remote_download_trace_state_variable;
remote_ops.to_enable_tracepoint = remote_enable_tracepoint;
remote_ops.to_upload_trace_state_variables
= remote_upload_trace_state_variables;
remote_ops.to_get_raw_trace_data = remote_get_raw_trace_data;
+ remote_ops.to_get_min_fast_tracepoint_insn_len = remote_get_min_fast_tracepoint_insn_len;
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;
extended_remote_ops.to_detach = extended_remote_detach;
extended_remote_ops.to_attach = extended_remote_attach;
extended_remote_ops.to_kill = extended_remote_kill;
+ extended_remote_ops.to_supports_disable_randomization
+ = extended_remote_supports_disable_randomization;
}
static int
add_packet_config_cmd (&remote_protocol_packets[PACKET_StaticTracepoints],
"StaticTracepoints", "static-tracepoints", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_InstallInTrace],
+ "InstallInTrace", "install-in-trace", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_statictrace_read],
"qXfer:statictrace:read", "read-sdata-object", 0);
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_fdpic],
"qXfer:fdpic:read", "read-fdpic-loadmap", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_QDisableRandomization],
+ "QDisableRandomization", "disable-randomization", 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