From patchwork Fri Oct 21 12:02:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Willgerodt, Felix" X-Patchwork-Id: 59284 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5B7433856974 for ; Fri, 21 Oct 2022 12:07:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B7433856974 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1666354030; bh=5uSnt53DhZVjGDBm6cUmnaXSS0iKhu0tK7JOotbkHuU=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=huJYzQ9jiYEhkRZhnfvzjCHuRjeNemvp/5i0viCWX/JCL1DgbBXP9swqBsxd9RHUR wfDgJrn3hAm3AAnAKh1Jx/sWqSAx3gOBMuCvPyPJwROmur7tE4CNiCTT8kg3PLrTZO +U2J7rrZd29LmaqkmOKv1JHoSHSEB075YuhccZxA= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by sourceware.org (Postfix) with ESMTPS id F3AFD385276F for ; Fri, 21 Oct 2022 12:04:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F3AFD385276F X-IronPort-AV: E=McAfee;i="6500,9779,10506"; a="308675567" X-IronPort-AV: E=Sophos;i="5.95,200,1661842800"; d="scan'208";a="308675567" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2022 05:04:04 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10506"; a="630458579" X-IronPort-AV: E=Sophos;i="5.95,200,1661842800"; d="scan'208";a="630458579" Received: from mulvlfelix.iul.intel.com (HELO localhost) ([172.28.48.92]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2022 05:04:02 -0700 To: gdb-patches@sourceware.org, markus.t.metzger@intel.com Subject: [PATCH v7 10/10] btrace: Extend ptwrite event decoding. Date: Fri, 21 Oct 2022 14:02:16 +0200 Message-Id: <20221021120216.359754-1-felix.willgerodt@intel.com> X-Mailer: git-send-email 2.34.3 MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Felix Willgerodt via Gdb-patches From: "Willgerodt, Felix" Reply-To: Felix Willgerodt Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Call the ptwrite filter function whenever a ptwrite event is decoded. The returned string is written to the aux_data string table and a corresponding auxiliary instruction is appended to the function segment. --- gdb/NEWS | 7 + gdb/btrace.c | 54 +++ gdb/config.in | 3 + gdb/configure | 11 + gdb/doc/python.texi | 150 ++++++ gdb/testsuite/gdb.btrace/i386-ptwrite.S | 550 ++++++++++++++++++++++ gdb/testsuite/gdb.btrace/ptwrite.c | 39 ++ gdb/testsuite/gdb.btrace/ptwrite.exp | 209 ++++++++ gdb/testsuite/gdb.btrace/x86_64-ptwrite.S | 544 +++++++++++++++++++++ gdb/testsuite/lib/gdb.exp | 74 +++ gdbsupport/common.m4 | 2 + gdbsupport/config.in | 3 + gdbsupport/configure | 11 + 13 files changed, 1657 insertions(+) create mode 100644 gdb/testsuite/gdb.btrace/i386-ptwrite.S create mode 100644 gdb/testsuite/gdb.btrace/ptwrite.c create mode 100644 gdb/testsuite/gdb.btrace/ptwrite.exp create mode 100644 gdb/testsuite/gdb.btrace/x86_64-ptwrite.S diff --git a/gdb/NEWS b/gdb/NEWS index 8b519a648f7..4d6fe4e951f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,13 @@ *** Changes since GDB 12 +* GDB now supports printing of ptwrite payloads from the Intel Processor + Trace during 'record instruction-history', 'record function-call-history' + and all stepping commands. The payload is also accessible in Python as a + RecordAuxiliary object. Printing is customizable via a ptwrite filter + function in Python. By default, the raw ptwrite payload is printed for + each ptwrite that is encountered. + * GDB now supports dumping memory tag data for AArch64 MTE. It also supports reading memory tag data for AArch64 MTE from core files generated by the gcore command or the Linux kernel. diff --git a/gdb/btrace.c b/gdb/btrace.c index e6ded61883b..97bcf1721f1 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -1253,6 +1253,54 @@ handle_pt_insn_events (struct btrace_thread_info *btinfo, bfun->insn_offset - 1, offset); break; +#if defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) + case ptev_ptwrite: + { + uint64_t ip = 0; + std::string ptw_string; + btrace_insn_flags flags = 0; + + /* Lookup the ip if available. */ + if (event.ip_suppressed == 0) + ip = event.variant.ptwrite.ip; + + if (btinfo->ptw_callback_fun != nullptr) + ptw_string + = btinfo->ptw_callback_fun (event.variant.ptwrite.payload, + ip, btinfo->ptw_context); + + if (ptw_string.empty ()) + break; + + btinfo->aux_data.emplace_back (ptw_string); + + if (!btinfo->functions.empty () + && !btinfo->functions.back ().insn.empty ()) + flags = btinfo->functions.back ().insn.back ().flags; + + /* Update insn list with ptw payload insn. */ + struct btrace_insn ptw_insn; + ptw_insn.aux_data_index = btinfo->aux_data.size () - 1; + ptw_insn.size = 0; + ptw_insn.iclass = BTRACE_INSN_AUX; + ptw_insn.flags = flags; + + if (ip != 0) + bfun = ftrace_update_function (btinfo, ip); + else + { + if (btinfo->functions.empty ()) + bfun = ftrace_new_function (btinfo, NULL, NULL); + else + bfun = &btinfo->functions.back (); + } + + bfun->flags |= BFUN_CONTAINS_AUX; + ftrace_update_insns (bfun, ptw_insn); + + break; + } +#endif /* defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) */ } } #endif /* defined (HAVE_PT_INSN_EVENT) */ @@ -2981,6 +3029,12 @@ pt_print_packet (const struct pt_packet *packet) case ppt_mnt: gdb_printf (("mnt %" PRIx64 ""), packet->payload.mnt.payload); break; + +#if defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) + case ppt_ptw: + gdb_printf (("ptw %" PRIx64 ""), packet->payload.ptw.payload); + break; +#endif /* defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) */ } } diff --git a/gdb/config.in b/gdb/config.in index e13a409ec2d..c9e5d0d9197 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -460,6 +460,9 @@ /* Define to 1 if `pl_tdname' is a member of `struct ptrace_lwpinfo'. */ #undef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME +/* Define to 1 if `variant.ptwrite' is a member of `struct pt_event'. */ +#undef HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE + /* Define to 1 if `enabled' is a member of `struct pt_insn'. */ #undef HAVE_STRUCT_PT_INSN_ENABLED diff --git a/gdb/configure b/gdb/configure index 33677262783..4fd5a09532c 100755 --- a/gdb/configure +++ b/gdb/configure @@ -15480,6 +15480,17 @@ cat >>confdefs.h <<_ACEOF _ACEOF +fi + + ac_fn_c_check_member "$LINENO" "struct pt_event" "variant.ptwrite" "ac_cv_member_struct_pt_event_variant_ptwrite" "#include +" +if test "x$ac_cv_member_struct_pt_event_variant_ptwrite" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE 1 +_ACEOF + + fi LIBS=$save_LIBS diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 2820e4d56e3..2a2d68ced5c 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -7117,6 +7117,7 @@ registering objfile-specific pretty-printers and frame-filters. * gdb.printing:: Building and registering pretty-printers. * gdb.types:: Utilities for working with types. * gdb.prompt:: Utilities for prompt value substitution. +* gdb.ptwrite:: Utilities for PTWRITE filter registration. @end menu @node gdb.printing @@ -7307,3 +7308,152 @@ substitute_prompt ("frame: \f, args: \p@{print frame-arguments@}") "frame: main, args: scalars" @end smallexample @end table + +@node gdb.ptwrite +@subsubsection gdb.ptwrite +@cindex gdb.ptwrite + +This module provides additional functionality for recording programs that +make use of the @code{PTWRITE} instruction. @code{PTWRITE} is a x86 +instruction that allows to write values into the Intel Processor Trace +(@pxref{Process Record and Replay}). +The @value{NGCC} built-in functions for it are: +@smallexample +void __builtin_ia32_ptwrite32 (unsigned); +void __builtin_ia32_ptwrite64 (unsigned long long); +@end smallexample + +If an inferior uses the instruction, @value{GDBN} by default inserts the +raw payload value as auxiliary information into the execution history. +Auxiliary information is by default printed during +@code{record instruction-history}, @code{record function-call-history}, +and all stepping commands, and is accessible in Python as a +@code{RecordAuxiliary} object. + +@exdent Sample program: +@smallexample +@group +void +ptwrite64 (unsigned long long value) +@{ + __builtin_ia32_ptwrite64 (value); +@} +@end group + +@group +int +main (void) +@{ + ptwrite64 (0x42); + return 0; /* break here. */ +@} +@end group +@end smallexample + + +@exdent @value{GDBN} output after recording the sample program in pt format: +@smallexample +@group +(gdb) record instruction-history 12,14 +12 0x0040074c : ptwrite %rbx +13 [42] +14 0x00400751 : mov -0x8(%rbp),%rbx +(gdb) record function-call-history +1 main +2 ptwrite64 + [42] +3 main +@end group +@end smallexample + +The @code{gdb.ptwrite} module allows customizing the default output of +@code{PTWRITE} auxiliary information. A custom Python function can be +registered via @code{gdb.ptwrite.register_filter} as the @code{PTWRITE} +filter function. This function will be called with the @code{PTWRITE} +payload and PC as arguments during trace decoding. + +@findex gdb.ptwrite.register_filter +@defun register_filter (@var{filter}) +Used to register the @code{PTWRITE} filter. The filter can be any callable +object that accepts two arguments, the payload and PC. It can return +a string, which will be printed by @value{GDBN} during the aforementioned +commands, or @code{None}, resulting in no output. @code{None} can also be +registered to deactivate printing. +@end defun + +@findex gdb.ptwrite.get_filter +@defun get_filter () +Return the currently active @code{PTWRITE} filter function. +@end defun + +@findex gdb.ptwrite.default_filter +@defun default_filter (@var{payload}, @var{ip}) +The filter function active by default. It prints the payload in hexadecimal +format. +@end defun + +@value{GDBN} creates a new copy of the filter function for each thread to +allow for independent internal states. There is no support for registering +different filters for different threads. The filter can however +distinguish between multiple threads with the help of +@code{gdb.selected_thread().global_num} (@pxref{Threads In Python}) or +similar. For example: + +@smallexample +@group +(gdb) python-interactive +>>> class my_filter(): +... def __init__(self): +... self.var = 0 +... def __call__(self, payload, ip): +... if gdb.selected_thread().global_num == 1: +... self.var += 1 +... return f"counter: @{self.var@}, ip: @{ip:#x@}" +... else: +... return None +... +>>> import gdb.ptwrite +>>> gdb.ptwrite.register_filter(my_filter()) +>>> +@end group + +@group +(gdb) record function-call-history 59,64 +59 pthread_create@@GLIBC_2.2.5 +60 job() +61 task(void*) +62 ptwrite64(unsigned long) + [counter: 1, ip: 0x401156] +63 task(void*) +64 ptwrite32(unsigned int) + [counter: 2, ip: 0x40116c] +@end group + +@group +(gdb) info threads +* 1 Thread 0x7ffff7fd8740 (LWP 25796) "ptw_threads" task () + at bin/ptwrite/ptw_threads.c:45 + 2 Thread 0x7ffff6eb8700 (LWP 25797) "ptw_threads" task () + at bin/ptwrite/ptw_threads.c:45 +@end group + +@group +(gdb) thread 2 +[Switching to thread 2 (Thread 0x7ffff6eb8700 (LWP 25797))] +#0 task (arg=0x0) at ptwrite_threads.c:45 +45 return NULL; +@end group + +@group +(gdb) record function-call-history 10,14 +10 start_thread +11 task(void*) +12 ptwrite64(unsigned long) +13 task(void*) +14 ptwrite32(unsigned int) +@end group +@end smallexample + +This @value{GDBN} feature is dependent on hardware and operating system +support and requires the Intel Processor Trace decoder library in version +2.0.0 or newer. diff --git a/gdb/testsuite/gdb.btrace/i386-ptwrite.S b/gdb/testsuite/gdb.btrace/i386-ptwrite.S new file mode 100644 index 00000000000..efafb4b847b --- /dev/null +++ b/gdb/testsuite/gdb.btrace/i386-ptwrite.S @@ -0,0 +1,550 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2022 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + This file has been generated using gcc version 10.3.1 20210422 + (Red Hat 10.3.1-1): + gcc -S -dA -g -m32 -mptwrite ptwrite.c -o i386-ptwrite.S. */ + + + .file "ptwrite.c" + .text +.Ltext0: + .globl ptwrite1 + .type ptwrite1, @function +ptwrite1: +.LFB4021: + .file 1 "ptwrite.c" + # ptwrite.c:22:1 + .loc 1 22 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + # ptwrite.c:23:3 + .loc 1 23 3 + movl 8(%ebp), %eax + movl %eax, -4(%ebp) +.LBB6: +.LBB7: + .file 2 "/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h" + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%ebp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE7: +.LBE6: + # ptwrite.c:24:1 + .loc 1 24 1 + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4021: + .size ptwrite1, .-ptwrite1 + .globl ptwrite2 + .type ptwrite2, @function +ptwrite2: +.LFB4022: + # ptwrite.c:28:1 + .loc 1 28 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + # ptwrite.c:29:3 + .loc 1 29 3 + movl 8(%ebp), %eax + movl %eax, -4(%ebp) +.LBB8: +.LBB9: + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%ebp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE9: +.LBE8: + # ptwrite.c:30:1 + .loc 1 30 1 + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4022: + .size ptwrite2, .-ptwrite2 + .globl main + .type main, @function +main: +.LFB4023: + # ptwrite.c:34:1 + .loc 1 34 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + # ptwrite.c:35:3 + .loc 1 35 3 + pushl $66 + call ptwrite1 + addl $4, %esp + # ptwrite.c:36:3 + .loc 1 36 3 + pushl $67 + call ptwrite2 + addl $4, %esp + # ptwrite.c:38:10 + .loc 1 38 10 + movl $0, %eax + # ptwrite.c:39:1 + .loc 1 39 1 + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4023: + .size main, .-main +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0x129 # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x4 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF15 # DW_AT_producer: "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -m32 -mptwrite -mtune=generic -march=i686 -g" + .byte 0xc # DW_AT_language + .long .LASF16 # DW_AT_name: "ptwrite.c" + .long .LASF17 # DW_AT_comp_dir: "gdb/gdb/testsuite/gdb.btrace" + .long .Ltext0 # DW_AT_low_pc + .long .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x25) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x3 # (DIE (0x2c) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF0 # DW_AT_name: "short int" + .uleb128 0x3 # (DIE (0x33) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF1 # DW_AT_name: "char" + .uleb128 0x3 # (DIE (0x3a) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF2 # DW_AT_name: "long long int" + .uleb128 0x3 # (DIE (0x41) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF3 # DW_AT_name: "float" + .uleb128 0x3 # (DIE (0x48) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF4 # DW_AT_name: "unsigned int" + .uleb128 0x3 # (DIE (0x4f) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF5 # DW_AT_name: "long int" + .uleb128 0x3 # (DIE (0x56) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x8 # DW_AT_encoding + .long .LASF6 # DW_AT_name: "unsigned char" + .uleb128 0x3 # (DIE (0x5d) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF7 # DW_AT_name: "short unsigned int" + .uleb128 0x3 # (DIE (0x64) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF8 # DW_AT_name: "long unsigned int" + .uleb128 0x3 # (DIE (0x6b) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF9 # DW_AT_name: "signed char" + .uleb128 0x3 # (DIE (0x72) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF10 # DW_AT_name: "long long unsigned int" + .uleb128 0x3 # (DIE (0x79) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF11 # DW_AT_name: "double" + .uleb128 0x4 # (DIE (0x80) DW_TAG_subprogram) + # DW_AT_external + .long .LASF18 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x21 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long 0x25 # DW_AT_type + .long .LFB4023 # DW_AT_low_pc + .long .LFE4023-.LFB4023 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_tail_call_sites + .uleb128 0x5 # (DIE (0x96) DW_TAG_subprogram) + # DW_AT_external + .long .LASF12 # DW_AT_name: "ptwrite2" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long .LFB4022 # DW_AT_low_pc + .long .LFE4022-.LFB4022 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0xd5 # DW_AT_sibling + .uleb128 0x6 # (DIE (0xac) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x25 # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 0 + .uleb128 0x7 # (DIE (0xbb) DW_TAG_inlined_subroutine) + .long 0x114 # DW_AT_abstract_origin + .long .LBB8 # DW_AT_low_pc + .long .LBE8-.LBB8 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x1d # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0xcb) DW_TAG_formal_parameter) + .long 0x11e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -12 + .byte 0 # end of children of DIE 0xbb + .byte 0 # end of children of DIE 0x96 + .uleb128 0x5 # (DIE (0xd5) DW_TAG_subprogram) + # DW_AT_external + .long .LASF13 # DW_AT_name: "ptwrite1" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long .LFB4021 # DW_AT_low_pc + .long .LFE4021-.LFB4021 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0x114 # DW_AT_sibling + .uleb128 0x6 # (DIE (0xeb) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x25 # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 0 + .uleb128 0x7 # (DIE (0xfa) DW_TAG_inlined_subroutine) + .long 0x114 # DW_AT_abstract_origin + .long .LBB6 # DW_AT_low_pc + .long .LBE6-.LBB6 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x17 # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0x10a) DW_TAG_formal_parameter) + .long 0x11e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -12 + .byte 0 # end of children of DIE 0xfa + .byte 0 # end of children of DIE 0xd5 + .uleb128 0x9 # (DIE (0x114) DW_TAG_subprogram) + # DW_AT_external + .long .LASF19 # DW_AT_name: "_ptwrite32" + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .byte 0x3 # DW_AT_inline + # DW_AT_artificial + .uleb128 0xa # (DIE (0x11e) DW_TAG_formal_parameter) + .ascii "__B\0" # DW_AT_name + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x16 # DW_AT_decl_column + .long 0x48 # DW_AT_type + .byte 0 # end of children of DIE 0x114 + .byte 0 # end of children of DIE 0xb + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0 # DW_children_no + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x1d # (TAG: DW_TAG_inlined_subroutine) + .byte 0x1 # DW_children_yes + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x58 # (DW_AT_call_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x59 # (DW_AT_call_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x57 # (DW_AT_call_column) + .uleb128 0xb # (DW_FORM_data1) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x20 # (DW_AT_inline) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x34 # (DW_AT_artificial) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .long 0x1c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x4 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 8 byte boundary + .value 0 + .long .Ltext0 # Address + .long .Letext0-.Ltext0 # Length + .long 0 + .long 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF2: + .string "long long int" +.LASF14: + .string "value" +.LASF19: + .string "_ptwrite32" +.LASF4: + .string "unsigned int" +.LASF17: + .string "gdb/gdb/testsuite/gdb.btrace" +.LASF18: + .string "main" +.LASF16: + .string "ptwrite.c" +.LASF8: + .string "long unsigned int" +.LASF10: + .string "long long unsigned int" +.LASF13:/ + .string "ptwrite1" +.LASF12: + .string "ptwrite2" +.LASF6: + .string "unsigned char" +.LASF1: + .string "char" +.LASF5: + .string "long int" +.LASF15: + .string "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -m32 -mptwrite -mtune=generic -march=i686 -g" +.LASF11: + .string "double" +.LASF7: + .string "short unsigned int" +.LASF9: + .string "signed char" +.LASF3: + .string "float" +.LASF0: + .string "short int" + .ident "GCC: (GNU) 10.3.1 20210422 (Red Hat 10.3.1-1)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.btrace/ptwrite.c b/gdb/testsuite/gdb.btrace/ptwrite.c new file mode 100644 index 00000000000..c85b656919b --- /dev/null +++ b/gdb/testsuite/gdb.btrace/ptwrite.c @@ -0,0 +1,39 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2021 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +void +ptwrite1 (int value) +{ + _ptwrite32 (value); +} + +void +ptwrite2 (int value) +{ + _ptwrite32 (value); +} + +int +main (void) +{ + ptwrite1 (0x42); + ptwrite2 (0x43); + + return 0; +} diff --git a/gdb/testsuite/gdb.btrace/ptwrite.exp b/gdb/testsuite/gdb.btrace/ptwrite.exp new file mode 100644 index 00000000000..569760087a4 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/ptwrite.exp @@ -0,0 +1,209 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2021 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib gdb-python.exp + +if { [skip_btrace_ptw_tests] } { + unsupported "No support for ptwrite decoding." + return -1 +} + +set opts {} + +if [info exists COMPILE] { + # make check RUNTESTFLAGS="gdb.btrace/ptwrite.exp COMPILE=1" + standard_testfile ptwrite.c + lappend opts debug additional_flags=-mptwrite +} elseif {[istarget "i?86-*-*"] || [istarget "x86_64-*-*"]} { + if {[is_amd64_regs_target]} { + standard_testfile x86_64-ptwrite.S + } else { + standard_testfile i386-ptwrite.S + } +} else { + unsupported "target architecture not supported" + return -1 +} + +if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] { + return -1 +} + +if { ![runto_main] } { + untested "failed to run to main" + return -1 +} + +# This needs to be after runto_main +if { [skip_python_tests] } { + unsupported "Configuration doesn't support python scripting." + return -1 +} + +### 1. Default testrun + +# Setup recording +gdb_test_no_output "set record instruction-history-size unlimited" +gdb_test_no_output "record btrace pt" +gdb_test "next" ".*" "next" +gdb_test "next" ".*" "next 2" + +with_test_prefix "Default" { + # Test record instruction-history + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[42\\\]" \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[43\\\].*" \ + ] + + gdb_test "record instruction-history /a 1" [multi_line \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+.*" \ + ] + + # Test function call history + gdb_test "record function-call-history 1,4" [multi_line \ + "1\tmain" \ + "2\tptwrite1" \ + "\t\t\\\[42\\\]" \ + "3\tmain" \ + "4\tptwrite2" \ + "\t\t\\\[43\\\]" \ + ] + + gdb_test "record function-call-history /a 1,4" [multi_line \ + "1\tmain" \ + "2\tptwrite1" \ + "3\tmain" \ + "4\tptwrite2" \ + ] +} + +# Test payload printing during stepping +with_test_prefix "Stepping" { + gdb_test "record goto 10" "No such instruction\." + gdb_test "record goto 9" ".*ptwrite.* at .*" + gdb_test "stepi" ".*\\\[42\\\].*" + gdb_test "reverse-stepi" ".*\\\[42\\\].*" + gdb_test "continue" [multi_line \ + ".*\\\[42\\\]" \ + "\\\[43\\\].*" \ + ] + gdb_test "reverse-continue" [multi_line \ + ".*\\\[43\\\]" \ + "\\\[42\\\].*" \ + ] +} + +# Test auxiliary type in python +gdb_test_multiline "auxiliary type in python" \ + "python" "" \ + "h = gdb.current_recording().instruction_history" "" \ + "for insn in h:" "" \ + " if hasattr(insn, 'decoded'):" "" \ + " print(insn.decoded.decode())" "" \ + " elif hasattr(insn, 'data'):" "" \ + " print(insn.data)" "" \ + "end" \ + [multi_line \ + ".*mov -0x4\\\(%(e|r)bp\\\),%(e|r)ax" \ + "ptwrite %eax" \ + "42" \ + "nop.*" \ + "mov -0x4\\\(%(e|r)bp\\\),%(e|r)ax" \ + "ptwrite %eax" \ + "43" \ + "nop.*" + ] + + +### 2. Test filter registration +### 2.1 Custom filter +with_test_prefix "Custom" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "def my_filter(payload, ip):" "" \ + " if payload == 66:" "" \ + " return \"payload: {0}, ip: {1:#x}\".format(payload, ip)" "" \ + " else:" "" \ + " return None" "" \ + "import gdb.ptwrite" "" \ + "gdb.ptwrite.register_filter(my_filter)" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[payload: 66, ip: $hex\\\]" \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t $hex :.*" \ + ] +} + +### 2.2 None as filter +with_test_prefix "None" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "import gdb.ptwrite" "" \ + "gdb.ptwrite.register_filter(None)" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t $hex :.*" \ + "\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t $hex :.*" \ + ] +} + +### 2.3 Lambdas as filter +with_test_prefix "Lambdas" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "import gdb.ptwrite" "" \ + "gdb.ptwrite.register_filter(lambda payload, ip: \"{}\".format(payload + 2))" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[68\\\]" \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[69\\\].*" \ + ] "Lambdas: record instruction-history 1" +} + +### 2.4 Functors as filter +with_test_prefix "Functors" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "import gdb.ptwrite" "" \ + "class foobar(object):" "" \ + " def __init__(self):" "" \ + " self.variable = 0" "" \ + " def __call__(self, payload, ip):" "" \ + " self.variable += 1" "" \ + " return \"{}, {}\".format(self.variable, payload)" "" \ + "gdb.ptwrite.register_filter(foobar())" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[1, 66\\\]" \ + ".*\[0-9\]+\t $hex :\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[2, 67\\\].*" \ + ] "Functors: record instruction-history 1" +} diff --git a/gdb/testsuite/gdb.btrace/x86_64-ptwrite.S b/gdb/testsuite/gdb.btrace/x86_64-ptwrite.S new file mode 100644 index 00000000000..6fe64013399 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/x86_64-ptwrite.S @@ -0,0 +1,544 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2022 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + This file has been generated using gcc version 10.3.1 20210422 + (Red Hat 10.3.1-1): + gcc -S -dA -g -mptwrite ptwrite.c -o x86_64-ptwrite.S. */ + + .file "ptwrite.c" + .text +.Ltext0: + .globl ptwrite1 + .type ptwrite1, @function +ptwrite1: +.LFB4096: + .file 1 "ptwrite.c" + # ptwrite.c:22:1 + .loc 1 22 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + # ptwrite.c:23:3 + .loc 1 23 3 + movl -20(%rbp), %eax + movl %eax, -4(%rbp) +.LBB6: +.LBB7: + .file 2 "/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h" + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%rbp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE7: +.LBE6: + # ptwrite.c:24:1 + .loc 1 24 1 + nop + popq %rbp + .cfi_def_cfa 7, 8 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4096: + .size ptwrite1, .-ptwrite1 + .globl ptwrite2 + .type ptwrite2, @function +ptwrite2: +.LFB4097: + # ptwrite.c:28:1 + .loc 1 28 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + # ptwrite.c:29:3 + .loc 1 29 3 + movl -20(%rbp), %eax + movl %eax, -4(%rbp) +.LBB8: +.LBB9: + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%rbp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE9: +.LBE8: + # ptwrite.c:30:1 + .loc 1 30 1 + nop + popq %rbp + .cfi_def_cfa 7, 8 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4097: + .size ptwrite2, .-ptwrite2 + .globl main + .type main, @function +main: +.LFB4098: + # ptwrite.c:34:1 + .loc 1 34 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + # ptwrite.c:35:3 + .loc 1 35 3 + movl $66, %edi + call ptwrite1 + # ptwrite.c:36:3 + .loc 1 36 3 + movl $67, %edi + call ptwrite2 + # ptwrite.c:38:10 + .loc 1 38 10 + movl $0, %eax + # ptwrite.c:39:1 + .loc 1 39 1 + popq %rbp + .cfi_def_cfa 7, 8 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4098: + .size main, .-main +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0x159 # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF15 # DW_AT_producer: "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -mptwrite -mtune=generic -march=x86-64 -g" + .byte 0xc # DW_AT_language + .long .LASF16 # DW_AT_name: "ptwrite.c" + .long .LASF17 # DW_AT_comp_dir: "gdb/gdb/testsuite/gdb.btrace" + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2d) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x3 # (DIE (0x34) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF0 # DW_AT_name: "short int" + .uleb128 0x3 # (DIE (0x3b) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF1 # DW_AT_name: "char" + .uleb128 0x3 # (DIE (0x42) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF2 # DW_AT_name: "long long int" + .uleb128 0x3 # (DIE (0x49) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF3 # DW_AT_name: "float" + .uleb128 0x3 # (DIE (0x50) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF4 # DW_AT_name: "long unsigned int" + .uleb128 0x3 # (DIE (0x57) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF5 # DW_AT_name: "long int" + .uleb128 0x3 # (DIE (0x5e) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x8 # DW_AT_encoding + .long .LASF6 # DW_AT_name: "unsigned char" + .uleb128 0x3 # (DIE (0x65) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF7 # DW_AT_name: "short unsigned int" + .uleb128 0x3 # (DIE (0x6c) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF8 # DW_AT_name: "unsigned int" + .uleb128 0x3 # (DIE (0x73) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF9 # DW_AT_name: "signed char" + .uleb128 0x3 # (DIE (0x7a) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF10 # DW_AT_name: "long long unsigned int" + .uleb128 0x3 # (DIE (0x81) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF11 # DW_AT_name: "double" + .uleb128 0x4 # (DIE (0x88) DW_TAG_subprogram) + # DW_AT_external + .long .LASF18 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x21 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long 0x2d # DW_AT_type + .quad .LFB4098 # DW_AT_low_pc + .quad .LFE4098-.LFB4098 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_tail_call_sites + .uleb128 0x5 # (DIE (0xa6) DW_TAG_subprogram) + # DW_AT_external + .long .LASF12 # DW_AT_name: "ptwrite2" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .quad .LFB4097 # DW_AT_low_pc + .quad .LFE4097-.LFB4097 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0xf5 # DW_AT_sibling + .uleb128 0x6 # (DIE (0xc4) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x2d # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -36 + .uleb128 0x7 # (DIE (0xd3) DW_TAG_inlined_subroutine) + .long 0x144 # DW_AT_abstract_origin + .quad .LBB8 # DW_AT_low_pc + .quad .LBE8-.LBB8 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x1d # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0xeb) DW_TAG_formal_parameter) + .long 0x14e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -20 + .byte 0 # end of children of DIE 0xd3 + .byte 0 # end of children of DIE 0xa6 + .uleb128 0x5 # (DIE (0xf5) DW_TAG_subprogram) + # DW_AT_external + .long .LASF13 # DW_AT_name: "ptwrite1" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .quad .LFB4096 # DW_AT_low_pc + .quad .LFE4096-.LFB4096 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0x144 # DW_AT_sibling + .uleb128 0x6 # (DIE (0x113) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x2d # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -36 + .uleb128 0x7 # (DIE (0x122) DW_TAG_inlined_subroutine) + .long 0x144 # DW_AT_abstract_origin + .quad .LBB6 # DW_AT_low_pc + .quad .LBE6-.LBB6 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x17 # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0x13a) DW_TAG_formal_parameter) + .long 0x14e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -20 + .byte 0 # end of children of DIE 0x122 + .byte 0 # end of children of DIE 0xf5 + .uleb128 0x9 # (DIE (0x144) DW_TAG_subprogram) + # DW_AT_external + .long .LASF19 # DW_AT_name: "_ptwrite32" + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .byte 0x3 # DW_AT_inline + # DW_AT_artificial + .uleb128 0xa # (DIE (0x14e) DW_TAG_formal_parameter) + .ascii "__B\0" # DW_AT_name + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x16 # DW_AT_decl_column + .long 0x6c # DW_AT_type + .byte 0 # end of children of DIE 0x144 + .byte 0 # end of children of DIE 0xb + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0 # DW_children_no + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x1d # (TAG: DW_TAG_inlined_subroutine) + .byte 0x1 # DW_children_yes + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x58 # (DW_AT_call_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x59 # (DW_AT_call_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x57 # (DW_AT_call_column) + .uleb128 0xb # (DW_FORM_data1) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x20 # (DW_AT_inline) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x34 # (DW_AT_artificial) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 16 byte boundary + .value 0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0 + .quad 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF2: + .string "long long int" +.LASF14: + .string "value" +.LASF19: + .string "_ptwrite32" +.LASF8: + .string "unsigned int" +.LASF17: + .string "gdb/gdb/testsuite/gdb.btrace" +.LASF18: + .string "main" +.LASF16: + .string "ptwrite.c" +.LASF4: + .string "long unsigned int" +.LASF10: + .string "long long unsigned int" +.LASF15: + .string "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -mptwrite -mtune=generic -march=x86-64 -g" +.LASF13: + .string "ptwrite1" +.LASF12: + .string "ptwrite2" +.LASF6: + .string "unsigned char" +.LASF1: + .string "char" +.LASF5: + .string "long int" +.LASF11: + .string "double" +.LASF7: + .string "short unsigned int" +.LASF9: + .string "signed char" +.LASF3: + .string "float" +.LASF0: + .string "short int" + .ident "GCC: (GNU) 10.3.1 20210422 (Red Hat 10.3.1-1)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index e2cda30b95a..fc5a539f88d 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -3940,6 +3940,80 @@ gdb_caching_proc skip_btrace_pt_tests { return $skip_btrace_tests } +# Run a test on the target to see if it supports ptwrite instructions and +# if GDB can decode ptwrite events. Return 0 if so, 1 if it does not. + +gdb_caching_proc skip_btrace_ptw_tests { + global srcdir subdir gdb_prompt inferior_exited_re decimal + + set me "skip_ptw_tests" + if { [skip_btrace_pt_tests] } { + verbose "$me: target does not support btrace pt, returning 1" 2 + return 1 + } + + set src { + int + main () + { + asm volatile ("PTWRITE %0;" : : "b"(0x42)); + return 0; + } + } + + if {![gdb_simple_compile $me $src executable]} { + return 1 + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load "$obj" + if ![runto_main] { + return 1 + } + + gdb_test_no_output "record btrace pt" "$me: record btrace pt" + + set skip_ptw_tests 2 + gdb_test_multiple "next" "$me: next" { + -re -wrap ".*Illegal instruction.*" { + verbose -log "$me: ptwrite instruction support not detected." + set skip_ptw_tests 2 + } + -re -wrap ".*$inferior_exited_re normally.*" { + verbose -log "$me: ptwrite support not detected." + set skip_ptw_tests 2 + } + -re -wrap "$decimal.*(at|in).*" { + set skip_ptw_tests 1 + } + } + + if { $skip_ptw_tests == 1 } { + # Show the func-call-history to get the packet trace. + gdb_test "record function-call-history" ".*" + + gdb_test_multiple "maintenance btrace packet-history 0,1000" \ + "$me: check decoding support" { + -re "ptw" { + verbose -log "$me: ptwrite decoding support detected." + set skip_ptw_tests 0 + } + -re ".*${gdb_prompt} $" { + verbose -log "$me: ptwrite decoding support not detected." + } + } + } + + gdb_exit + remote_file build delete $obj + + verbose "$me: returning $skip_ptw_tests" 2 + return $skip_ptw_tests +} + + # Run a test on the target to see if it supports Aarch64 SVE hardware. # Return 0 if so, 1 if it does not. Note this causes a restart of GDB. diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4 index 0fed186ae1d..526f7d47c05 100644 --- a/gdbsupport/common.m4 +++ b/gdbsupport/common.m4 @@ -179,6 +179,8 @@ AC_DEFUN([GDB_AC_COMMON], [ AC_CHECK_FUNCS(pt_insn_event) AC_CHECK_MEMBERS([struct pt_insn.enabled, struct pt_insn.resynced], [], [], [#include ]) + AC_CHECK_MEMBERS([struct pt_event.variant.ptwrite], [], [], + [#include ]) LIBS=$save_LIBS fi fi diff --git a/gdbsupport/config.in b/gdbsupport/config.in index 577866c97b3..56a314195f3 100644 --- a/gdbsupport/config.in +++ b/gdbsupport/config.in @@ -235,6 +235,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H +/* Define to 1 if `variant.ptwrite' is a member of `struct pt_event'. */ +#undef HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE + /* Define to 1 if `enabled' is a member of `struct pt_insn'. */ #undef HAVE_STRUCT_PT_INSN_ENABLED diff --git a/gdbsupport/configure b/gdbsupport/configure index 38541e87c15..71efc9fe41f 100755 --- a/gdbsupport/configure +++ b/gdbsupport/configure @@ -9605,6 +9605,17 @@ cat >>confdefs.h <<_ACEOF _ACEOF +fi + + ac_fn_c_check_member "$LINENO" "struct pt_event" "variant.ptwrite" "ac_cv_member_struct_pt_event_variant_ptwrite" "#include +" +if test "x$ac_cv_member_struct_pt_event_variant_ptwrite" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE 1 +_ACEOF + + fi LIBS=$save_LIBS