This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] gdbserver: Support the "swbreak"/"hwbreak" stop reasons


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1ec68e26c982a256df03d22dce072b88ab117a73

commit 1ec68e26c982a256df03d22dce072b88ab117a73
Author: Pedro Alves <palves@redhat.com>
Date:   Wed Mar 4 20:41:16 2015 +0000

    gdbserver: Support the "swbreak"/"hwbreak" stop reasons
    
    This patch teaches the core of gdbserver about the new "swbreak" and
    "hwbreak" stop reasons, and adds the necessary hooks a backend needs
    to implement to support the feature.
    
    gdb/gdbserver/ChangeLog:
    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.

Diff:
---
 gdb/gdbserver/ChangeLog      | 15 +++++++++++++++
 gdb/gdbserver/remote-utils.c | 10 ++++++++++
 gdb/gdbserver/server.c       | 25 +++++++++++++++++++++++++
 gdb/gdbserver/server.h       | 11 +++++++++++
 gdb/gdbserver/target.h       | 31 +++++++++++++++++++++++++++++++
 5 files changed, 92 insertions(+)

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 156fcc8..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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]