diff options
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/gdb.arch/aarch64-mte.c | 22 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/aarch64-mte.exp | 196 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/memtag.c | 22 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/memtag.exp | 59 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 16 |
5 files changed, 315 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/aarch64-mte.c b/gdb/testsuite/gdb.arch/aarch64-mte.c new file mode 100644 index 0000000..63a42ae --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mte.c @@ -0,0 +1,22 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2020 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 (int argc, char **argv) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-mte.exp b/gdb/testsuite/gdb.arch/aarch64-mte.exp new file mode 100644 index 0000000..aa25cc3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mte.exp @@ -0,0 +1,196 @@ +# Copyright (C) 2020 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 with address signing works regardless of whether the target +# supports pauth instructions. On non pauth systems, all pauth instructions +# are treated as nops. + +global hex +global decimal + +# Return TAG in hex format with no leading zeroes. +proc get_hex_tag { tag } { + return [format "%x" $tag] +} + +# Return TAG in the NN format where N is 4 bits of the byte. +proc get_tag_nn { tag } { + return [format "%02x" $tag] +} + +# Return the address of PTR with a tag of TAG. +proc get_tagged_ptr { tag ptr } { + return [get_valueof "/x" \ + "${ptr} & (0x00ffffffffffffff) | ((unsigned long) ${tag} << 56)" \ + "0" "fetch pointer ${ptr} with tag ${tag}"] +} + +# Return the logical TAG from PTR. +proc get_ltag_from_ptr { ptr } { + return [get_valueof "/x" "$ptr >> 56 & 0xf" -1 "fetch tag from pointer ${ptr}"] +} + +if {![is_aarch64_target]} { + verbose "Skipping ${gdb_test_file_name}." + return +} + +standard_testfile +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return -1 +} + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +# Targets that don't support memory tagging should not execute the +# runtime memory tagging tests. +if {![supports_memtag]} { + untested "memory tagging unsupported" + return -1 +} + +with_test_prefix "literals" { + set setatag_msg "Allocation tag\\(s\\) updated successfully\." + set check_msg "Memory tags match\." + + # Test setting and showing the logical tags. + for {set i 0} {$i < 32} {incr i} { + set addr [get_tagged_ptr $i 0xdeadbeef] + set tag [get_hex_tag [expr $i % 16]] + gdb_test "mtag showltag $addr" " = 0x${tag}" "showltag with tag ${i}" + + set tag_nn [get_tag_nn $i] + gdb_test "mtag setltag ${addr} ${tag_nn}" " = \\(void \\*\\) ${addr}" \ + "setltag with tag ${i}" + } + + # Fetch the pointer to a known PROT_MTE-mapped area. + set tagged_ptr [get_hexadecimal_valueof "argv" -1] + + if {$tagged_ptr == -1} { + untested "unexpected pointer or tag value" + return -1 + } + + # Test setting and showing the allocation tags + for {set i 0} {$i < 32} {incr i} { + + set tag_nn [get_tag_nn $i] + gdb_test "mtag setatag $tagged_ptr 0 ${tag_nn}" \ + $setatag_msg \ + "setatag with tag ${i}" + + set tag [get_hex_tag [expr $i % 16]] + gdb_test "mtag showatag $tagged_ptr" " = 0x${i}" \ + "showatag with tag ${i}" + } + + # Test tag mismatches. + with_test_prefix "tag mismatches" { + for {set i 0} {$i < 32} {incr i} { + + # Set the allocation tag to a known value. + set tag_nn [get_tag_nn $i] + gdb_test "mtag setatag $tagged_ptr 0 ${tag_nn}" \ + $setatag_msg \ + "setatag with tag ${i}" + + # Validate that the logical tag matches against the allocation + # tag. + set addr [get_tagged_ptr $i $tagged_ptr] + gdb_test "mtag check $addr" $check_msg \ + "check match with tag ${i}" + + # Get a pointer with the logical tag that does not match the + # allocation tag. + set ltag [expr $i + 1] + with_test_prefix "fetch mismatch tag" { + set addr [get_tagged_ptr $ltag $tagged_ptr] + } + + # Validate that the logical tag does not match the allocation + # tag. + set ltag [get_hex_tag [expr [expr $i + 1]% 16]] + set atag [get_hex_tag [expr $i % 16]] + gdb_test "mtag check $addr" \ + "Logical tag \\(0x${ltag}\\) does not match the allocation tag \\(0x${atag}\\)\." \ + "check mismatch with tag ${i}" + } + } + +} + +# Test the memory tagging extensions for the "print" command. +with_test_prefix "print command" { + set ptr_name "argv" + set tagged_ptr [get_hexadecimal_valueof $ptr_name -1] + + if {$tagged_ptr == -1} { + untested "unexpected pointer or tag value" + return -1 + } + + set ltag [get_ltag_from_ptr ${tagged_ptr}] + + if {$ltag == -1} { + untested "unexpected tag value" + return -1 + } + + set atag [expr [expr $ltag + 1] % 16] + set atag_nn [get_tag_nn $atag] + + gdb_test "mtag setatag $tagged_ptr 0 ${atag_nn}" \ + $setatag_msg \ + "make atag and ltag different" + + gdb_test "p $ptr_name" \ + [multi_line \ + "Logical tag \\(${ltag}\\) does not match Allocation tag \\(0x${atag}\\)\." \ + "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <.*>)?\[\r\n\]+"] \ + "show tag mismatch" +} + +# Test the memory tagging extensions for the "x" command. +with_test_prefix "x command" { + set ptr_name "argv" + + # Check if the allocation tags match what we expect. + gdb_test "x/gxm argv" \ + [multi_line \ + "<Allocation Tag $hex for range \\\[$hex,$hex\\)>" \ + "$hex:\[ \t\]+$hex"] \ + "outputs tag information" +} + +# Validate the presence of the MTE registers. +foreach reg {"sctlr" "gcr"} { + gdb_test "info registers $reg" \ + "$reg\[ \t\]+$hex\[ \t\]+$decimal" \ + "register $reg available" +} + +# Run until a crash and confirm GDB displays memory tag violation +# information. +gdb_test "continue" \ + [multi_line \ + "Memory tag violation while accessing address $hex" \ + "Logical tag $hex" \ + "Allocation tag $hex" \ + "$hex in main \\(argc=1, argv=0xfffffffff3b8\\) at .*"] \ + "display tag violation information" diff --git a/gdb/testsuite/gdb.base/memtag.c b/gdb/testsuite/gdb.base/memtag.c new file mode 100644 index 0000000..63a42ae --- /dev/null +++ b/gdb/testsuite/gdb.base/memtag.c @@ -0,0 +1,22 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2020 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 (int argc, char **argv) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/memtag.exp b/gdb/testsuite/gdb.base/memtag.exp new file mode 100644 index 0000000..657f40d --- /dev/null +++ b/gdb/testsuite/gdb.base/memtag.exp @@ -0,0 +1,59 @@ +# Copyright 2020 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/>. + +# Exercise the various bits of memory tagging support in GDB. + +# Return 0 if memory tagging is supported. +# Return 1 otherwise. + +set u_msg "Memory tagging not supported or disabled by the current architecture\." + +standard_testfile +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { + return -1 +} + +# Test commands without running the program. +with_test_prefix "before program execution" { + # These commands should all fails without a running program. + foreach subcmd {"setltag" "showltag" "setatag" "showatag" "check"} { + gdb_test "mtag $subcmd" "$u_msg" + } +} + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +# Targets that don't support memory tagging should not execute the +# runtime memory tagging tests. +if {![supports_memtag]} { + untested "memory tagging unsupported" + return -1 +} + +# With the program running, try to use the memory tagging commands. +with_test_prefix "during program execution" { + set msg "Argument required \\(address or pointer\\)\." + + # Test the various mtag commands again. + gdb_test "mtag showltag" $msg + gdb_test "mtag showatag" $msg + gdb_test "mtag setltag" "Arguments required \\(<address> <tag>\\)\." + gdb_test "mtag setatag" + "Arguments required \\(<starting address> <length> <tag bytes>\\)\." + gdb_test "mtag check" $msg +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index f502eb1..0e87c86 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -2613,6 +2613,22 @@ proc supports_get_siginfo_type {} { } } +# Return 1 if memory tagging is supported at runtime, otherwise return 0. + +proc supports_memtag {} { + global gdb_prompt + + gdb_test_multiple "mtag check" "" { + -re "Memory tagging not supported or disabled by the current architecture\..*$gdb_prompt $" { + return 0 + } + -re "Argument required \\(address or pointer\\).*$gdb_prompt $" { + return 1 + } + } + return 0 +} + # Return 1 if the target supports hardware single stepping. proc can_hardware_single_step {} { |