summaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index 01e3f306c93..1c9367d2b0f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -242,6 +242,8 @@ static void remote_console_output (char *msg);
static int remote_supports_cond_breakpoints (void);
+static int remote_can_run_breakpoint_commands (void);
+
/* The non-stop remote protocol provisions for one pending stop reply.
This is where we keep it until it is acknowledged. */
@@ -323,6 +325,10 @@ struct remote_state
conditions. */
int cond_breakpoints;
+ /* True if the stub reports support for target-side breakpoint
+ commands. */
+ int breakpoint_commands;
+
/* True if the stub reports support for fast tracepoints. */
int fast_tracepoints;
@@ -1274,6 +1280,7 @@ enum {
PACKET_qAttached,
PACKET_ConditionalTracepoints,
PACKET_ConditionalBreakpoints,
+ PACKET_BreakpointCommands,
PACKET_FastTracepoints,
PACKET_StaticTracepoints,
PACKET_InstallInTrace,
@@ -3801,6 +3808,16 @@ remote_cond_breakpoint_feature (const struct protocol_feature *feature,
}
static void
+remote_breakpoint_commands_feature (const struct protocol_feature *feature,
+ enum packet_support support,
+ const char *value)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ rs->breakpoint_commands = (support == PACKET_ENABLE);
+}
+
+static void
remote_fast_tracepoint_feature (const struct protocol_feature *feature,
enum packet_support support,
const char *value)
@@ -3898,6 +3915,8 @@ static struct protocol_feature remote_protocol_features[] = {
PACKET_ConditionalTracepoints },
{ "ConditionalBreakpoints", PACKET_DISABLE, remote_cond_breakpoint_feature,
PACKET_ConditionalBreakpoints },
+ { "BreakpointCommands", PACKET_DISABLE, remote_breakpoint_commands_feature,
+ PACKET_BreakpointCommands },
{ "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature,
PACKET_FastTracepoints },
{ "StaticTracepoints", PACKET_DISABLE, remote_static_tracepoint_feature,
@@ -7873,6 +7892,37 @@ remote_add_target_side_condition (struct gdbarch *gdbarch,
return 0;
}
+static void
+remote_add_target_side_commands (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt, char *buf)
+{
+ struct agent_expr *aexpr = NULL;
+ int i, ix;
+
+ if (VEC_empty (agent_expr_p, bp_tgt->tcommands))
+ return;
+
+ buf += strlen (buf);
+
+ sprintf (buf, ";cmds:%x,", bp_tgt->persist);
+ buf += strlen (buf);
+
+ /* Concatenate all the agent expressions that are commands into the
+ cmds parameter. */
+ for (ix = 0;
+ VEC_iterate (agent_expr_p, bp_tgt->tcommands, ix, aexpr);
+ ix++)
+ {
+ sprintf (buf, "X%x,", aexpr->len);
+ buf += strlen (buf);
+ for (i = 0; i < aexpr->len; ++i)
+ buf = pack_hex_byte (buf, aexpr->buf[i]);
+ *buf = '\0';
+ }
+
+ VEC_free (agent_expr_p, bp_tgt->tcommands);
+}
+
/* Insert a breakpoint. On targets that have software breakpoint
support, we ask the remote target to do the work; on targets
which don't, we insert a traditional memory breakpoint. */
@@ -7910,6 +7960,9 @@ remote_insert_breakpoint (struct gdbarch *gdbarch,
if (remote_supports_cond_breakpoints ())
remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
+ if (remote_can_run_breakpoint_commands ())
+ remote_add_target_side_commands (gdbarch, bp_tgt, p);
+
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
@@ -8151,6 +8204,9 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch,
if (remote_supports_cond_breakpoints ())
remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
+ if (remote_can_run_breakpoint_commands ())
+ remote_add_target_side_commands (gdbarch, bp_tgt, p);
+
putpkt (rs->buf);
getpkt (&rs->buf, &rs->buf_size, 0);
@@ -10089,6 +10145,14 @@ remote_supports_string_tracing (void)
return rs->string_tracing;
}
+static int
+remote_can_run_breakpoint_commands (void)
+{
+ struct remote_state *rs = get_remote_state ();
+
+ return rs->breakpoint_commands;
+}
+
static void
remote_trace_init (void)
{
@@ -11007,6 +11071,7 @@ Specify the serial device it is connected to\n\
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_supports_evaluation_of_breakpoint_conditions = remote_supports_cond_breakpoints;
+ remote_ops.to_can_run_breakpoint_commands = remote_can_run_breakpoint_commands;
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;
@@ -11537,6 +11602,10 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
"ConditionalBreakpoints",
"conditional-breakpoints", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_BreakpointCommands],
+ "BreakpointCommands",
+ "breakpoint-commands", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
"FastTracepoints", "fast-tracepoints", 0);