From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12915 invoked by alias); 4 Mar 2013 17:07:31 -0000 Received: (qmail 12729 invoked by uid 22791); 4 Mar 2013 17:07:21 -0000 X-SWARE-Spam-Status: No, hits=-7.9 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_SPAMHAUS_DROP,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,TW_QB,TW_XS,TW_XZ X-Spam-Check-By: sourceware.org Received: from mga14.intel.com (HELO mga14.intel.com) (143.182.124.37) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 04 Mar 2013 17:06:31 +0000 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga102.ch.intel.com with ESMTP; 04 Mar 2013 09:06:20 -0800 X-ExtLoop1: 1 Received: from swsutil001.isw.intel.com ([10.237.237.11]) by AZSMGA002.ch.intel.com with ESMTP; 04 Mar 2013 09:06:18 -0800 Received: from ulslx001.iul.intel.com (ulslx001.iul.intel.com [172.28.207.63]) by swsutil001.isw.intel.com (8.13.6/8.13.6/MailSET/Hub) with ESMTP id r24H6Cn1004054; Mon, 4 Mar 2013 17:06:13 GMT Received: from ulslx001.iul.intel.com (localhost [127.0.0.1]) by ulslx001.iul.intel.com with ESMTP id r24H6CUI020040; Mon, 4 Mar 2013 18:06:12 +0100 Received: (from mmetzger@localhost) by ulslx001.iul.intel.com with id r24H6C2P020036; Mon, 4 Mar 2013 18:06:12 +0100 From: Markus Metzger To: jan.kratochvil@redhat.com Cc: gdb-patches@sourceware.org, markus.t.metzger@gmail.com Subject: [patch v9 05/23] remote, btrace: add branch trace remote ops Date: Mon, 04 Mar 2013 17:07:00 -0000 Message-Id: <1362416770-19750-6-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1362416770-19750-1-git-send-email-markus.t.metzger@intel.com> References: <1362416770-19750-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2013-03/txt/msg00100.txt.bz2 Add the gdb remote target operations for branch tracing. We define the following packets: qbtrace query the current thread if new trace data is available returns "yes" or "no" or "Enn" Qbtrace:on enable branch tracing for the current thread returns "OK" or "Enn" Qbtrace:off disable branch tracing for the current thread returns "OK" or "Enn" qXfer:btrace:read read the full branch trace data for the current thread 2013-03-04 Markus Metzger * target.h (enum target_object): Add TARGET_OBJECT_BTRACE. * remote.c: Include btrace.h. (struct btrace_target_info): New struct. (remote_supports_btrace): New function. (send_Qbtrace): New function. (remote_enable_btrace): New function. (remote_disable_btrace): New function. (remote_btrace_has_changed): New function. (remote_read_btrace): New function. (init_remote_ops): Add btrace ops. (enum ): Add btrace packets. (struct protocol_feature remote_protocol_features[]): Add btrace packets. (_initialize_remote): Add packet configuration for branch tracing. --- gdb/remote.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/target.h | 4 +- 2 files changed, 181 insertions(+), 1 deletions(-) mode change 100644 => 100755 gdb/remote.c diff --git a/gdb/remote.c b/gdb/remote.c old mode 100644 new mode 100755 index 88a57c8..787c596 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -68,6 +68,7 @@ #include "ax.h" #include "ax-gdb.h" #include "agent.h" +#include "btrace.h" /* Temp hacks for tracepoint encoding migration. */ static char *target_buf; @@ -1284,6 +1285,9 @@ enum { PACKET_qXfer_fdpic, PACKET_QDisableRandomization, PACKET_QAgent, + PACKET_qbtrace, + PACKET_Qbtrace, + PACKET_qXfer_btrace, PACKET_MAX }; @@ -3995,6 +3999,10 @@ static struct protocol_feature remote_protocol_features[] = { { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent}, { "tracenz", PACKET_DISABLE, remote_string_tracing_feature, -1 }, + { "qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_qbtrace }, + { "Qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace }, + { "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet, + PACKET_qXfer_btrace } }; static char *remote_support_xml; @@ -8796,6 +8804,10 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len, &remote_protocol_packets[PACKET_qXfer_uib]); + case TARGET_OBJECT_BTRACE: + return remote_read_qxfer (ops, "btrace", annex, readbuf, offset, len, + &remote_protocol_packets[PACKET_qXfer_btrace]); + default: return -1; } @@ -11115,6 +11127,158 @@ remote_can_use_agent (void) return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE); } +struct btrace_target_info +{ + /* The ptid of the traced thread. */ + ptid_t ptid; +}; + +/* Check whether the target supports branch tracing. */ + +static int +remote_supports_btrace (void) +{ + if (remote_protocol_packets[PACKET_qbtrace].support != PACKET_ENABLE) + return 0; + if (remote_protocol_packets[PACKET_Qbtrace].support != PACKET_ENABLE) + return 0; + if (remote_protocol_packets[PACKET_qXfer_btrace].support != PACKET_ENABLE) + return 0; + + return 1; +} + +/* Send the Qbtrace packet and check the response. */ + +static void +send_Qbtrace (ptid_t ptid, int enable) +{ + struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace]; + struct remote_state *rs = get_remote_state (); + char *buf = rs->buf; + char *endbuf = rs->buf + get_remote_packet_size (); + + if (packet->support != PACKET_ENABLE) + error (_("Target does not support branch tracing.")); + + set_general_thread (ptid); + + buf += xsnprintf (buf, endbuf - buf, "%s:", packet->name); + buf += xsnprintf (buf, endbuf - buf, enable ? "on" : "off"); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + + if (packet_ok (rs->buf, packet) == PACKET_ERROR) + { + if (enable != 0) + error (_("Could not enable branch tracing for %s: %s"), + target_pid_to_str (ptid), rs->buf); + else + error (_("Could not disable branch tracing for %s: %s"), + target_pid_to_str (ptid), rs->buf); + } +} + +/* Enable branch tracing. */ + +static struct btrace_target_info * +remote_enable_btrace (ptid_t ptid) +{ + struct btrace_target_info *tinfo = NULL; + + /* This will throw an error if enabling failed. */ + send_Qbtrace (ptid, 1); + + tinfo = xzalloc (sizeof (*tinfo)); + tinfo->ptid = ptid; + + return tinfo; +} + +/* Disable branch tracing. */ + +static void +remote_disable_btrace (struct btrace_target_info *tinfo) +{ + /* This will throw an error if disabling failed. */ + send_Qbtrace (tinfo->ptid, 0); + + xfree (tinfo); +} + +/* Check whether branch trace data has changed. */ + +static int +remote_btrace_has_changed (struct btrace_target_info *tinfo) +{ + struct packet_config *packet = &remote_protocol_packets[PACKET_qbtrace]; + struct remote_state *rs = get_remote_state (); + char *buf = rs->buf; + char *endbuf = rs->buf + get_remote_packet_size (); + + if (packet->support != PACKET_ENABLE) + error (_("Target does not support branch tracing.")); + + set_general_thread (tinfo->ptid); + + buf += xsnprintf (buf, endbuf - buf, "%s", packet->name); + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + + switch (packet_ok (rs->buf, packet)) + { + case PACKET_OK: + break; + + case PACKET_UNKNOWN: + return 0; + + case PACKET_ERROR: + error (_("Failed to check for branch trace data for %s: %s."), + target_pid_to_str (tinfo->ptid), rs->buf); + } + + if (strcmp (rs->buf, "yes") == 0) + return 1; + + if (strcmp (rs->buf, "no") == 0) + return 0; + + error (_("Bad remote reply: %s."), rs->buf); + + return 0; +} + +/* Read the branch trace. */ + +static VEC (btrace_block_s) * +remote_read_btrace (struct btrace_target_info *tinfo) +{ + struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace]; + struct remote_state *rs = get_remote_state (); + VEC (btrace_block_s) *btrace = NULL; + char *xml; + + if (packet->support != PACKET_ENABLE) + error (_("Target does not support branch tracing.")); + +#if !defined(HAVE_LIBEXPAT) + error (_("Cannot process branch tracing result. XML parsing not supported.")); +#endif + + xml = target_read_stralloc (¤t_target, + TARGET_OBJECT_BTRACE, NULL); + if (xml != NULL) + { + struct cleanup *cleanup = make_cleanup (xfree, xml); + + btrace = parse_xml_btrace (xml); + do_cleanups (cleanup); + } + + return btrace; +} + static void init_remote_ops (void) { @@ -11231,6 +11395,11 @@ Specify the serial device it is connected to\n\ remote_ops.to_traceframe_info = remote_traceframe_info; remote_ops.to_use_agent = remote_use_agent; remote_ops.to_can_use_agent = remote_can_use_agent; + remote_ops.to_supports_btrace = remote_supports_btrace; + remote_ops.to_enable_btrace = remote_enable_btrace; + remote_ops.to_disable_btrace = remote_disable_btrace; + remote_ops.to_btrace_has_changed = remote_btrace_has_changed; + remote_ops.to_read_btrace = remote_read_btrace; } /* Set up the extended remote vector by making a copy of the standard @@ -11755,6 +11924,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent], "QAgent", "agent", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_qbtrace], + "qbtrace", "query-btrace", 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace], + "Qbtrace", "enable-btrace", 0); + + add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace], + "qXfer:btrace", "read-btrace", 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 diff --git a/gdb/target.h b/gdb/target.h index 628c108..c543118 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -287,7 +287,9 @@ enum target_object /* Darwin dynamic linker info data. */ TARGET_OBJECT_DARWIN_DYLD_INFO, /* OpenVMS Unwind Information Block. */ - TARGET_OBJECT_OPENVMS_UIB + TARGET_OBJECT_OPENVMS_UIB, + /* Branch trace data, in XML format. */ + TARGET_OBJECT_BTRACE /* Possible future objects: TARGET_OBJECT_FILE, ... */ }; -- 1.7.1