You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
7.6 KiB
219 lines
7.6 KiB
http://sourceware.org/ml/gdb-patches/2015-02/msg00733.html |
|
Subject: [PATCH 4/8] remote+docs: software/hardware breakpoint traps |
|
|
|
This adjusts target remote to tell the core whether a trap was caused |
|
by a breakpoint. |
|
|
|
To that end, the patch teaches GDB about new RSP stop reasons "T05 |
|
swbreak" and "T05 hwbreak", that remote targets report back to GDB, |
|
similarly to how "T05 watch" indicates a stop caused by a watchpoint. |
|
|
|
Because targets that can report these events are expected to |
|
themselves adjust the PC after a software breakpoint, these new stop |
|
reasons must only be reported if the stub is talking to a GDB that |
|
understands them. Because of that, the use of the new stop reasons |
|
needs to be handshaked on initial connection, using the qSupported |
|
mechanism. GDB simply sends "swbreak+" in its qSupports query, and |
|
the stub reports back "swbreak+" too. |
|
|
|
Because these new stop reasons are required to fix a fundamental |
|
non-stop mode problem, this commit extends the remote non-stop intro |
|
section in the manual, documenting the events as required. |
|
|
|
To be clear, GDB will still cope with remote targets that don't |
|
support these new stop reasons; it will behave just like today. |
|
|
|
Tested on x86-64 Fedora 20, native and gdbserver. |
|
|
|
gdb/ChangeLog: |
|
2015-02-25 Pedro Alves <palves@redhat.com> |
|
|
|
* NEWS: Mention the new "swbreak" and "hwbreak" stop reasons. |
|
* remote.c (struct remote_state) <remote_stopped_by_watchpoint_p>: |
|
Delete field. |
|
<stop_reason>: New field. |
|
(PACKET_swbreak_feature, PACKET_hwbreak_feature): New enum values. |
|
(packet_set_cmd_state): New function. |
|
(remote_protocol_features): Register the "swbreak" and "hwbreak" |
|
features. |
|
(remote_query_supported): If not disabled with the corresponding |
|
"set remote foo-packet" command, report support for the swbreak |
|
and hwbreak features. |
|
(struct stop_reply) <remote_stopped_by_watchpoint_p>: Delete |
|
field. |
|
<stop_reason>: New field. |
|
(remote_parse_stop_reply): Handle "swbreak" and "hwbreak". |
|
(remote_wait_as): Adjust. |
|
(remote_stopped_by_sw_breakpoint) |
|
(remote_supports_stopped_by_sw_breakpoint) |
|
(remote_stopped_by_hw_breakpoint) |
|
(remote_supports_stopped_by_hw_breakpoint): New functions. |
|
(remote_stopped_by_watchpoint): New function. |
|
(init_remote_ops): Install them. |
|
(_initialize_remote): Register new "set/show remote |
|
swbreak-feature-packet" and "set/show remote |
|
swbreak-feature-packet" commands. |
|
|
|
gdb/doc/ChangeLog: |
|
2015-02-25 Pedro Alves <palves@redhat.com> |
|
|
|
* gdb.texinfo (Remote Configuration): Document the "set/show |
|
remote swbreak-feature-packet" and "set/show remote |
|
hwbreak-feature-packet" commands. |
|
(Packets) <Z0>: Add cross link to the "swbreak" stop reason's |
|
decription. |
|
(Stop Reply Packets): Document the swbreak and hwbreak stop |
|
reasons. |
|
(General Query Packets): Document the swbreak and hwbreak |
|
qSupported features. |
|
(Remote Non-Stop): Explain that swbreak and hwbreak are required. |
|
--- |
|
gdb/NEWS | 10 +++++ |
|
gdb/doc/gdb.texinfo | 80 +++++++++++++++++++++++++++++++++++ |
|
gdb/remote.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++---- |
|
3 files changed, 200 insertions(+), 9 deletions(-) |
|
|
|
Index: gdb-7.6.1/gdb/remote.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/remote.c 2016-03-13 19:41:32.258628611 +0100 |
|
+++ gdb-7.6.1/gdb/remote.c 2016-03-13 19:42:35.787094677 +0100 |
|
@@ -728,6 +728,9 @@ |
|
/* This is non-zero if target stopped for a watchpoint. */ |
|
static int remote_stopped_by_watchpoint_p; |
|
|
|
+/* RHEL: TARGET_STOPPED_BY_HW_BREAKPOINT */ |
|
+static int stopped_by_hw_breakpoint; |
|
+ |
|
static struct target_ops remote_ops; |
|
|
|
static struct target_ops extended_remote_ops; |
|
@@ -1289,11 +1292,24 @@ |
|
PACKET_Qbtrace_off, |
|
PACKET_Qbtrace_bts, |
|
PACKET_qXfer_btrace, |
|
+ |
|
+ /* Support for hwbreak+ feature. */ |
|
+ PACKET_hwbreak_feature, |
|
+ |
|
PACKET_MAX |
|
}; |
|
|
|
static struct packet_config remote_protocol_packets[PACKET_MAX]; |
|
|
|
+/* Returns the packet's corresponding "set remote foo-packet" command |
|
+ state. See struct packet_config for more details. */ |
|
+ |
|
+static enum auto_boolean |
|
+packet_set_cmd_state (int packet) |
|
+{ |
|
+ return remote_protocol_packets[packet].detect; |
|
+} |
|
+ |
|
static void |
|
set_remote_protocol_packet_cmd (char *args, int from_tty, |
|
struct cmd_list_element *c) |
|
@@ -4017,7 +4033,8 @@ |
|
{ "Qbtrace:off", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_off }, |
|
{ "Qbtrace:bts", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_bts }, |
|
{ "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet, |
|
- PACKET_qXfer_btrace } |
|
+ PACKET_qXfer_btrace }, |
|
+ { "hwbreak", PACKET_DISABLE, remote_supported_packet, PACKET_hwbreak_feature } |
|
}; |
|
|
|
static char *remote_support_xml; |
|
@@ -4086,6 +4103,9 @@ |
|
|
|
q = remote_query_supported_append (q, "multiprocess+"); |
|
|
|
+ if (packet_set_cmd_state (PACKET_hwbreak_feature) != AUTO_BOOLEAN_FALSE) |
|
+ q = remote_query_supported_append (q, "hwbreak+"); |
|
+ |
|
if (remote_support_xml) |
|
q = remote_query_supported_append (q, remote_support_xml); |
|
|
|
@@ -5202,6 +5222,9 @@ |
|
int stopped_by_watchpoint_p; |
|
CORE_ADDR watch_data_address; |
|
|
|
+ /* RHEL: TARGET_STOPPED_BY_HW_BREAKPOINT */ |
|
+ int stopped_by_hw_breakpoint; |
|
+ |
|
int solibs_changed; |
|
int replay_event; |
|
|
|
@@ -5467,6 +5490,7 @@ |
|
event->solibs_changed = 0; |
|
event->replay_event = 0; |
|
event->stopped_by_watchpoint_p = 0; |
|
+ event->stopped_by_hw_breakpoint = 0; |
|
event->regcache = NULL; |
|
event->core = -1; |
|
|
|
@@ -5522,6 +5546,23 @@ |
|
p = unpack_varlen_hex (++p1, &addr); |
|
event->watch_data_address = (CORE_ADDR) addr; |
|
} |
|
+ else if (strncmp (p, "hwbreak", p1 - p) == 0) |
|
+ { |
|
+ event->stopped_by_hw_breakpoint = 1; |
|
+ |
|
+ /* Make sure the stub doesn't forget to indicate support |
|
+ with qSupported. */ |
|
+ //if (packet_support (PACKET_hwbreak_feature) != PACKET_ENABLE) |
|
+ // error (_("Unexpected hwbreak stop reason")); |
|
+ |
|
+ /* See above. */ |
|
+ //p = skip_to_semicolon (p1 + 1); |
|
+ p1++; |
|
+ p_temp = p1; |
|
+ while (*p_temp && *p_temp != ';') |
|
+ p_temp++; |
|
+ p = p_temp; |
|
+ } |
|
else if (strncmp (p, "library", p1 - p) == 0) |
|
{ |
|
p1++; |
|
@@ -5783,6 +5824,7 @@ |
|
|
|
remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p; |
|
remote_watch_data_address = stop_reply->watch_data_address; |
|
+ stopped_by_hw_breakpoint = stop_reply->stopped_by_hw_breakpoint; |
|
|
|
remote_notice_new_inferior (ptid, 0); |
|
demand_private_info (ptid)->core = stop_reply->core; |
|
@@ -8310,6 +8352,16 @@ |
|
return -1; |
|
} |
|
|
|
+/* The to_stopped_by_hw_breakpoint method of target remote. */ |
|
+ |
|
+static int |
|
+remote_stopped_by_hw_breakpoint (struct target_ops *ops) |
|
+{ |
|
+ struct remote_state *rs = get_remote_state (); |
|
+ |
|
+ return stopped_by_hw_breakpoint; |
|
+} |
|
+ |
|
static int |
|
remote_stopped_by_watchpoint (void) |
|
{ |
|
@@ -11372,6 +11424,7 @@ |
|
remote_ops.to_files_info = remote_files_info; |
|
remote_ops.to_insert_breakpoint = remote_insert_breakpoint; |
|
remote_ops.to_remove_breakpoint = remote_remove_breakpoint; |
|
+ remote_ops.to_stopped_by_hw_breakpoint = remote_stopped_by_hw_breakpoint; |
|
remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint; |
|
remote_ops.to_stopped_data_address = remote_stopped_data_address; |
|
remote_ops.to_watchpoint_addr_within_range = |
|
@@ -12010,6 +12063,9 @@ |
|
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace], |
|
"qXfer:btrace", "read-btrace", 0); |
|
|
|
+ add_packet_config_cmd (&remote_protocol_packets[PACKET_hwbreak_feature], |
|
+ "hwbreak-feature", "hwbreak-feature", 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
|
|
|