aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/gdbserver/ChangeLog15
-rw-r--r--gdb/gdbserver/remote-utils.c10
-rw-r--r--gdb/gdbserver/server.c25
-rw-r--r--gdb/gdbserver/server.h11
-rw-r--r--gdb/gdbserver/target.h31
5 files changed, 92 insertions, 0 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 69844cf..53538a4 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,20 @@
2015-03-04 Pedro Alves <palves@redhat.com>
+ * remote-utils.c (prepare_resume_reply): Report swbreak/hbreak.
+ * server.c (swbreak_feature, hwbreak_feature): New globals.
+ (handle_query) <qSupported>: Handle "swbreak+" and "hwbreak+".
+ (captured_main): Clear swbreak_feature and hwbreak_feature.
+ * server.h (swbreak_feature, hwbreak_feature): Declare.
+ * target.h (struct target_ops) <stopped_by_sw_breakpoint,
+ supports_stopped_by_sw_breakpoint, stopped_by_hw_breakpoint,
+ supports_stopped_by_hw_breakpoint>: New fields.
+ (target_supports_stopped_by_sw_breakpoint)
+ (target_stopped_by_sw_breakpoint)
+ (target_supports_stopped_by_hw_breakpoint)
+ (target_stopped_by_hw_breakpoint): Declare.
+
+2015-03-04 Pedro Alves <palves@redhat.com>
+
enum lwp_stop_reason -> enum target_stop_reason
* linux-low.c (check_stopped_by_breakpoint): Adjust.
(thread_still_has_status_pending_p, check_stopped_by_watchpoint)
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 8854c4c..02c40f5 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1149,6 +1149,16 @@ prepare_resume_reply (char *buf, ptid_t ptid,
*buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
*buf++ = ';';
}
+ else if (swbreak_feature && target_stopped_by_sw_breakpoint ())
+ {
+ sprintf (buf, "swbreak:;");
+ buf += strlen (buf);
+ }
+ else if (hwbreak_feature && target_stopped_by_hw_breakpoint ())
+ {
+ sprintf (buf, "hwbreak:;");
+ buf += strlen (buf);
+ }
while (*regp)
{
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 156fcc8a..83529ff 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -58,6 +58,8 @@ int run_once;
int multi_process;
int non_stop;
+int swbreak_feature;
+int hwbreak_feature;
/* Whether we should attempt to disable the operating system's address
space randomization feature before starting an inferior. */
@@ -1977,6 +1979,21 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
/* GDB supports relocate instruction requests. */
gdb_supports_qRelocInsn = 1;
}
+ else if (strcmp (p, "swbreak+") == 0)
+ {
+ /* GDB wants us to report whether a trap is caused
+ by a software breakpoint and for us to handle PC
+ adjustment if necessary on this target. */
+ if (target_supports_stopped_by_sw_breakpoint ())
+ swbreak_feature = 1;
+ }
+ else if (strcmp (p, "hwbreak+") == 0)
+ {
+ /* GDB wants us to report whether a trap is caused
+ by a hardware breakpoint. */
+ if (target_supports_stopped_by_hw_breakpoint ())
+ hwbreak_feature = 1;
+ }
else
target_process_qsupported (p);
@@ -2061,6 +2078,12 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
supported_btrace_packets (own_buf);
+ if (target_supports_stopped_by_sw_breakpoint ())
+ strcat (own_buf, ";swbreak+");
+
+ if (target_supports_stopped_by_hw_breakpoint ())
+ strcat (own_buf, ";hwbreak+");
+
return;
}
@@ -3376,6 +3399,8 @@ captured_main (int argc, char *argv[])
/* Be sure we're out of tfind mode. */
current_traceframe = -1;
cont_thread = null_ptid;
+ swbreak_feature = 0;
+ hwbreak_feature = 0;
remote_open (port);
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index dbf31d5..91d4080 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -86,6 +86,17 @@ extern int run_once;
extern int multi_process;
extern int non_stop;
+/* True if the "swbreak+" feature is active. In that case, GDB wants
+ us to report whether a trap is explained by a software breakpoint
+ and for the server to handle PC adjustment if necessary on this
+ target. Only enabled if the target supports it. */
+extern int swbreak_feature;
+
+/* True if the "hwbreak+" feature is active. In that case, GDB wants
+ us to report whether a trap is explained by a hardware breakpoint.
+ Only enabled if the target supports it. */
+extern int hwbreak_feature;
+
extern int disable_randomization;
#if USE_WIN32API
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 05feb36..126c861 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -207,6 +207,21 @@ struct target_ops
int (*remove_point) (enum raw_bkpt_type type, CORE_ADDR addr,
int size, struct raw_breakpoint *bp);
+ /* Returns 1 if the target stopped because it executed a software
+ breakpoint instruction, 0 otherwise. */
+ int (*stopped_by_sw_breakpoint) (void);
+
+ /* Returns true if the target knows whether a trap was caused by a
+ SW breakpoint triggering. */
+ int (*supports_stopped_by_sw_breakpoint) (void);
+
+ /* Returns 1 if the target stopped for a hardware breakpoint. */
+ int (*stopped_by_hw_breakpoint) (void);
+
+ /* Returns true if the target knows whether a trap was caused by a
+ HW breakpoint triggering. */
+ int (*supports_stopped_by_hw_breakpoint) (void);
+
/* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise. */
int (*stopped_by_watchpoint) (void);
@@ -515,6 +530,22 @@ int kill_inferior (int);
(the_target->supports_range_stepping ? \
(*the_target->supports_range_stepping) () : 0)
+#define target_supports_stopped_by_sw_breakpoint() \
+ (the_target->supports_stopped_by_sw_breakpoint ? \
+ (*the_target->supports_stopped_by_sw_breakpoint) () : 0)
+
+#define target_stopped_by_sw_breakpoint() \
+ (the_target->stopped_by_sw_breakpoint ? \
+ (*the_target->stopped_by_sw_breakpoint) () : 0)
+
+#define target_supports_stopped_by_hw_breakpoint() \
+ (the_target->supports_stopped_by_hw_breakpoint ? \
+ (*the_target->supports_stopped_by_hw_breakpoint) () : 0)
+
+#define target_stopped_by_hw_breakpoint() \
+ (the_target->stopped_by_hw_breakpoint ? \
+ (*the_target->stopped_by_hw_breakpoint) () : 0)
+
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);