From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 69173 invoked by alias); 28 Apr 2017 14:44:32 -0000 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 Received: (qmail 65144 invoked by uid 89); 28 Apr 2017 14:44:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.5 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=resumed X-HELO: mga04.intel.com Received: from mga04.intel.com (HELO mga04.intel.com) (192.55.52.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 28 Apr 2017 14:44:22 +0000 Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Apr 2017 07:44:21 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga004.jf.intel.com with ESMTP; 28 Apr 2017 07:44:20 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id v3SEiJb9026731; Fri, 28 Apr 2017 15:44:19 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id v3SEiJCu022638; Fri, 28 Apr 2017 16:44:19 +0200 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id v3SEiJAg022634; Fri, 28 Apr 2017 16:44:19 +0200 From: Markus Metzger To: gdb-patches@sourceware.org Subject: [PATCH 3/3] btrace: support decoder events Date: Fri, 28 Apr 2017 14:44:00 -0000 Message-Id: <1493390658-22342-3-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1493390658-22342-1-git-send-email-markus.t.metzger@intel.com> References: <1493390658-22342-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2017-04/txt/msg00781.txt.bz2 Newer versions of libipt support instruction flow decoder events instead of indicating those events with flags in struct pt_insn. Add support for them in GDB. 2017-04-28 Markus Metzger gdb/ * btrace.c (handle_pt_insn_events): New. (ftrace_add_pt): Call handle_pt_insn_events. Rename ERRCODE into STATUS. Split into this and ... (handle_pt_insn_event_flags): ... this. --- gdb/btrace.c | 174 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 127 insertions(+), 47 deletions(-) diff --git a/gdb/btrace.c b/gdb/btrace.c index 6780e22..21d0be9 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -1132,6 +1132,116 @@ pt_btrace_insn (const struct pt_insn &insn) pt_btrace_insn_flags (insn)}; } +/* Handle instruction decode events (libipt-v2). */ + +static int +handle_pt_insn_events (struct pt_insn_decoder *decoder, + struct btrace_function **pbegin, + struct btrace_function **pend, + VEC (bfun_s) **gaps, int status) +{ +#if defined (HAVE_PT_INSN_EVENT) + while (status & pts_event_pending) + { + struct pt_event event; + uint64_t offset; + + status = pt_insn_event (decoder, &event, sizeof (event)); + if (status < 0) + break; + + switch (event.type) + { + default: + break; + + case ptev_enabled: + if (*pbegin != NULL && event.variant.enabled.resumed == 0) + { + *pend = ftrace_new_gap (*pend, BDE_PT_DISABLED); + if (*pbegin == NULL) + *pbegin = *pend; + + VEC_safe_push (bfun_s, *gaps, *pend); + + pt_insn_get_offset (decoder, &offset); + + warning (_("Non-contiguous trace at instruction %u (offset = 0x%" + PRIx64 ")."), (*pend)->insn_offset - 1, offset); + } + + break; + + case ptev_overflow: + *pend = ftrace_new_gap (*pend, BDE_PT_OVERFLOW); + if (*pbegin == NULL) + *pbegin = *pend; + + VEC_safe_push (bfun_s, *gaps, *pend); + + pt_insn_get_offset (decoder, &offset); + + warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ")."), + (*pend)->insn_offset - 1, offset); + + break; + } + } +#endif /* defined (HAVE_PT_INSN_EVENT) */ + + return status; +} + +/* Handle events indicated by flags in INSN (libipt-v1). */ + +static void +handle_pt_insn_event_flags (struct pt_insn_decoder *decoder, + const struct pt_insn *insn, + struct btrace_function **pbegin, + struct btrace_function **pend, + VEC (bfun_s) **gaps) +{ +#if defined (HAVE_STRUCT_PT_INSN_ENABLED) + /* Tracing is disabled and re-enabled each time we enter the kernel. Most + times, we continue from the same instruction we stopped before. This is + indicated via the RESUMED instruction flag. The ENABLED instruction flag + means that we continued from some other instruction. Indicate this as a + trace gap except when tracing just started. */ + if (insn.enabled && (*begin != NULL)) + { + uint64_t offset; + + *end = ftrace_new_gap (*end, BDE_PT_DISABLED); + + VEC_safe_push (bfun_s, *gaps, *end); + + pt_insn_get_offset (decoder, &offset); + + warning (_("Non-contiguous trace at instruction %u (offset = 0x%" PRIx64 + ", pc = 0x%" PRIx64 ")."), (*end)->insn_offset - 1, offset, + insn.ip); + } +#endif /* defined (HAVE_STRUCT_PT_INSN_ENABLED) */ + +#if defined (HAVE_STRUCT_PT_INSN_RESYNCED) + /* Indicate trace overflows. */ + if (insn.resynced) + { + uint64_t offset; + + *end = ftrace_new_gap (*end, BDE_PT_OVERFLOW); + if (*begin == NULL) + *begin = *end; + + VEC_safe_push (bfun_s, *gaps, *end); + + pt_insn_get_offset (decoder, &offset); + + warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ", pc = 0x%" + PRIx64 ")."), (*end)->insn_offset - 1, offset, insn.ip); + } +#endif /* defined (HAVE_STRUCT_PT_INSN_RESYNCED) */ +} /* Add function branch trace using DECODER. */ @@ -1142,64 +1252,34 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, VEC (bfun_s) **gaps) { uint64_t offset; - int errcode; + int status; for (;;) { struct pt_insn insn; - errcode = pt_insn_sync_forward (decoder); - if (errcode < 0) + status = pt_insn_sync_forward (decoder); + if (status < 0) { - if (errcode != -pte_eos) + if (status != -pte_eos) warning (_("Failed to synchronize onto the Intel Processor " - "Trace stream: %s."), pt_errstr (pt_errcode (errcode))); + "Trace stream: %s."), pt_errstr (pt_errcode (status))); break; } for (;;) { - errcode = pt_insn_next (decoder, &insn, sizeof(insn)); - if (errcode < 0) + /* Handle events from the previous iteration or synchronization. */ + status = handle_pt_insn_events (decoder, begin, end, gaps, status); + if (status < 0) break; - /* Look for gaps in the trace - unless we're at the beginning. */ - if (*begin != NULL) - { - /* Tracing is disabled and re-enabled each time we enter the - kernel. Most times, we continue from the same instruction we - stopped before. This is indicated via the RESUMED instruction - flag. The ENABLED instruction flag means that we continued - from some other instruction. Indicate this as a trace gap. */ - if (insn.enabled) - { - *end = ftrace_new_gap (*end, BDE_PT_DISABLED); - - VEC_safe_push (bfun_s, *gaps, *end); - - pt_insn_get_offset (decoder, &offset); - - warning (_("Non-contiguous trace at instruction %u (offset " - "= 0x%" PRIx64 ", pc = 0x%" PRIx64 ")."), - (*end)->insn_offset - 1, offset, insn.ip); - } - } - - /* Indicate trace overflows. */ - if (insn.resynced) - { - *end = ftrace_new_gap (*end, BDE_PT_OVERFLOW); - if (*begin == NULL) - *begin = *end; - - VEC_safe_push (bfun_s, *gaps, *end); - - pt_insn_get_offset (decoder, &offset); + status = pt_insn_next (decoder, &insn, sizeof(insn)); + if (status < 0) + break; - warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 - ", pc = 0x%" PRIx64 ")."), (*end)->insn_offset - 1, - offset, insn.ip); - } + /* Handle events indicated by flags in INSN. */ + handle_pt_insn_event_flags (decoder, &insn, begin, end, gaps); *end = ftrace_update_function (*end, insn.ip); if (*begin == NULL) @@ -1212,11 +1292,11 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, ftrace_update_insns (*end, &btinsn); } - if (errcode == -pte_eos) + if (status == -pte_eos) break; /* Indicate the gap in the trace. */ - *end = ftrace_new_gap (*end, errcode); + *end = ftrace_new_gap (*end, status); if (*begin == NULL) *begin = *end; @@ -1225,9 +1305,9 @@ ftrace_add_pt (struct pt_insn_decoder *decoder, pt_insn_get_offset (decoder, &offset); warning (_("Decode error (%d) at instruction %u (offset = 0x%" PRIx64 - ", pc = 0x%" PRIx64 "): %s."), errcode, + ", pc = 0x%" PRIx64 "): %s."), status, (*end)->insn_offset - 1, offset, insn.ip, - pt_errstr (pt_errcode (errcode))); + pt_errstr (pt_errcode (status))); } } -- 1.8.3.1