From patchwork Thu Feb 26 00:17:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 5293 Received: (qmail 45434 invoked by alias); 26 Feb 2015 00:17:44 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 45378 invoked by uid 89); 26 Feb 2015 00:17:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 26 Feb 2015 00:17:41 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t1Q0Hemv019551 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 25 Feb 2015 19:17:40 -0500 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t1Q0HXwI000814 for ; Wed, 25 Feb 2015 19:17:39 -0500 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 6/8] gdbserver: Support the "swbreak"/"hwbreak" stop reasons Date: Thu, 26 Feb 2015 00:17:30 +0000 Message-Id: <1424909852-25917-7-git-send-email-palves@redhat.com> In-Reply-To: <1424909852-25917-1-git-send-email-palves@redhat.com> References: <1424909852-25917-1-git-send-email-palves@redhat.com> 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-02-25 Pedro Alves * remote-utils.c (prepare_resume_reply): Report swbreak/hbreak. * server.c (swbreak_feature, hwbreak_feature): New globals. (handle_query) : Handle "swbreak+" and "hwbreak+". (captured_main): Clear swbreak_feature and hwbreak_feature. * server.h (swbreak_feature, hwbreak_feature): Declare. * target.h (struct target_ops) : 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. --- gdb/gdbserver/remote-utils.c | 10 ++++++++++ gdb/gdbserver/server.c | 25 +++++++++++++++++++++++++ gdb/gdbserver/server.h | 11 +++++++++++ gdb/gdbserver/target.h | 31 +++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) 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);