From patchwork Thu May 23 03:51:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 798396 Delivered-To: patch@linaro.org Received: by 2002:a5d:6a47:0:b0:354:fb4b:99cd with SMTP id t7csp28993wrw; Wed, 22 May 2024 20:52:17 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCU066CmygFv3T5aRoG3tWfrXfGjecxGjxLDaghzNryHuEdXoH0y2VfDQ+gwbdKp5G2KyN8Qe3voT1oaTx1jFePE X-Google-Smtp-Source: AGHT+IEl6M3AAzVEHZxdEqNOCb1e2ta93Efq+pEXJtYU1AotGI+NyXriMeJTw7OFK4bOLwKOgT27 X-Received: by 2002:ad4:5246:0:b0:6ab:8bb0:4f0b with SMTP id 6a1803df08f44-6ab8bb05002mr20848566d6.38.1716436337552; Wed, 22 May 2024 20:52:17 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716436337; cv=pass; d=google.com; s=arc-20160816; b=TuKybgOfDY7wc3AEtXB9iEwBto4RPQarOGdJOrozBq5ZLP5kVf93hofgfCiLLFTZm+ h6IuuQiWml0io5eYQqHZwGRDt1+ychb9Yxx8FLwmboucDRd2vM9aTa+i/8DRJY06vYO8 PSMJFFWvb8qDNE6Xf0VH74LazC/tqQ4mQJoJgOmqBoZ2xXna58itCvR5GUHynN8ZmzqU FMXwfXTM5f9zD5iJa370VjNIl06tEuPFqDMSqPdY7WhMbNyF0P5fW08M9khOO10D491X BshBdbt3/EhBNWviJ4rpR0MqMxD+wtaI9aH9c2b//4FavvvJno/YwbM1Rj5u/ELHkyFy 226A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=RBoHwSgF8xYLjJcEc+G4G7bkLW7C3uZr8zNFMvEEXnU=; fh=loWCTN49GeJC1HCrrvtQFeZ0kzyLaMXCA7ZZRe9+Kj4=; b=yXW4VjRY2r62MI912iLo7daedrac2laiRZzgjnJavAhIjid8jd5Topr59ZXrZQk8NA 1gIV8el7XuAKqX58blQtcubg8W6VeKCJiT5t+BqfrDR2TW45AuKoCPoVRGtaRypVlXy5 8mpnC5AVBoxG2j9CAOMenkKgSR8h2T3rofIesS0Kp9q1QDaa6Ajvye8hUmLl40bJTTso rPnwSxQ+RwLBYyVGdj62r7ktMX/KRerPQVzJZdIULSZ9sz3mm1soILejp+ICz4K1lcGU 2tf3NW5Tb9dr55CgA8hJMSKbtdFsKUt5oZIfIQSu2RYO+5V4zto4isnRiXtCzcmDZi+4 oTyg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PG3kfT3a; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id 6a1803df08f44-6a15f29a492si22283616d6.301.2024.05.22.20.52.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 20:52:17 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PG3kfT3a; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2F673384A02A for ; Thu, 23 May 2024 03:52:17 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by sourceware.org (Postfix) with ESMTPS id 84A653865488 for ; Thu, 23 May 2024 03:51:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 84A653865488 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 84A653865488 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1031 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716436297; cv=none; b=BKSemsD4F3HVec8qpxEUP/3qeIDJ7I9yRB6g2UgaEKj71BGZabhlpuqvPDGSxEY2ASGn16X8nQteANORNKlmcHFcgRtUIFmUAqEjuN1uxdUmSCuH57ulFxe2AmuEVJju6N4aMTZrliXeIh4n1AHIQPCQpjApOAKZ2ztFwcgqOgQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716436297; c=relaxed/simple; bh=cVTTJfOU9D1WeYgi6uAF8Q3dSASG8wBIk15+CexUe78=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=wgqzI956PI1lmh66cUx+lyoHhPGU8ckxmP4v3rL4MrEGevpMwvTAmBT8adXp/fj9RrRUj4xrmrdfvSKy43r++sOBYV+QUUNXaSl7G0mLgjKXsYmg+1ydlb15QMaUmTheHVrFyV639zepqmhzl61K6HiuhO0Lyb1yvTxmnT2LuIk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2bd92c36cebso1580941a91.0 for ; Wed, 22 May 2024 20:51:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1716436291; x=1717041091; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RBoHwSgF8xYLjJcEc+G4G7bkLW7C3uZr8zNFMvEEXnU=; b=PG3kfT3awlWbK7nNSdsz7/hpgssnROIzcKOV9bJg0FBgDDc8Ec8KUqI0h3olngt5q6 TglVVRwxnVj3qvI70ocq+0X8XOAcv9BAQrlBCySgMKQ1HG5fOW+n3NavAQPE0FdQbt9D /QTTm/30p4lMhm3rxemrEdwnMv9J5g6Jj4cNzbWrzF9ULHSzkhaMvmHJ2E1j88UTT8Oc rtgcKTiZM3hjSPFspnL1LlW4N2CTOYiLJVEDRs8WHcINtJ7XMuu1AN8PVR278cp8wZEM BB+t15f/7qIz6rdXSKEpFYGM9GTunBlRxoJOnxBF5I+bvUZDqPCNgYXR6YAIWM8QsEII r0ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716436291; x=1717041091; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RBoHwSgF8xYLjJcEc+G4G7bkLW7C3uZr8zNFMvEEXnU=; b=iVlqET7mHna69z84hXyFdM7Gu42Zaweoj81I/pAVXk/YAs718pyTr6RsS+E+c/kkqQ 2OpkxhkMBwdbWEucpG5MKVFbmANeILdZ7RU0xowHbd2ECQ2CrXPTyRJQ8W2ZnTqTUXi6 2aTzq6o+o61AXUU/AEot+EtZnMnuPa2m5jq8LHGab1UopYGHTJ5cTMTGo+WiCVAUGfc3 qlpNcoyEghRbkNsodNAoNiaNnyreJsa0WQfuBzf4b/PIBWaz5UenDK8l1gcuCrs5RJfS 8Mv/TBGXt+HS4czvScble/brTgJ6VYNdR1iEXNfxKk92rp78l6NCDpmdGjwflny9xylg mcKw== X-Gm-Message-State: AOJu0Yx2A1K8wY/T8P8CwRbB/fL/NZYcOhZ+xBj+901x66U4XVhrPBx2 M4GpRxWcgid4A/IFJ2verTiKFL0E431VslcVwqGLqtYpC87UWziFbkTrSo5nHVSeV2Cd90yOnHO d X-Received: by 2002:a17:90a:a617:b0:2b9:d6cd:ff63 with SMTP id 98e67ed59e1d1-2bd9f454a03mr4052459a91.8.1716436291312; Wed, 22 May 2024 20:51:31 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8470:f149:d562:aa25:4733]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2bdd9f4dfbfsm562537a91.37.2024.05.22.20.51.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 20:51:30 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Cc: Christophe Lyon , Luis Machado , Guinevere Larsen , Pedro Alves Subject: [PATCH v4 1/3] gdb/aarch64: Disable displaced single-step for MOPS instructions Date: Thu, 23 May 2024 00:51:22 -0300 Message-ID: <20240523035124.2639220-2-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20240523035124.2639220-1-thiago.bauermann@linaro.org> References: <20240523035124.2639220-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patch=linaro.org@sourceware.org The AArch64 MOPS (Memory Operation) instructions provide a standardised instruction sequence to perform a memset, memcpy or memmove. A sequence is always composed of three instructions: a prologue instruction, a main instruction and an epilogue instruction. As an illustration, here are the implementations of these memory operations in glibc 2.39: (gdb) disassemble/r Dump of assembler code for function __memset_mops: => 0x0000fffff7e8d780 <+0>: d503201f nop 0x0000fffff7e8d784 <+4>: aa0003e3 mov x3, x0 0x0000fffff7e8d788 <+8>: 19c10443 setp [x3]!, x2!, x1 0x0000fffff7e8d78c <+12>: 19c14443 setm [x3]!, x2!, x1 0x0000fffff7e8d790 <+16>: 19c18443 sete [x3]!, x2!, x1 0x0000fffff7e8d794 <+20>: d65f03c0 ret End of assembler dump. (gdb) disassemble/r Dump of assembler code for function __memcpy_mops: => 0x0000fffff7e8c580 <+0>: d503201f nop 0x0000fffff7e8c584 <+4>: aa0003e3 mov x3, x0 0x0000fffff7e8c588 <+8>: 19010443 cpyfp [x3]!, [x1]!, x2! 0x0000fffff7e8c58c <+12>: 19410443 cpyfm [x3]!, [x1]!, x2! 0x0000fffff7e8c590 <+16>: 19810443 cpyfe [x3]!, [x1]!, x2! 0x0000fffff7e8c594 <+20>: d65f03c0 ret End of assembler dump. (gdb) disassemble/r Dump of assembler code for function __memmove_mops: => 0x0000fffff7e8d180 <+0>: d503201f nop 0x0000fffff7e8d184 <+4>: aa0003e3 mov x3, x0 0x0000fffff7e8d188 <+8>: 1d010443 cpyp [x3]!, [x1]!, x2! 0x0000fffff7e8d18c <+12>: 1d410443 cpym [x3]!, [x1]!, x2! 0x0000fffff7e8d190 <+16>: 1d810443 cpye [x3]!, [x1]!, x2! 0x0000fffff7e8d194 <+20>: d65f03c0 ret End of assembler dump. The Arm Architecture Reference Manual says that "the prologue, main, and epilogue instructions are expected to be run in succession and to appear consecutively in memory". Therefore this patch disables displaced stepping on them. The testcase verifies that MOPS sequences are correctly single-stepped. PR tdep/31666 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31666 --- Changes in v4: - Fix typo in comment (Spotted by Luis). - Moved procedures is_at_instruction and arrive_at_instruction to lib/gdb.exp so that they can be used by gdb.reverse/aarch64-mops.exp. - Moved procedure allow_aarch64_mops_tests to this patch. Change in v3: - Remove aarch64_software_single_step_mops function and the change to call it from aarch64_software_single_step, since Luis clarified that it is in fact possible to single step through MOPS sequences. No change in v2. gdb/aarch64-tdep.c | 8 +- .../gdb.arch/aarch64-mops-single-step.c | 73 ++++++++++++++ .../gdb.arch/aarch64-mops-single-step.exp | 98 ++++++++++++++++++ gdb/testsuite/lib/gdb.exp | 99 +++++++++++++++++++ 4 files changed, 275 insertions(+), 3 deletions(-) create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-single-step.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-single-step.exp diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 8d0553f3d7cd..05ecd421cd0e 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3808,10 +3808,12 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch, if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0) return NULL; - /* Look for a Load Exclusive instruction which begins the sequence. */ - if (inst.opcode->iclass == ldstexcl && bit (insn, 22)) + /* Look for a Load Exclusive instruction which begins the sequence, + or for a MOPS instruction. */ + if ((inst.opcode->iclass == ldstexcl && bit (insn, 22)) + || AARCH64_CPU_HAS_FEATURE (*inst.opcode->avariant, MOPS)) { - /* We can't displaced step atomic sequences. */ + /* We can't displaced step atomic sequences nor MOPS instructions. */ return NULL; } diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-single-step.c b/gdb/testsuite/gdb.arch/aarch64-mops-single-step.c new file mode 100644 index 000000000000..4a27867d4b57 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mops-single-step.c @@ -0,0 +1,73 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2024 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 . */ + +#define TEST_STRING "Just a test string." +#define BUF_SIZE sizeof(TEST_STRING) + +int +main (void) +{ + char source[BUF_SIZE] = TEST_STRING; + char dest[BUF_SIZE]; + char *p, *q; + long size, zero; + + /* Note: The prfm instruction in the asm statements below is there just + to allow the testcase to recognize when the PC is at the instruction + right after the MOPS sequence. */ + + p = dest; + size = sizeof (dest); + zero = 0; + /* Break memset. */ + /* memset implemented in MOPS instructions. */ + __asm__ volatile ("setp [%0]!, %1!, %2\n\t" + "setm [%0]!, %1!, %2\n\t" + "sete [%0]!, %1!, %2\n\t" + "prfm pldl3keep, [%0, #0]\n\t" + : "+&r"(p), "+&r"(size) + : "r"(zero) + : "memory"); + + p = dest; + q = source; + size = sizeof (dest); + /* Break memcpy. */ + /* memcpy implemented in MOPS instructions. */ + __asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t" + "cpyfm [%0]!, [%1]!, %2!\n\t" + "cpyfe [%0]!, [%1]!, %2!\n\t" + "prfm pldl3keep, [%0, #0]\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + + p = dest; + q = source; + size = sizeof (dest); + /* Break memmove. */ + /* memmove implemented in MOPS instructions. */ + __asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t" + "cpym [%0]!, [%1]!, %2!\n\t" + "cpye [%0]!, [%1]!, %2!\n\t" + "prfm pldl3keep, [%0, #0]\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-single-step.exp b/gdb/testsuite/gdb.arch/aarch64-mops-single-step.exp new file mode 100644 index 000000000000..2cb5fdcca36b --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mops-single-step.exp @@ -0,0 +1,98 @@ +# Copyright 2024 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 is part of the GDB testsuite. + +# Test single stepping through MOPS (memory operations) instruction sequences. + +require allow_aarch64_mops_tests + +standard_testfile +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + [list debug additional_flags=-march=armv9.3-a]] } { + return -1 +} + +# If the inferior is rescheduled to another CPU while a main or epilogue +# instruction is executed, the OS resets the inferior back to the prologue +# instruction, so we need to allow for that possibility. +proc step_through_sequence { prefix } { + set count 0 + + while { [is_at_instruction ${prefix}p] == 1 && $count < 50 } { + incr count + + # The stepi output isn't useful to detect whether we stepped over + # the instruction. + gdb_test "stepi" "\[^\r\n\]+" "step over ${prefix}p" + if { [is_at_instruction ${prefix}m] == 1 } { + pass "stepped over ${prefix}p" + } else { + fail "stepped over ${prefix}e" + return 0 + } + + gdb_test "stepi" "\[^\r\n\]+" "step over ${prefix}m" + if { [is_at_instruction ${prefix}e] == 1 } { + pass "stepped over ${prefix}m" + } elseif { [is_at_instruction ${prefix}p] == 1 } { + # The inferior was rescheduled to another CPU. + pass "${prefix}m: reset back to prologue" + continue + } else { + fail "stepped over ${prefix}m" + return 0 + } + + gdb_test "stepi" "\[^\r\n\]+" "step over ${prefix}e" + if { [is_at_instruction prfm] == 1 } { + pass "stepped over ${prefix}e" + return 1 + } elseif { [is_at_instruction ${prefix}p] == 1 } { + # The inferior was rescheduled to another CPU. + pass "${prefix}e: reset back to prologue" + continue + } + } + + fail "step through $prefix sequence" + return 0 +} + +if ![runto_main] { + return -1 +} + +gdb_breakpoint ${srcfile}:[gdb_get_line_number "Break memset"] +gdb_breakpoint ${srcfile}:[gdb_get_line_number "Break memcpy"] +gdb_breakpoint ${srcfile}:[gdb_get_line_number "Break memmove"] + +gdb_continue_to_breakpoint "memset breakpoint" + +if { [arrive_at_instruction setp] } { + step_through_sequence set +} + +gdb_continue_to_breakpoint "memcpy breakpoint" + +if { [arrive_at_instruction cpyfp] } { + step_through_sequence cpyf +} + +gdb_continue_to_breakpoint "memmove breakpoint" + +if { [arrive_at_instruction cpyp] } { + step_through_sequence cpy +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 55f6ab1fd8b9..762cf1cd5cf0 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -848,6 +848,44 @@ proc gdb_continue_to_breakpoint {name {location_pattern .*}} { }] } +# Check whether GDB is stopped at the given instruction. +# INSTRUCTION should be just its mnemonic, without any arguments. + +proc is_at_instruction { instruction } { + global gdb_prompt hex + + set test "pc points to $instruction" + gdb_test_multiple {x/i $pc} $test { + -re -wrap "=> $hex \[^\r\n\]+:\t$instruction\t\[^\r\n\]+" { + return 1 + } + -re "\r\n$gdb_prompt $" { + return 0 + } + } + + return 0 +} + +# Single-steps GDB until it arrives at the given instruction. +# INSTRUCTION should be just its mnemonic, without any arguments. + +proc arrive_at_instruction { instruction } { + set count 0 + + while { [is_at_instruction $instruction] != 1 } { + gdb_test -nopass "stepi" "\[^\r\n\]+" \ + "stepi #$count to reach $instruction" + incr count + + if { $count > 50 } { + fail "didn't reach $instruction" + return 0 + } + } + + return 1 +} # gdb_internal_error_resync: # @@ -4497,6 +4535,67 @@ proc aarch64_supports_sme_svl { length } { return 1 } +# Run a test on the target to see if it supports AArch64 MOPS (Memory +# Operations) extensions. Return 1 if so, 0 if it does not. Note this +# causes a restart of GDB. + +gdb_caching_proc allow_aarch64_mops_tests {} { + global srcdir subdir gdb_prompt inferior_exited_re + + set me "allow_aarch64_mops_tests" + + if { ![is_aarch64_target]} { + return 0 + } + + # ARMv9.3-A contains the MOPS extension. The test program doesn't use it, + # but take the opportunity to check whether the toolchain knows about MOPS. + set compile_flags "{additional_flags=-march=armv9.3-a}" + + # Compile a program that tests the MOPS feature. + set src { + #include + #include + + #ifndef HWCAP2_MOPS + #define HWCAP2_MOPS (1UL << 43) + #endif + + int main() { + bool mops_supported = getauxval (AT_HWCAP2) & HWCAP2_MOPS; + + return !mops_supported; + } + } + + if {![gdb_simple_compile $me $src executable $compile_flags]} { + return 0 + } + + # Compilation succeeded so now run it via gdb. + clean_restart $obj + gdb_run_cmd + gdb_expect { + -re ".*$inferior_exited_re with code 01.*${gdb_prompt} $" { + verbose -log "\n$me mops support not detected" + set allow_mops_tests 0 + } + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { + verbose -log "\n$me: mops support detected" + set allow_mops_tests 1 + } + default { + warning "\n$me: default case taken" + set allow_mops_tests 0 + } + } + gdb_exit + remote_file build delete $obj + + verbose "$me: returning $allow_mops_tests" 2 + return $allow_mops_tests +} + # A helper that compiles a test case to see if __int128 is supported. proc gdb_int128_helper {lang} { return [gdb_can_simple_compile "i128-for-$lang" { From patchwork Thu May 23 03:51:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 798394 Delivered-To: patch@linaro.org Received: by 2002:a5d:6a47:0:b0:354:fb4b:99cd with SMTP id t7csp28950wrw; Wed, 22 May 2024 20:52:06 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWNweTYcQbX6F+TqQknRQscPpkwyHKd+0CUbeZYLSDFZuDP49W1mI69mDhF62fWd9ksZZVSNlUuDdz+QhDOEC9L X-Google-Smtp-Source: AGHT+IHo1MjLkcrmLlmosX5jYxO9X2sFo0JyXYcbBvoSi+ncR1BbKh/8Hy/kFp5FAyyu6YCy8y4t X-Received: by 2002:aca:130b:0:b0:3c9:6a50:95f5 with SMTP id 5614622812f47-3cdb949ab4dmr3565015b6e.56.1716436326411; Wed, 22 May 2024 20:52:06 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716436326; cv=pass; d=google.com; s=arc-20160816; b=zNkOyDCyGw490Riv/6Dr7T3OpPobiyPASHgKJPd9R2F9bWM22h9Rz9Dr6xKWOBglyM cMdNd2aPHlir61lpSJgciIXrKC20gPX85oLCHk3985h8wKTP+UQ+sS7wTvPw9r8EFgfP DIZK6JfvmcxqzUCJCz8vuRcoppSINrfmBZQ9+g2TWv6vyCR9obtg/IA7EP7DWY1Y7L8/ fucg8sX7GbulwYKbAwAUbDsKP8pmzC5/IXK/CukKxH0xsgMt4MeoCse0cRkHr75wmOyj Mm6vIXMB3CPr3YBW+x08Y+tAnCY3c/VHRzMrLUyf0abl8lG3TG3J+oTdxSyosHsFL4vj eOIA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=zVNfO5kmVGXfUFvfwlVZxOEUsGM9F8bYwhPy68tk7b0=; fh=loWCTN49GeJC1HCrrvtQFeZ0kzyLaMXCA7ZZRe9+Kj4=; b=hrHQRvyKXnP+ayZ3hM9B6wWtgGgiTDBfMWehnWV4dTJVEMyh7/dN9XfmQYTMQYVcKT 6YuD7H9txoOfMmQAq5/PShsja8AQqh6exL50wJ63Ej5DIKs5ScIZrNHFHAo9kR/rSR1r V079Zu4c5vDbHrfxX+7Dq7K2AgQm6RJ4RCRW2/i4nwSYDiOZkwSQzhmKHSf6AXNWkI/l jcyMBYUo+AyFgLr0L/F4SzdvxRRv9DKMD1snEPazHaHGofd54K6mbVznCmu4Lg7jSEp/ 8AhrHFdQaqy8tqfK4h0qxMD0F8ufDJv5jyi2fPOPhr8jCec6Zm+G02TFonk35s0HLDFf XEmQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ndeSTW1X; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id af79cd13be357-792bf29aa05si734767385a.224.2024.05.22.20.52.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 20:52:06 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ndeSTW1X; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E05363858C62 for ; Thu, 23 May 2024 03:52:05 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd2d.google.com (mail-io1-xd2d.google.com [IPv6:2607:f8b0:4864:20::d2d]) by sourceware.org (Postfix) with ESMTPS id 699AF384F4B9 for ; Thu, 23 May 2024 03:51:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 699AF384F4B9 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 699AF384F4B9 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::d2d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716436300; cv=none; b=LC5VdEpu9W2jTWqJSXMYt4s6wMiRv4VBCL4zKTpuS2ExF725td3+FfD1afMgJjaXo9jDhE7lCgRYvKYOJ4qaHDI4ZSsPTU3PHxqRETfjBFsy9s0FH1tOKkaVlqfjQ55TQkfEsp7PLwsoNnYGrEMSQcIJw26enfBfSE22pKcEGSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716436300; c=relaxed/simple; bh=swY4W75GePSKUuJ1t7QMB3M8dJhMmfTTrnlIEF6LYBo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Q5YkhGXvyV/soHXWaxQTbz9MarLNIvf5ArDMOor/xsheLnuLTQrwy/QQIcFrvCHkOZ1CjpM7Q4i9x08fud53xet/XI3bni9cpnvP4RfbHXV83u3eQYVGSVNG67zT3U5H1QjzFpEhtQIDiyk0iTs8RTA08vBc70tLXhrXx7PFaxw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-io1-xd2d.google.com with SMTP id ca18e2360f4ac-7e2119a1b82so205129039f.0 for ; Wed, 22 May 2024 20:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1716436295; x=1717041095; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zVNfO5kmVGXfUFvfwlVZxOEUsGM9F8bYwhPy68tk7b0=; b=ndeSTW1XnzwQJbaLPXgndRriJTsfHtXqzN9ZbC96Au6LT5er5BDqrbzNyWk4oab8Kb vlME3cYyiDa3V16DsfAX1lJVOkRxLZ5hRLI+ptc4ZRAJOVfSoF0J0IvtMEtFfjN6Hkcf /HqTr231x1EmWSjtKpxeXeHxqwUNsEycK6jUtCCBORRQ8sozfXhXLqOcRSfq9nqQMu/c zodaBOl5C2eWEbWS3G5GOsHCX8k/979btejQxtuTGZ51C1QDz/0W2EV3GWgx2cGdSen/ sy/aC6P3THJ380nVh92szZaonUK9HJ5m60mC+n3L8SxDTZUIVPMJXcWS4KAtlt/Iqz3y BuSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716436295; x=1717041095; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zVNfO5kmVGXfUFvfwlVZxOEUsGM9F8bYwhPy68tk7b0=; b=vgpG0judOM4wlVNrYyWB0LqZ5ba6o4UuG1N/AsQ1iVL6qZ/lq/9jRQhLhA0tc4zpXy ej2ZmR4ZKWQfDrg1XF7cnplyHPgppE+EPfexIZ9tFveTsPV/cTkF9GiZEvFAblv8RH5E VzSq3jDCqa+zGNbtDbdBOV8JuD0FeWtLOAvyx5G1Q1KXvFJ0Eygs6c7zqN3RjRpOqT3n CkLMrGiUBA9fyMys9mJw6ic6OUCY3UtONskwaob3r+cZB80LXvyx6OyZIeHN1LO7r7MV FnltIpQH/V+icK56DzjKghKFGFS8hB7uKw2ZrPcyJAQPNlpRjADW6Nn91hak8Y/SAgqN yg1w== X-Gm-Message-State: AOJu0YxxqfYX/xt78Frf5olLwRAOZU1jFUz3kTUjcqaYiSdM8JIB+71D 0ecRmUGzxnNyUxACx3AWTUx0dfRKu49PptXrG0lEEJ1uIbq7o/65mPpzaEtLLJhrzIoMNgOomep w X-Received: by 2002:a92:ca4d:0:b0:36c:c5ef:8265 with SMTP id e9e14a558f8ab-371f3f481f2mr42980935ab.0.1716436295407; Wed, 22 May 2024 20:51:35 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8470:f149:d562:aa25:4733]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-6f67ed10e79sm11886134b3a.45.2024.05.22.20.51.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 20:51:35 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Cc: Christophe Lyon , Luis Machado , Guinevere Larsen , Pedro Alves Subject: [PATCH v4 2/3] gdb/aarch64: Add record support for MOPS instructions. Date: Thu, 23 May 2024 00:51:23 -0300 Message-ID: <20240523035124.2639220-3-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20240523035124.2639220-1-thiago.bauermann@linaro.org> References: <20240523035124.2639220-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patch=linaro.org@sourceware.org There are two kinds of MOPS instructions: set instructions and copy instructions. Within each group there are variants with minor differences in how they read or write to memory — e.g., non-temporal read and/or write, unprivileged read and/or write and permutations of those — but they work in the same way in terms of the registers and regions of memory that they modify. The new gdb.reverse/aarch64-mops.exp testcase verifies that MOPS instructions are recorded and correctly reversed. Not all variants of the copy and set instructions are tested, since there are many and the record and replay target processes them in the same way. PR tdep/31666 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31666 --- Changes in v4: - Implemented common path for set and copy instructions in aarch64_record_memcopy_memset (Suggested by Luis). - Removed identical or operands in aarch64_record_memcopy_memset. - Moved gdb.reverse/aarch64-mops.exp testcase to this patch (Suggested by Guinevere). - Use foreach_with_prefix instead of test procedure in testcase (Suggested by Guinevere). - Use gdb_continue_to_breakpoint instead of gdb_test "continue" in testcase (Suggested by Guinevere). - Test that source and dest variables are correctly recorded. - Reset dest variable after each memops sequence. - Step to prologue instruction after hitting "before" breakpoint and put a breakpoint there, to cope with Clang's line number info including some register preparation instructions as part of the line with the asm statement. No change in v1, v2 or v3. gdb/aarch64-tdep.c | 69 ++++++++ gdb/testsuite/gdb.reverse/aarch64-mops.c | 78 +++++++++ gdb/testsuite/gdb.reverse/aarch64-mops.exp | 186 +++++++++++++++++++++ 3 files changed, 333 insertions(+) create mode 100644 gdb/testsuite/gdb.reverse/aarch64-mops.c create mode 100644 gdb/testsuite/gdb.reverse/aarch64-mops.exp diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 05ecd421cd0e..8b7582d12be9 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -5188,6 +5188,71 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r) return AARCH64_RECORD_SUCCESS; } +/* Record handler for Memory Copy and Memory Set instructions. */ + +static unsigned int +aarch64_record_memcopy_memset (aarch64_insn_decode_record *aarch64_insn_r) +{ + if (record_debug) + debug_printf ("Process record: memory copy and memory set\n"); + + uint8_t op1 = bits (aarch64_insn_r->aarch64_insn, 22, 23); + uint8_t op2 = bits (aarch64_insn_r->aarch64_insn, 12, 15); + uint32_t reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4); + uint32_t reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9); + uint32_t record_buf[3]; + uint64_t record_buf_mem[4]; + + if (op1 == 3 && op2 > 11) + /* Unallocated instructions. */ + return AARCH64_RECORD_UNKNOWN; + + /* Set instructions have two registers and one memory region to be + recorded. */ + record_buf[0] = reg_rd; + record_buf[1] = reg_rn; + aarch64_insn_r->reg_rec_count = 2; + + ULONGEST dest_addr; + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rd, &dest_addr); + + LONGEST length; + regcache_raw_read_signed (aarch64_insn_r->regcache, reg_rn, &length); + + /* In one ofthe algorithm options a processor can implement, the length + in Rn has an inverted sign. */ + if (length < 0) + length *= -1; + + record_buf_mem[0] = length; + record_buf_mem[1] = dest_addr; + aarch64_insn_r->mem_rec_count = 1; + + if (op1 != 3) + { + /* Copy instructions have an additional register and an additional + memory region to be recorded. */ + uint32_t reg_rs = bits (aarch64_insn_r->aarch64_insn, 16, 20); + + record_buf[2] = reg_rs; + aarch64_insn_r->reg_rec_count++; + + ULONGEST source_addr; + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rs, + &source_addr); + + record_buf_mem[2] = length; + record_buf_mem[3] = source_addr; + aarch64_insn_r->mem_rec_count++; + } + + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count, + record_buf_mem); + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, + record_buf); + return AARCH64_RECORD_SUCCESS; +} + /* Record handler for load and store instructions. */ static unsigned int @@ -5465,6 +5530,10 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r) if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03) record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn; } + /* Memory Copy and Memory Set instructions. */ + else if ((insn_bits24_27 & 1) == 1 && insn_bits28_29 == 1 + && insn_bits10_11 == 1 && !insn_bit21) + return aarch64_record_memcopy_memset (aarch64_insn_r); /* Advanced SIMD load/store instructions. */ else return aarch64_record_asimd_load_store (aarch64_insn_r); diff --git a/gdb/testsuite/gdb.reverse/aarch64-mops.c b/gdb/testsuite/gdb.reverse/aarch64-mops.c new file mode 100644 index 000000000000..95318fed9d93 --- /dev/null +++ b/gdb/testsuite/gdb.reverse/aarch64-mops.c @@ -0,0 +1,78 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2024 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 + +#define INITIAL_STRING "Initial fill value." +#define NEW_STRING "Just a test string." +#define BUF_SIZE sizeof(NEW_STRING) + +int +main (void) +{ + char dest[BUF_SIZE] = INITIAL_STRING; + char source[BUF_SIZE] = NEW_STRING; + register char *p asm ("x19"); + register char *q asm ("x20"); + register long size asm ("x21"); + register long zero asm ("x22"); + + p = dest; + size = BUF_SIZE; + zero = 0; + /* Before setp. */ + /* memset implemented in MOPS instructions. */ + __asm__ volatile ("setp [%0]!, %1!, %2\n\t" + "setm [%0]!, %1!, %2\n\t" + "sete [%0]!, %1!, %2\n\t" + : "+&r"(p), "+&r"(size) + : "r"(zero) + : "memory"); + + /* After sete. */ + p = dest; + q = source; + size = BUF_SIZE; + memcpy (dest, INITIAL_STRING, sizeof (dest)); + /* Before cpyp. */ + /* memmove implemented in MOPS instructions. */ + __asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t" + "cpym [%0]!, [%1]!, %2!\n\t" + "cpye [%0]!, [%1]!, %2!\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + + /* After cpye. */ + p = dest; + q = source; + size = BUF_SIZE; + memcpy (dest, INITIAL_STRING, sizeof (dest)); + /* Before cpyfp. */ + /* memcpy implemented in MOPS instructions. */ + __asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t" + "cpyfm [%0]!, [%1]!, %2!\n\t" + "cpyfe [%0]!, [%1]!, %2!\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + + /* After cpyfe. */ + p = dest; + + return 0; +} diff --git a/gdb/testsuite/gdb.reverse/aarch64-mops.exp b/gdb/testsuite/gdb.reverse/aarch64-mops.exp new file mode 100644 index 000000000000..05a991d4bfb9 --- /dev/null +++ b/gdb/testsuite/gdb.reverse/aarch64-mops.exp @@ -0,0 +1,186 @@ +# Copyright 2024 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 . + +# Test instruction record for AArch64 FEAT_MOPS instructions. +# Based on gdb.reverse/ppc_record_test_isa_3_1.exp +# +# The basic flow of the record tests are: +# 1) Stop before executing the instructions of interest. Record +# the initial value of the registers that the instruction will +# change, i.e. the destination register. +# 2) Execute the instructions. Record the new value of the +# registers that changed. +# 3) Reverse the direction of the execution and execute back to +# just before the instructions of interest. Record the final +# value of the registers of interest. +# 4) Check that the initial and new values of the registers are +# different, i.e. the instruction changed the registers as expected. +# 5) Check that the initial and final values of the registers are +# the same, i.e. GDB record restored the registers to their +# original values. + +require allow_aarch64_mops_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + [list debug additional_flags=-march=armv9.3-a]] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test_no_output "record full" + +foreach_with_prefix insn_prefix {"set" "cpy" "cpyf"} { + global decimal hex + + set before_seq [gdb_get_line_number "Before ${insn_prefix}p"] + set after_seq [gdb_get_line_number "After ${insn_prefix}e"] + + gdb_test "break $before_seq" \ + "Breakpoint $decimal at $hex: file .*/aarch64-mops.c, line $decimal\\." \ + "break before instruction sequence" + gdb_continue_to_breakpoint "about to execute instruction sequence" \ + [multi_line ".*/aarch64-mops.c:$decimal" \ + "$decimal\[ \t\]+__asm__ volatile \\(\"${insn_prefix}p \[^\r\n\]+\""] + + # Depending on the compiler, the line number information may put GDB a few + # instructions before the beginning of the asm statement. + arrive_at_instruction "${insn_prefix}p" + # Add a breakpoint that we're sure is at the prologue instruction. + gdb_test "break *\$pc" \ + "Breakpoint $decimal at $hex: file .*/aarch64-mops.c, line $decimal\\." \ + "break at prologue instruction" + + # Record the initial memory and register values. + set dest_initial [get_valueof "/x" "dest" "unable to read initial" \ + "get dest initial value"] + set x19_initial [capture_command_output "info register x19" ""] + set x21_initial [capture_command_output "info register x21" ""] + + # The set instructions use the ZERO variable, but not Q nor SOURCE, + # and the other instructions are the opposite. + if {[string compare $insn_prefix "set"] == 0} { + set x22_initial [capture_command_output "info register x22" ""] + } else { + set x20_initial [capture_command_output "info register x20" ""] + set source_initial [get_valueof "/x" "source" "unable to read initial" \ + "get source initial value"] + } + + gdb_test "break $after_seq" \ + "Breakpoint $decimal at $hex: file .*/aarch64-mops.c, line $decimal\\." \ + "break after instruction sequence" + gdb_continue_to_breakpoint "executed instruction sequence" \ + [multi_line ".*/aarch64-mops.c:$decimal" "$decimal\[ \t\]+p = dest;"] + + # Record the new memory and register values. + set dest_new [get_valueof "/x" "dest" "unable to read new" \ + "get dest new value"] + set x19_new [capture_command_output "info register x19" ""] + set x21_new [capture_command_output "info register x21" ""] + + if {[string compare $insn_prefix "set"] == 0} { + set x22_new [capture_command_output "info register x22" ""] + } else { + set x20_new [capture_command_output "info register x20" ""] + set source_new [get_valueof "/x" "source" "unable to read new" \ + "get source new value"] + } + + # Execute in reverse to before the instruction sequence. + gdb_test_no_output "set exec-direction reverse" + + gdb_continue_to_breakpoint "reversed execution of instruction sequence" \ + [multi_line ".*/aarch64-mops.c:$decimal" \ + "$decimal\[ \t\]+__asm__ volatile \\(\"${insn_prefix}p \[^\r\n\]+\""] + + # Record the final memory and register values. + set dest_final [get_valueof "/x" "dest" "unable to read final" \ + "get dest final value"] + set x19_final [capture_command_output "info register x19" ""] + set x21_final [capture_command_output "info register x21" ""] + + if {[string compare $insn_prefix "set"] == 0} { + set x22_final [capture_command_output "info register x22" ""] + } else { + set x20_final [capture_command_output "info register x20" ""] + set source_final [get_valueof "/x" "source" "unable to read final" \ + "get source final value"] + } + + # Check initial and new values of dest are different. + gdb_assert [string compare $dest_initial $dest_new] \ + "check dest initial value versus dest new value" + + # Check initial and new values of x19 are different. + gdb_assert [string compare $x19_initial $x19_new] \ + "check x19 initial value versus x19 new value" + + # Check initial and new values of x21 are different. + gdb_assert [string compare $x21_initial $x21_new] \ + "check x21 initial value versus x21 new value" + + if {[string compare $insn_prefix "set"] == 0} { + # Check initial and new values of x22 are the same. + # The register with the value to set shouldn't change. + gdb_assert ![string compare $x22_initial $x22_new] \ + "check x22 initial value versus x22 new value" + } else { + # Check initial and new values of x20 are different. + gdb_assert [string compare $x20_initial $x20_new] \ + "check x20 initial value versus x20 new value" + # Check initial and new values of source are the same. + gdb_assert ![string compare $source_initial $source_new] \ + "check source initial value versus source new value" + } + + # Check initial and final values of dest are the same. + gdb_assert ![string compare $dest_initial $dest_final] \ + "check dest initial value versus dest final value" + + # Check initial and final values of x19 are the same. + gdb_assert ![string compare $x19_initial $x19_final] \ + "check x19 initial value versus x19 final value" + + # Check initial and final values of x21 are the same. + gdb_assert ![string compare $x21_initial $x21_final] \ + "check x21 initial value versus x21 final value" + + if {[string compare $insn_prefix "set"] == 0} { + # Check initial and final values of x22 are the same. + gdb_assert ![string compare $x22_initial $x22_final] \ + "check x22 initial value versus x22 final value" + } else { + # Check initial and final values of x20 are the same. + gdb_assert ![string compare $x20_initial $x20_final] \ + "check x20 initial value versus x20 final value" + + # Check initial and final values of source are the same. + gdb_assert ![string compare $source_initial $source_final] \ + "check source initial value versus source final value" + } + + # Restore forward execution and go to end of recording. + gdb_test_no_output "set exec-direction forward" + gdb_test "record goto end" \ + [multi_line \ + "Go forward to insn number $decimal" \ + "#0 main \\(\\) at .*/aarch64-mops.c:$decimal" \ + "$decimal\[ \t\]+p = dest;"] +} From patchwork Thu May 23 03:51:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 798397 Delivered-To: patch@linaro.org Received: by 2002:a5d:6a47:0:b0:354:fb4b:99cd with SMTP id t7csp29041wrw; Wed, 22 May 2024 20:52:29 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUMfc+pXo85j7+1Fx5vekuG0ZCsjsq/mYrip4HQ7hyItTBpY8tn1Sc2Ybl2A62/lQgemM+0wvt/jbYArZ9stoxy X-Google-Smtp-Source: AGHT+IHnyZoa0Km1vN8LepZdN5/aFFSqd5py0fGc0hwryP7eCAOc64kyWOfTZ1DqzRRzJSaKaioa X-Received: by 2002:a0d:cb58:0:b0:61b:34b0:ff04 with SMTP id 00721157ae682-627e4846b5dmr36760757b3.32.1716436349396; Wed, 22 May 2024 20:52:29 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716436349; cv=pass; d=google.com; s=arc-20160816; b=aYHcDmDgiB8xGQQPtY2fG6o+3aArRRp0DFdJbVTuTZ+lDvb3lusld2gyl9snW1bEQq 9GdDfsILny01KfKOvsVjLWlYYvHE5GguTwJCw3EkzyTsPTcpXv8xGoz1upaLot8IyJ6Z DXZRkFFus3nJ9qkgxOuRjgJdoiu5JezdJwU5m4Um88I1Uy2QUWdQ+ud6n+SSbpe8dUwd UbovZ4ufFVD95PDXd42NCAw+mgeI4UwPm1/1v91A3sH3wkqx/eB3SjEvLmQOZSIMUwUh vrh4/jPaZwqjuSMdf5hvkUG3F8sxPtZbvfgxWh290U033V1NzoO4EEO2AvbrSZOqHNCg f78g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=+Hlgtl9IW3h71ehJygtrZ7Azc2qhSTdSpst7m2YEwI0=; fh=loWCTN49GeJC1HCrrvtQFeZ0kzyLaMXCA7ZZRe9+Kj4=; b=FdnGGK79ZaeMVjb4UQrcWJU/gC3TpFAfF7Smwn6Bp4REyxTU8TJh0l/Xm8mFLCyeV1 hFguU1WMfIHmeydlUg8/pjV0z75nJxqYcwRgvFcLSLBG+qj3F02Ia/pjaVAPbC+tbsJF xf4y6mfPv4Cnrz8VFUqXxl1pIiIpVMSC9zCwcd1+wYRUUrqpG0DakKkq+f/qpMY3sVlk 80YdFKqZvt0A9lBYDThxTkl3Qsm2GwNfdiF5JxJzBDzMJNZ7bfvLn2qVPKlGzupA3bL9 /piBwmCu/iol5+5HI4WuVHK5YTHex1+SOTO3gH/UDr7zdFOyUtKrl2BDlnPbylNwdwnC /jdA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yvDP7i9s; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id 6a1803df08f44-6a15f2b486fsi316695476d6.313.2024.05.22.20.52.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 20:52:29 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yvDP7i9s; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0D16F38654B4 for ; Thu, 23 May 2024 03:52:29 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by sourceware.org (Postfix) with ESMTPS id CB8BD38654AD for ; Thu, 23 May 2024 03:51:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CB8BD38654AD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CB8BD38654AD Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::42f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716436302; cv=none; b=GUdfztsXi23F8J1u5l/kmgrO8YFYaQRjaP862suK8uPHcAJze7xCJK2EG5dVVNYRhNwnb1UPJUPK5DuQ5iy5UCfEJ+NusQmGmpyaKAHlyq5/oNpNNkbB8koKfr9qQt78dz4F2IyilL4QWEJeegmoPa7h0HIYLKFJ00kP4Iu3nWs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716436302; c=relaxed/simple; bh=MCukXILfTqNFR9VFFKkVJeeWOlnNv03R4Xipj2Jdu4s=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FyZgYwtx9PLnLYtuUn2nsC5h3RTd+D/jOD8i3SJs0BoEXDSPWxNCNlEwrKvAKtBf7uNPvezacsHdwjjZuPGhrQUalsiOb/KXevacXDqFug8yKi2rPGLQRk0/RqT4rr/YfQn6akipTVsd4J0/B4pjhFPcNnrDq5ZCoFmqVkRs82Q= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pf1-x42f.google.com with SMTP id d2e1a72fcca58-6f693fb0ad4so2419689b3a.1 for ; Wed, 22 May 2024 20:51:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1716436299; x=1717041099; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+Hlgtl9IW3h71ehJygtrZ7Azc2qhSTdSpst7m2YEwI0=; b=yvDP7i9sw9SeRhq8Eucq8edcFSrLHF1r3VHtay9KWUgQ/+K+bEOO1eq2lSUc3eILuS iK26akmRzwKfRJ7TiLAvZb57FanVymlLBEC9rvNAmEl43BCGXCd5wDhYHK7gT8Mcs+mN Tnv5YnvohvudHi0edX111JAMfGOzUBZOKlQ6LL1b5bSXx7ne7zu6YuY2E8W3fPlK7cLc NA25QvZKu7ordbCUbzJp+pDLcIspGGKsczd4caG4ZxT4nqfVbuGreSZRRR2Xp0hkVngy wVl2RMiwuQj2KysQ9sjCxrxN18M6avm2gljnmOdh9+ZEIS0OIskaeJ0Rb/yrqPN8RI/d Vrsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716436299; x=1717041099; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+Hlgtl9IW3h71ehJygtrZ7Azc2qhSTdSpst7m2YEwI0=; b=LDbik+t26KJkB/lCVAdIpwlaZz3IHWGXdZtFDGb9uoI3TYgA0ySuxXnA1LEJ+psKGo 1LM1VvVXTt5mgNyAMXJuSNFCU4LKvaR8gZCOt/VFTG93PN0QSdHqNDi5hzbR9cLmWfVT 1Q8uQprwmkvL12f2G/i2YzYSO3FlNm01J+94YBar3y4UBzSfRTsJaVXrIMva1TpFAset 3F/xM5BrTTqP0+7t4JMzjp0TP/jta71ergQAHkRYad7KwFYDYphdFQLU8w5BinsrvAzR SsE0skszZU7h1rcPF/ScgEWnTAP5staLHNws6zGeShaLms8Ie3Itx7jhKTeK9emRJSEm RmzA== X-Gm-Message-State: AOJu0YxgwxgNyrxvO65LEULDimk0lrrH790q0wKdRfav8aRCSiKidtZ2 NOdNmbPmWoDSo7Xh48qri5i4Qv9SOrtrgDfOOWBQY+nYoB+lchgZMLGXNlitV8Z0TprlYnFksWx I X-Received: by 2002:a05:6a00:3a25:b0:6ed:4f2e:ef22 with SMTP id d2e1a72fcca58-6f6d61e9ffemr4432177b3a.31.1716436298763; Wed, 22 May 2024 20:51:38 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8470:f149:d562:aa25:4733]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-6f679902e57sm12778803b3a.110.2024.05.22.20.51.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 20:51:38 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Cc: Christophe Lyon , Luis Machado , Guinevere Larsen , Pedro Alves Subject: [PATCH v4 3/3] gdb/testsuite: Add gdb.arch/aarch64-mops-watchpoint.exp Date: Thu, 23 May 2024 00:51:24 -0300 Message-ID: <20240523035124.2639220-4-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20240523035124.2639220-1-thiago.bauermann@linaro.org> References: <20240523035124.2639220-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patch=linaro.org@sourceware.org Test behaviour of watchpoints triggered by MOPS instructions. This test is similar to gdb.base/memops-watchpoint.exp, but specifically for MOPS instructions rather than whatever instructions are used in the libc's implementation of memset/memcpy/memmove. There's a separate watched variable for each set of instructions so that the testcase can test whether GDB correctly identified the watchpoint that triggered in each case. --- Changes in v4: - Moved procedure allow_aarch64_mops_tests to patch 1. - Fix typo in comment (Spotted by Luis). No change in v1, v2 or v3. .../gdb.arch/aarch64-mops-watchpoint.c | 66 ++++++++++++++++ .../gdb.arch/aarch64-mops-watchpoint.exp | 79 +++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c new file mode 100644 index 000000000000..b981f033d210 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c @@ -0,0 +1,66 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2024 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 . */ + +int +main (void) +{ + char source[40] __attribute__ ((aligned (8))) + = "This is a relatively long string..."; + char a[40] __attribute__ ((aligned (8))) + = "String to be overwritten with zeroes"; + char b[40] __attribute__ ((aligned (8))) + = "Another string to be memcopied..."; + char c[40] __attribute__ ((aligned (8))) + = "Another string to be memmoved..."; + char *p, *q; + long size, zero; + + /* Break here. */ + p = a; + size = sizeof (a); + zero = 0; + /* memset implemented in MOPS instructions. */ + __asm__ volatile ("setp [%0]!, %1!, %2\n\t" + "setm [%0]!, %1!, %2\n\t" + "sete [%0]!, %1!, %2\n\t" + : "+&r"(p), "+&r"(size) + : "r"(zero) + : "memory"); + + p = b; + q = source; + size = sizeof (b); + /* memmove implemented in MOPS instructions. */ + __asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t" + "cpym [%0]!, [%1]!, %2!\n\t" + "cpye [%0]!, [%1]!, %2!\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + p = c; + q = source; + size = sizeof (c); + /* memcpy implemented in MOPS instructions. */ + __asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t" + "cpyfm [%0]!, [%1]!, %2!\n\t" + "cpyfe [%0]!, [%1]!, %2!\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp new file mode 100644 index 000000000000..9e210602d800 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp @@ -0,0 +1,79 @@ +# Copyright 2024 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 . + +# Test a binary that uses MOPS (Memory Operations) instructions. +# This test is similar to gdb.base/memops-watchpoint.exp, but specifically +# tests MOPS instructions rather than whatever instructions are used in the +# system libc's implementation of memset/memcpy/memmove. + +require allow_hw_watchpoint_tests allow_aarch64_mops_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + [list debug additional_flags=-march=armv9.3-a]] } { + return -1 +} + +set linespec ${srcfile}:[gdb_get_line_number "Break here"] +if ![runto ${linespec}] { + return -1 +} + +gdb_test "watch -location a\[28\]" \ + "(Hardware w|W)atchpoint ${decimal}: -location a\\\[28\\\]" \ + "set watch on a" +gdb_test "watch -location b\[28\]" \ + "(Hardware w|W)atchpoint ${decimal}: -location b\\\[28\\\]" \ + "set watchpoint on b" +gdb_test "watch -location c\[28\]" \ + "(Hardware w|W)atchpoint ${decimal}: -location c\\\[28\\\]" \ + "set watchpoint on c" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Hardware watchpoint ${decimal}: -location a\\\[28\\\]" \ + "" \ + "Old value = 104 'h'" \ + "New value = 0 '\\\\000'" \ + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"setp.*\\\\n\\\\t\""] \ + "continue until set watchpoint hits" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Hardware watchpoint ${decimal}: -location b\\\[28\\\]" \ + "" \ + "Old value = 101 'e'" \ + "New value = 114 'r'" \ + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"cpyp.*\\\\n\\\\t\""] \ + "continue until cpy watchpoint hits" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Hardware watchpoint ${decimal}: -location c\\\[28\\\]" \ + "" \ + "Old value = 100 'd'" \ + "New value = 114 'r'" \ + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"cpyfp.*\\\\n\\\\t\""] \ + "continue until cpyf watchpoint hits"