diff mbox series

[v3,3/5] gdb/testsuite: Add gdb.arch/aarch64-mops-watchpoint.exp

Message ID 20240510052408.2173579-4-thiago.bauermann@linaro.org
State New
Headers show
Series Add support for AArch64 MOPS instructions | expand

Commit Message

Thiago Jung Bauermann May 10, 2024, 5:24 a.m. UTC
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.
---
 .../gdb.arch/aarch64-mops-watchpoint.c        | 66 ++++++++++++++++
 .../gdb.arch/aarch64-mops-watchpoint.exp      | 79 +++++++++++++++++++
 gdb/testsuite/lib/gdb.exp                     | 61 ++++++++++++++
 3 files changed, 206 insertions(+)
 create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c
 create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp

No change since v1.

Comments

Luis Machado May 10, 2024, 1:04 p.m. UTC | #1
Thanks.

Just a nit below. I'll set something up on my end to give these tests a try.

On 5/10/24 06:24, Thiago Jung Bauermann wrote:
> 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.
> ---
>  .../gdb.arch/aarch64-mops-watchpoint.c        | 66 ++++++++++++++++
>  .../gdb.arch/aarch64-mops-watchpoint.exp      | 79 +++++++++++++++++++
>  gdb/testsuite/lib/gdb.exp                     | 61 ++++++++++++++
>  3 files changed, 206 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c
>  create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp
> 
> No change since v1.
> 
> 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 <http://www.gnu.org/licenses/>.  */
> +
> +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 <http://www.gnu.org/licenses/>.
> +
> +# 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"
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 0d78691c381b..25b272fdaabc 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -4497,6 +4497,67 @@ proc aarch64_supports_sme_svl { length } {
>      return 1
>  }
>  
> +# Run a test on the target to see if it supports Aarch64 MOPS (Memory

s/Aarch64/AArch64

> +# Operations) extensions.  Return 0 if so, 1 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 <stdbool.h>
> +	#include <sys/auxv.h>
> +
> +	#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" {
Thiago Jung Bauermann May 23, 2024, 2:06 a.m. UTC | #2
Luis Machado <luis.machado@arm.com> writes:

> Thanks.
>
> Just a nit below. I'll set something up on my end to give these tests a try.

Thanks!

> On 5/10/24 06:24, Thiago Jung Bauermann wrote:
>> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
>> index 0d78691c381b..25b272fdaabc 100644
>> --- a/gdb/testsuite/lib/gdb.exp
>> +++ b/gdb/testsuite/lib/gdb.exp
>> @@ -4497,6 +4497,67 @@ proc aarch64_supports_sme_svl { length } {
>>      return 1
>>  }
>>  
>> +# Run a test on the target to see if it supports Aarch64 MOPS (Memory
>
> s/Aarch64/AArch64

Thanks. Fixed in v4.

>> +# Operations) extensions.  Return 0 if so, 1 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
>> +    }
diff mbox series

Patch

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 <http://www.gnu.org/licenses/>.  */
+
+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 <http://www.gnu.org/licenses/>.
+
+# 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"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 0d78691c381b..25b272fdaabc 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4497,6 +4497,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 0 if so, 1 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 <stdbool.h>
+	#include <sys/auxv.h>
+
+	#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" {