aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog21
-rw-r--r--gdb/aarch64-linux-nat.c9
-rw-r--r--gdb/arm-linux-tdep.c5
-rw-r--r--gdb/doc/ChangeLog7
-rw-r--r--gdb/doc/gdb.texinfo8
-rw-r--r--gdb/gdbserver/ChangeLog9
-rw-r--r--gdb/gdbserver/server.c23
-rw-r--r--gdb/remote.c58
-rw-r--r--gdb/target-delegates.c31
-rw-r--r--gdb/target.h9
10 files changed, 170 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index aefa301..9932d60 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,26 @@
2015-09-15 Yao Qi <yao.qi@linaro.org>
+ * aarch64-linux-nat.c (aarch64_linux_can_do_single_step): New
+ function.
+ (_initialize_aarch64_linux_nat): Install it to to_can_do_single_step.
+ * arm-linux-tdep.c (arm_linux_software_single_step): Return 0
+ if target_can_do_single_step returns 1.
+ * remote.c (struct vCont_action_support) <s, S>: New fields.
+ (PACKET_vContSupported): New enum.
+ (remote_protocol_features): New element for vContSupported.
+ (remote_query_supported): Append "vContSupported+".
+ (remote_vcont_probe): Remove support_s and support_S, use
+ rs->supports_vCont.s and rs->supports_vCont.S instead. Disable
+ vCont packet if c and C actions are not supported.
+ (remote_can_do_single_step): New function.
+ (init_remote_ops): Install it to to_can_do_single_step.
+ (_initialize_remote): Call add_packet_config_cmd.
+ * target.h (struct target_ops) <to_can_do_single_step>: New field.
+ (target_can_do_single_step): New macro.
+ * target-delegates.c: Re-generated.
+
+2015-09-15 Yao Qi <yao.qi@linaro.org>
+
* aarch64-linux-nat.c (aarch64_linux_siginfo_fixup): New function.
(_initialize_aarch64_linux_nat): Call linux_nat_set_siginfo_fixup.
* nat/aarch64-linux.c (aarch64_compat_siginfo_from_siginfo):
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index ddb2788..d7ac19e 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -807,6 +807,14 @@ aarch64_linux_watchpoint_addr_within_range (struct target_ops *target,
return start <= addr && start + length - 1 >= addr;
}
+/* Implement the "to_can_do_single_step" target_ops method. */
+
+static int
+aarch64_linux_can_do_single_step (struct target_ops *target)
+{
+ return 1;
+}
+
/* Define AArch64 maintenance commands. */
static void
@@ -858,6 +866,7 @@ _initialize_aarch64_linux_nat (void)
t->to_stopped_data_address = aarch64_linux_stopped_data_address;
t->to_watchpoint_addr_within_range =
aarch64_linux_watchpoint_addr_within_range;
+ t->to_can_do_single_step = aarch64_linux_can_do_single_step;
/* Override the GNU/Linux inferior startup hook. */
super_post_startup_inferior = t->to_post_startup_inferior;
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index b3ad868..bc2cec4 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -917,6 +917,11 @@ arm_linux_software_single_step (struct frame_info *frame)
if (arm_deal_with_atomic_sequence (frame))
return 1;
+ /* If the target does have hardware single step, GDB doesn't have
+ to bother software single step. */
+ if (target_can_do_single_step () == 1)
+ return 0;
+
next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
/* The Linux kernel offers some user-mode helpers in a high page. We can
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 1f99a2f..b5de969 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,10 @@
+2015-09-15 Yao Qi <yao.qi@linaro.org>
+
+ * gdb.texinfo (General Query Packets): Add vContSupported to
+ tables of 'gdbfeatures' and 'stub features' supported in the
+ qSupported packet, as well as to the list containing stub
+ feature details.
+
2015-09-11 Don Breazeal <donb@codesourcery.com>
* gdb.texinfo (Remote Configuration): Add exec event
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 395f0d4..4ecdb8f 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -36132,6 +36132,10 @@ This feature indicates whether @value{GDBN} supports exec event
extensions to the remote protocol. @value{GDBN} does not use such
extensions unless the stub also reports that it supports them by
including @samp{exec-events+} in its @samp{qSupported} reply.
+
+@item vContSupported
+This feature indicates whether @value{GDBN} wants to know the
+supported actions in the reply to @samp{vCont?} packet.
@end table
Stubs should ignore any unknown values for
@@ -36608,6 +36612,10 @@ and vforkdone events.
@item exec-events
The remote stub reports the @samp{exec} stop reason for exec events.
+@item vContSupported
+The remote stub reports the supported actions in the reply to
+@samp{vCont?} packet.
+
@end table
@item qSymbol::
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 7831b85..fac52ef 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,14 @@
2015-09-15 Yao Qi <yao.qi@linaro.org>
+ * server.c (vCont_supported): New global variable.
+ (handle_query): Set vCont_supported to 1 if "vContSupported+"
+ matches. Append ";vContSupported+" to own_buf.
+ (handle_v_requests): Append ";s;S" to own_buf if target supports
+ hardware single step or vCont_supported is false.
+ (capture_main): Set vCont_supported to zero.
+
+2015-09-15 Yao Qi <yao.qi@linaro.org>
+
* linux-low.c (linux_supports_conditional_breakpoints): Rename
it to ...
(linux_supports_hardware_single_step): ... New function.
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 1481c47..3b9ec98 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -64,6 +64,11 @@ int non_stop;
int swbreak_feature;
int hwbreak_feature;
+/* True if the "vContSupported" feature is active. In that case, GDB
+ wants us to report whether single step is supported in the reply to
+ "vCont?" packet. */
+static int vCont_supported;
+
/* Whether we should attempt to disable the operating system's address
space randomization feature before starting an inferior. */
int disable_randomization = 1;
@@ -2118,6 +2123,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_exec_events ())
report_exec_events = 1;
}
+ else if (strcmp (p, "vContSupported+") == 0)
+ vCont_supported = 1;
else
target_process_qsupported (p);
@@ -2227,6 +2234,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (the_target->pid_to_exec_file != NULL)
strcat (own_buf, ";qXfer:exec-file:read+");
+ strcat (own_buf, ";vContSupported+");
+
/* Reinitialize components as needed for the new connection. */
hostio_handle_new_gdb_connection ();
target_handle_new_gdb_connection ();
@@ -2825,7 +2834,18 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
if (startswith (own_buf, "vCont?"))
{
- strcpy (own_buf, "vCont;c;C;s;S;t");
+ strcpy (own_buf, "vCont;c;C;t");
+
+ if (target_supports_hardware_single_step () || !vCont_supported)
+ {
+ /* If target supports hardware single step, add actions s
+ and S to the list of supported actions. On the other
+ hand, if GDB doesn't request the supported vCont actions
+ in qSupported packet, add s and S to the list too. */
+ own_buf = own_buf + strlen (own_buf);
+ strcpy (own_buf, ";s;S");
+ }
+
if (target_supports_range_stepping ())
{
own_buf = own_buf + strlen (own_buf);
@@ -3566,6 +3586,7 @@ captured_main (int argc, char *argv[])
cont_thread = null_ptid;
swbreak_feature = 0;
hwbreak_feature = 0;
+ vCont_supported = 0;
remote_open (port);
diff --git a/gdb/remote.c b/gdb/remote.c
index db83e6b..b9dc4af 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -260,6 +260,12 @@ struct vCont_action_support
/* vCont;r */
int r;
+
+ /* vCont;s */
+ int s;
+
+ /* vCont;S */
+ int S;
};
/* Controls whether GDB is willing to use range stepping. */
@@ -1466,6 +1472,9 @@ enum {
/* Support for exec events. */
PACKET_exec_event_feature,
+ /* Support for query supported vCont actions. */
+ PACKET_vContSupported,
+
PACKET_MAX
};
@@ -4375,7 +4384,8 @@ static const struct protocol_feature remote_protocol_features[] = {
{ "exec-events", PACKET_DISABLE, remote_supported_packet,
PACKET_exec_event_feature },
{ "Qbtrace-conf:pt:size", PACKET_DISABLE, remote_supported_packet,
- PACKET_Qbtrace_conf_pt_size }
+ PACKET_Qbtrace_conf_pt_size },
+ { "vContSupported", PACKET_DISABLE, remote_supported_packet, PACKET_vContSupported }
};
static char *remote_support_xml;
@@ -4468,6 +4478,9 @@ remote_query_supported (void)
q = remote_query_supported_append (q, "exec-events+");
}
+ if (packet_set_cmd_state (PACKET_vContSupported) != AUTO_BOOLEAN_FALSE)
+ q = remote_query_supported_append (q, "vContSupported+");
+
q = reconcat (q, "qSupported:", q, (char *) NULL);
putpkt (q);
@@ -5061,10 +5074,10 @@ remote_vcont_probe (struct remote_state *rs)
if (startswith (buf, "vCont"))
{
char *p = &buf[5];
- int support_s, support_S, support_c, support_C;
+ int support_c, support_C;
- support_s = 0;
- support_S = 0;
+ rs->supports_vCont.s = 0;
+ rs->supports_vCont.S = 0;
support_c = 0;
support_C = 0;
rs->supports_vCont.t = 0;
@@ -5073,9 +5086,9 @@ remote_vcont_probe (struct remote_state *rs)
{
p++;
if (*p == 's' && (*(p + 1) == ';' || *(p + 1) == 0))
- support_s = 1;
+ rs->supports_vCont.s = 1;
else if (*p == 'S' && (*(p + 1) == ';' || *(p + 1) == 0))
- support_S = 1;
+ rs->supports_vCont.S = 1;
else if (*p == 'c' && (*(p + 1) == ';' || *(p + 1) == 0))
support_c = 1;
else if (*p == 'C' && (*(p + 1) == ';' || *(p + 1) == 0))
@@ -5088,9 +5101,9 @@ remote_vcont_probe (struct remote_state *rs)
p = strchr (p, ';');
}
- /* If s, S, c, and C are not all supported, we can't use vCont. Clearing
- BUF will make packet_ok disable the packet. */
- if (!support_s || !support_S || !support_c || !support_C)
+ /* If c, and C are not all supported, we can't use vCont. Clearing
+ BUF will make packet_ok disable the packet. */
+ if (!support_c || !support_C)
buf[0] = 0;
}
@@ -12653,6 +12666,29 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
return filename;
}
+/* Implement the to_can_do_single_step target_ops method. */
+
+static int
+remote_can_do_single_step (struct target_ops *ops)
+{
+ /* We can only tell whether target supports single step or not by
+ supported s and S vCont actions if the stub supports vContSupported
+ feature. If the stub doesn't support vContSupported feature,
+ we have conservatively to think target doesn't supports single
+ step. */
+ if (packet_support (PACKET_vContSupported) == PACKET_ENABLE)
+ {
+ struct remote_state *rs = get_remote_state ();
+
+ if (packet_support (PACKET_vCont) == PACKET_SUPPORT_UNKNOWN)
+ remote_vcont_probe (rs);
+
+ return rs->supports_vCont.s && rs->supports_vCont.S;
+ }
+ else
+ return 0;
+}
+
static void
init_remote_ops (void)
{
@@ -12724,6 +12760,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_can_async_p = remote_can_async_p;
remote_ops.to_is_async_p = remote_is_async_p;
remote_ops.to_async = remote_async;
+ remote_ops.to_can_do_single_step = remote_can_do_single_step;
remote_ops.to_terminal_inferior = remote_terminal_inferior;
remote_ops.to_terminal_ours = remote_terminal_ours;
remote_ops.to_supports_non_stop = remote_supports_non_stop;
@@ -13431,6 +13468,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_pt_size],
"Qbtrace-conf:pt:size", "btrace-conf-pt-size", 0);
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_vContSupported],
+ "vContSupported", "verbose-resume-supported", 0);
+
add_packet_config_cmd (&remote_protocol_packets[PACKET_exec_event_feature],
"exec-event-feature", "exec-event-feature", 0);
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index 87197f8..c358814 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -826,6 +826,33 @@ debug_masked_watch_num_registers (struct target_ops *self, CORE_ADDR arg1, CORE_
return result;
}
+static int
+delegate_can_do_single_step (struct target_ops *self)
+{
+ self = self->beneath;
+ return self->to_can_do_single_step (self);
+}
+
+static int
+tdefault_can_do_single_step (struct target_ops *self)
+{
+ return -1;
+}
+
+static int
+debug_can_do_single_step (struct target_ops *self)
+{
+ int result;
+ fprintf_unfiltered (gdb_stdlog, "-> %s->to_can_do_single_step (...)\n", debug_target.to_shortname);
+ result = debug_target.to_can_do_single_step (&debug_target);
+ fprintf_unfiltered (gdb_stdlog, "<- %s->to_can_do_single_step (", debug_target.to_shortname);
+ target_debug_print_struct_target_ops_p (&debug_target);
+ fputs_unfiltered (") = ", gdb_stdlog);
+ target_debug_print_int (result);
+ fputs_unfiltered ("\n", gdb_stdlog);
+ return result;
+}
+
static void
delegate_terminal_init (struct target_ops *self)
{
@@ -4028,6 +4055,8 @@ install_delegators (struct target_ops *ops)
ops->to_can_accel_watchpoint_condition = delegate_can_accel_watchpoint_condition;
if (ops->to_masked_watch_num_registers == NULL)
ops->to_masked_watch_num_registers = delegate_masked_watch_num_registers;
+ if (ops->to_can_do_single_step == NULL)
+ ops->to_can_do_single_step = delegate_can_do_single_step;
if (ops->to_terminal_init == NULL)
ops->to_terminal_init = delegate_terminal_init;
if (ops->to_terminal_inferior == NULL)
@@ -4298,6 +4327,7 @@ install_dummy_methods (struct target_ops *ops)
ops->to_region_ok_for_hw_watchpoint = default_region_ok_for_hw_watchpoint;
ops->to_can_accel_watchpoint_condition = tdefault_can_accel_watchpoint_condition;
ops->to_masked_watch_num_registers = tdefault_masked_watch_num_registers;
+ ops->to_can_do_single_step = tdefault_can_do_single_step;
ops->to_terminal_init = tdefault_terminal_init;
ops->to_terminal_inferior = tdefault_terminal_inferior;
ops->to_terminal_ours_for_output = tdefault_terminal_ours_for_output;
@@ -4450,6 +4480,7 @@ init_debug_target (struct target_ops *ops)
ops->to_region_ok_for_hw_watchpoint = debug_region_ok_for_hw_watchpoint;
ops->to_can_accel_watchpoint_condition = debug_can_accel_watchpoint_condition;
ops->to_masked_watch_num_registers = debug_masked_watch_num_registers;
+ ops->to_can_do_single_step = debug_can_do_single_step;
ops->to_terminal_init = debug_terminal_init;
ops->to_terminal_inferior = debug_terminal_inferior;
ops->to_terminal_ours_for_output = debug_terminal_ours_for_output;
diff --git a/gdb/target.h b/gdb/target.h
index 5f05b56..2875ad4 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -559,6 +559,12 @@ struct target_ops
int (*to_masked_watch_num_registers) (struct target_ops *,
CORE_ADDR, CORE_ADDR)
TARGET_DEFAULT_RETURN (-1);
+
+ /* Return 1 for sure target can do single step. Return -1 for
+ unknown. Return 0 for target can't do. */
+ int (*to_can_do_single_step) (struct target_ops *)
+ TARGET_DEFAULT_RETURN (-1);
+
void (*to_terminal_init) (struct target_ops *)
TARGET_DEFAULT_IGNORE ();
void (*to_terminal_inferior) (struct target_ops *)
@@ -1910,6 +1916,9 @@ extern char *target_thread_name (struct thread_info *);
addr, len)
+#define target_can_do_single_step() \
+ (*current_target.to_can_do_single_step) (&current_target)
+
/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes.
TYPE is 0 for write, 1 for read, and 2 for read/write accesses.
COND is the expression for its condition, or NULL if there's none.