From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id tWLCIAqfsl9jYwAAWB0awg (envelope-from ) for ; Mon, 16 Nov 2020 10:47:22 -0500 Received: by simark.ca (Postfix, from userid 112) id 7EEB81F08B; Mon, 16 Nov 2020 10:47:22 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_NONE,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id B18641E552 for ; Mon, 16 Nov 2020 10:47:21 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 673B5385783C; Mon, 16 Nov 2020 15:47:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 673B5385783C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1605541641; bh=DzOc/DuXUiDRvzIBdUiAK3BRjpRKFEJI/xYjXH5rofo=; h=References:In-Reply-To:Date:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=vNWSzjncx9U+5je3z1RhM6l20x4ejICJxKt6Ce+39OXDftCHHVabNKEqZ+3zg3cK1 tF7dFQvn2rub7VQ/AApLAxOu+WfFCWXfi91sAkgIrs+sSwpB7mW+7yEqTuhu3BkR4B nJZvwoNoBrZPlKnybTI9q2j+BbOFQS5C7t/O7dZc= Received: from mail-vk1-xa42.google.com (mail-vk1-xa42.google.com [IPv6:2607:f8b0:4864:20::a42]) by sourceware.org (Postfix) with ESMTPS id A423B3858C27 for ; Mon, 16 Nov 2020 15:47:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A423B3858C27 Received: by mail-vk1-xa42.google.com with SMTP id i3so3804798vkk.11 for ; Mon, 16 Nov 2020 07:47:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=DzOc/DuXUiDRvzIBdUiAK3BRjpRKFEJI/xYjXH5rofo=; b=hoXlpFeIcDIqil9dNG0TnY5xVEBF7j7AlqPqqkrW1DxZOIqt9rEsVj0cT2EgDvlGbs ki9vVtsWqrgyZxhQdI72f5hTGnGtXUqqPv/aXC26+uPVQtxZK1lQeNzvLSaYbJdJKNy9 Hxr7jImnCMbqcH/QMF04zYJEQe3VWTBznAiR8hbi0yfX+PAQhLhDC47YfNiEEhqX9OG0 g+lM6Awc/kc8igJ3sCrlrfHna2I7F3nvhxbqf1/ww0ca7UPlgg2Meue67b9D7d0Z5Xb8 PjiQnfTsMgmUPQ0DQv1z0zdEc1kVBiBN8NBNh6AL0lnS5o/WqrDwtpyDDBp1YU4Rkvg+ EHvg== X-Gm-Message-State: AOAM531Sk+TE0Obd550UllTccb7kuGtc4jIQ8W78YtHU5mdTCc0hc+72 Al6QBirK+cBEwb95YsEK3D3ryrlFZqcCUtBIz2mbLw== X-Google-Smtp-Source: ABdhPJypZ4x98mayGwbcWCVeOixCS+oLeBo8lsnDeHxH6ASR6wvJyox2O33bnGhhzgREmi0u3uopWphrc4mSMPqWVwg= X-Received: by 2002:a05:6122:84f:: with SMTP id 15mr7661069vkk.25.1605541636907; Mon, 16 Nov 2020 07:47:16 -0800 (PST) MIME-Version: 1.0 References: <20201109170435.15766-1-luis.machado@linaro.org> <20201109170435.15766-25-luis.machado@linaro.org> In-Reply-To: <20201109170435.15766-25-luis.machado@linaro.org> Date: Mon, 16 Nov 2020 15:47:05 +0000 Message-ID: Subject: Re: [PATCH v3 24/24] Add memory tagging testcases To: Luis Machado Content-Type: text/plain; charset="UTF-8" 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: , From: David Spickett via Gdb-patches Reply-To: David Spickett Cc: gdb-patches@sourceware.org Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" (I've just skimmed through so not a review in any real way) In gdb/testsuite/gdb.arch/aarch64-mte.exp: +# 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. I assume this was left over from the original test file you adapted, it doesn't apply to MTE. On Mon, 9 Nov 2020 at 17:05, Luis Machado wrote: > > Add an AArch64-specific test and a more generic memory tagging test that > other architectures can run. > > Even though architectures not supporting memory tagging can run the memory > tagging tests, the runtime check will make the tests bail out early, as it > would make no sense to proceed without proper support. > > It is also tricky to do any further runtime tests for memory tagging, given > we'd need to deal with tags, and those are arch-specific. Therefore the > test in gdb.base is more of a smoke test. > > If an architecture wants to implement memory tagging, then it makes sense to > have tests within gdb.arch instead. > > gdb/testsuite/ChangeLog: > > YYYY-MM-DD Luis Machado > > * gdb.arch/aarch64-mte.c: New file. > * gdb.arch/aarch64-mte.exp: New test. > * gdb.base/memtag.c: New file. > * gdb.base/memtag.exp: New test. > * lib/gdb.exp (supports_memtag): New function. > --- > gdb/testsuite/gdb.arch/aarch64-mte.c | 107 +++++++ > gdb/testsuite/gdb.arch/aarch64-mte.exp | 371 +++++++++++++++++++++++++ > gdb/testsuite/gdb.base/memtag.c | 22 ++ > gdb/testsuite/gdb.base/memtag.exp | 64 +++++ > gdb/testsuite/lib/gdb.exp | 16 ++ > 5 files changed, 580 insertions(+) > create mode 100644 gdb/testsuite/gdb.arch/aarch64-mte.c > create mode 100644 gdb/testsuite/gdb.arch/aarch64-mte.exp > create mode 100644 gdb/testsuite/gdb.base/memtag.c > create mode 100644 gdb/testsuite/gdb.base/memtag.exp > > diff --git a/gdb/testsuite/gdb.arch/aarch64-mte.c b/gdb/testsuite/gdb.arch/aarch64-mte.c > new file mode 100644 > index 0000000000..f6fb4cca67 > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/aarch64-mte.c > @@ -0,0 +1,107 @@ > +/* 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 . */ > + > +/* Exercise AArch64's Memory Tagging Extension with tagged pointers. */ > + > +/* This test was based on the documentation for the AArch64 Memory Tagging > + Extension from the Linux Kernel, found in the sources in > + Documentation/arm64/memory-tagging-extension.rst. */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* From arch/arm64/include/uapi/asm/hwcap.h */ > +#define HWCAP2_MTE (1 << 18) > + > +/* From arch/arm64/include/uapi/asm/mman.h */ > +#define PROT_MTE 0x20 > + > +/* From include/uapi/linux/prctl.h */ > +#define PR_SET_TAGGED_ADDR_CTRL 55 > +#define PR_GET_TAGGED_ADDR_CTRL 56 > +#define PR_TAGGED_ADDR_ENABLE (1UL << 0) > +#define PR_MTE_TCF_SHIFT 1 > +#define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) > +#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) > +#define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT) > +#define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) > +#define PR_MTE_TAG_SHIFT 3 > +#define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) > + > +void > +access_memory (unsigned char *tagged_ptr, unsigned char *untagged_ptr) > +{ > + tagged_ptr[0] = 'a'; > +} > + > +int > +main (int argc, char **argv) > +{ > + unsigned char *tagged_ptr; > + unsigned char *untagged_ptr; > + unsigned long page_sz = sysconf (_SC_PAGESIZE); > + unsigned long hwcap2 = getauxval(AT_HWCAP2); > + > + /* Bail out if MTE is not supported. */ > + if (!(hwcap2 & HWCAP2_MTE)) > + return 1; > + > + /* Enable the tagged address ABI, synchronous MTE tag check faults and > + allow all non-zero tags in the randomly generated set. */ > + if (prctl (PR_SET_TAGGED_ADDR_CTRL, > + PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC > + | (0xfffe << PR_MTE_TAG_SHIFT), > + 0, 0, 0)) > + { > + perror ("prctl () failed"); > + return 1; > + } > + > + /* Create a mapping that will have PROT_MTE set. */ > + tagged_ptr = mmap (0, page_sz, PROT_READ | PROT_WRITE, > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > + if (tagged_ptr == MAP_FAILED) > + { > + perror ("mmap () failed"); > + return 1; > + } > + > + /* Create another mapping that won't have PROT_MTE set. */ > + untagged_ptr = mmap (0, page_sz, PROT_READ | PROT_WRITE, > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > + if (untagged_ptr == MAP_FAILED) > + { > + perror ("mmap () failed"); > + return 1; > + } > + > + /* Enable MTE on the above anonymous mmap. */ > + if (mprotect (tagged_ptr, page_sz, PROT_READ | PROT_WRITE | PROT_MTE)) > + { > + perror ("mprotect () failed"); > + return 1; > + } > + > + access_memory (tagged_ptr, untagged_ptr); > + > + 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 0000000000..39dba493fb > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/aarch64-mte.exp > @@ -0,0 +1,371 @@ > +# 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 . > + > +# 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 } { > + set addr [get_hexadecimal_valueof $ptr -1] > + return [get_valueof "/x" \ > + "${addr} & (0xf0ffffffffffffff) | ((unsigned long) ${tag} << 56)" \ > + "0" "fetch pointer ${ptr} with tag ${tag}"] > +} > + > +# Return the logical TAG from PTR. > +proc get_ltag_from_ptr { ptr } { > + set addr [get_hexadecimal_valueof $ptr -1] > + return [get_valueof "/x" "${addr} >> 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 > +} > + > +gdb_breakpoint "access_memory" > + > +if [gdb_continue "access_memory"] { > + fail "could not run to tagged memory test function" > + return -1 > +} > + > +# Fetch a known pointer to an area mapped with PROT_MTE. > +set tagged_ptr_symbol "tagged_ptr" > +set tagged_ptr_addr [get_hexadecimal_valueof $tagged_ptr_symbol -1] > + > +if {$tagged_ptr_addr == -1} { > + untested "unexpected pointer or tag value" > + return -1 > +} > + > +# Fetch a known pointer to an area not mapped with PROT_MTE. > +set untagged_ptr_symbol "untagged_ptr" > +set untagged_ptr_addr [get_hexadecimal_valueof $untagged_ptr_symbol -1] > + > +if {$untagged_ptr_addr == -1} { > + untested "unexpected pointer or tag value" > + return -1 > +} > + > +with_test_prefix "literals" { > + # Test inspecting an allocation tag from a pointer to a memory area that > + # is not mapped with PROT_MTE. > + set msg "Address ${untagged_ptr_addr} not in a region mapped with a memory tagging flag\." > + gdb_test "mtag showatag ${untagged_ptr_addr}" $msg \ > + "mtag showatag with an untagged address" > + > + gdb_test "mtag setatag ${untagged_ptr_addr} 0 00" $msg \ > + "mtag setatag with an untagged address" > + > + set addr_tagged 0 > + set addr_tagged_valid 0 > + > + # Test setting and showing the logical tags for a literal address. > + for {set i 0} {$i < 32} {incr i} { > + with_test_prefix "tag ${i}" { > + set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}] > + } > + > + set tag_hexnz [get_hex_tag [expr $i % 16]] > + gdb_test "mtag showltag ${addr_tagged}" \ > + " = 0x${tag_hexnz}" \ > + "showltag with tag ${i}" > + > + set tag_hexnn [get_tag_nn $i] > + gdb_test "mtag withltag ${addr_tagged} ${tag_hexnn}" \ > + " = \\(void \\*\\) ${addr_tagged}" \ > + "withltag with tag ${i}" > + } > + > + set setatag_msg "Allocation tag\\(s\\) updated successfully\." > + # Test setting and showing the allocation tags. > + for {set i 0} {$i < 32} {incr i} { > + > + set tag_hexnn [get_tag_nn $i] > + gdb_test "mtag setatag ${tagged_ptr_addr} 0 ${tag_hexnn}" \ > + $setatag_msg \ > + "setatag with tag ${i}" > + > + set tag_hexnz [get_hex_tag [expr $i % 16]] > + gdb_test "mtag showatag ${tagged_ptr_addr}" " = 0x${tag_hexnz}" \ > + "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_hexnn [get_tag_nn $i] > + gdb_test "mtag setatag ${tagged_ptr_addr} 0 ${tag_hexnn}" \ > + $setatag_msg \ > + "setatag with tag ${i}" > + > + set atag_hexnz [get_hex_tag [expr $i % 16]] > + > + # Validate that the logical tag matches the allocation tag. > + with_test_prefix "tag ${i}" { > + set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}] > + } > + > + gdb_test "mtag check ${addr_tagged}" \ > + "Memory tags for address $hex match \\(0x${atag_hexnz}\\)\." \ > + "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 ${i}" { > + set addr_tagged [get_tagged_ptr $ltag ${tagged_ptr_addr}] > + } > + > + # Validate that the logical tag does not match the allocation > + # tag. > + set ltag_hexnz [get_hex_tag [expr [expr $i + 1]% 16]] > + gdb_test "mtag check ${addr_tagged}" \ > + "Logical tag \\(0x${ltag_hexnz}\\) does not match the allocation tag \\(0x${atag_hexnz}\\) for address $hex\." \ > + "check mismatch with tag ${i}" > + } > + } > +} > + > +with_test_prefix "symbolic" { > + # Test inspecting an allocation tag from a pointer to a memory area that > + # is not mapped with PROT_MTE. > + set msg "Address ${untagged_ptr_addr} not in a region mapped with a memory tagging flag\." > + gdb_test "mtag showatag ${untagged_ptr_symbol}" $msg \ > + "mtag showatag with an untagged address" > + > + gdb_test "mtag setatag ${untagged_ptr_symbol} 0 00" $msg \ > + "mtag setatag with an untagged address" > + > + # Test setting and showing the logical tags for a literal address. > + for {set i 0} {$i < 32} {incr i} { > + set addr_tagged 0 > + > + with_test_prefix "tag ${i}" { > + set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}] > + gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${addr_tagged}" \ > + "update value of symbol ${tagged_ptr_symbol}" > + } > + > + set tag_hexnz [get_hex_tag [expr $i % 16]] > + gdb_test "mtag showltag ${tagged_ptr_symbol}" \ > + " = 0x${tag_hexnz}" \ > + "showltag with tag ${i}" > + > + set tag_hexnn [get_tag_nn $i] > + gdb_test "mtag withltag ${tagged_ptr_symbol} ${tag_hexnn}" \ > + " = \\(void \\*\\) ${addr_tagged}" \ > + "withltag with tag ${i}" > + } > + > + # Reset the tagged ptr to its original value > + gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${tagged_ptr_addr}" \ > + "reset ${tagged_ptr_symbol} to ${tagged_ptr_addr}" > + > + set setatag_msg "Allocation tag\\(s\\) updated successfully\." > + # Test setting and showing the allocation tags. > + for {set i 0} {$i < 32} {incr i} { > + > + set tag_hexnn [get_tag_nn $i] > + gdb_test "mtag setatag ${tagged_ptr_symbol} 0 ${tag_hexnn}" \ > + $setatag_msg \ > + "setatag with tag ${i}" > + > + set tag_hexnz [get_hex_tag [expr $i % 16]] > + gdb_test "mtag showatag ${tagged_ptr_symbol}" " = 0x${tag_hexnz}" \ > + "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 (0). > + set tag_hexnn [get_tag_nn $i] > + gdb_test "mtag setatag ${tagged_ptr_symbol} 0 ${tag_hexnn}" \ > + $setatag_msg \ > + "setatag with tag ${i}" > + > + set atag_hexnz [get_hex_tag [expr $i % 16]] > + > + # Validate that the logical tag matches the allocation tag. > + with_test_prefix "tag ${i}" { > + set addr_tagged [get_tagged_ptr $i ${tagged_ptr_addr}] > + } > + > + with_test_prefix "tag ${i}" { > + gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${addr_tagged}" \ > + "set ${tagged_ptr_symbol} to a matching logical tag" > + } > + > + gdb_test "mtag check ${tagged_ptr_symbol}" \ > + "Memory tags for address $hex match \\(0x${atag_hexnz}\\)\." \ > + "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 ${i}" { > + set addr_tagged [get_tagged_ptr $ltag ${tagged_ptr_addr}] > + } > + > + with_test_prefix "tag ${i}" { > + gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${addr_tagged}" \ > + "set ${tagged_ptr_symbol} to a mismatching logical tag" > + } > + > + # Validate that the logical tag does not match the allocation > + # tag. > + set ltag_hexnz [get_hex_tag [expr [expr $i + 1]% 16]] > + gdb_test "mtag check ${tagged_ptr_symbol}" \ > + "Logical tag \\(0x${ltag_hexnz}\\) does not match the allocation tag \\(0x${atag_hexnz}\\) for address $hex\." \ > + "check mismatch with tag ${i}" > + } > + # Reset the tagged ptr to its original value > + gdb_test_no_output "set variable ${tagged_ptr_symbol} = ${tagged_ptr_addr}" \ > + "reset ${tagged_ptr_symbol} to ${tagged_ptr_addr}" > + } > +} > + > +# Test the memory tagging extensions for the "print" command. > +with_test_prefix "print command" { > + set untagged_ptr [get_tagged_ptr 0 ${tagged_ptr_addr}] > + > + with_test_prefix "fetch ltag" { > + set ltag [get_ltag_from_ptr ${tagged_ptr_addr}] > + } > + > + if {$ltag == -1} { > + untested "unexpected tag value" > + return -1 > + } > + > + set atag [expr [expr $ltag + 1] % 16] > + set atag_hexnn [get_tag_nn $atag] > + > + gdb_test "mtag setatag ${tagged_ptr_symbol} 0 ${atag_hexnn}" \ > + $setatag_msg \ > + "make atag and ltag different" > + > + set atag_hexnz [get_hex_tag $atag] > + gdb_test "p/x ${tagged_ptr_symbol}" \ > + [multi_line \ > + "Logical tag \\(${ltag}\\) does not match the allocation tag \\(0x${atag_hexnz}\\)\." \ > + "\\\$\[0-9\]+ = ${untagged_ptr}"] \ > + "show tag mismatch" > +} > + > +# Test the memory tagging extensions for the "x" command. > +with_test_prefix "x command" { > + > + # Check if the allocation tags match what we expect. > + gdb_test "x/gxm ${tagged_ptr_symbol}" \ > + [multi_line \ > + "" \ > + "$hex:\[ \t\]+$hex"] \ > + "outputs tag information" > + > + # Also make sure no tag information is output for memory areas without > + # PROT_MTE mappings. > + gdb_test "x/gxm ${untagged_ptr_symbol}" \ > + "$hex:\[ \t\]+$hex" \ > + "does not output tag information" > +} > + > +# Validate the presence of the MTE registers. > +foreach reg {"tag_ctl" } { > + 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 \ > + "Program received signal SIGSEGV, Segmentation fault" \ > + "Memory tag violation while accessing address $hex" \ > + "Allocation tag $hex\." \ > + "$hex in access_memory \\(.*\\) at .*" \ > + ".*tagged_ptr\\\[0\\\] = 'a';"] \ > + "display tag violation information" > + > +# Restart to execute the async tag fault test. > +with_test_prefix "async" { > + if ![runto_main] { > + untested "could not run to main" > + return -1 > + } > + > + gdb_breakpoint "access_memory" > + > + if [gdb_continue "access_memory"] { > + fail "could not run to tagged memory test function" > + return -1 > + } > + > + # Force a tag fault. > + gdb_test "mtag setatag tagged_ptr 0 05" \ > + $setatag_msg \ > + "make atag and ltag different" > + > + # Force the tag fault to be async. > + gdb_test_no_output "set \$tag_ctl=0x7fff5" "set tag_ctl to async" > + > + # Run until a crash and confirm GDB displays memory tag violation > + # information for async mode > + gdb_test "continue" \ > + [multi_line \ > + "Program received signal SIGSEGV, Segmentation fault" \ > + "Memory tag violation" \ > + "Fault address unavailable\." \ > + "$hex in .* \\(.*\\) .*"] \ > + "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 0000000000..63a42ae278 > --- /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 . */ > + > +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 0000000000..484a78e828 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/memtag.exp > @@ -0,0 +1,64 @@ > +# 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 . > + > +# Smoke testing for the various memory tagging commands in GDB. > + > +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 > +} > + > +if {[target_info gdb_protocol] == "extended-remote"} { > + # Make sure we're disconnected, in case we're testing with an > + # extended-remote board, therefore already connected. > + gdb_test "disconnect" ".*" > +} > + > +# Test commands without running the program. > +with_test_prefix "before program execution" { > + # These commands should all fails without a running program. > + foreach subcmd {"withltag" "showltag" "setatag" "showatag" "check"} { > + gdb_test "mtag $subcmd" $u_msg > + } > +} > + > +clean_restart $testfile > + > +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 withltag" "Argument required \\(
\\)\." > + gdb_test "mtag setatag" \ > + "Argument required \\( \\)\." > + gdb_test "mtag check" $msg > +} > diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp > index 55154db6a5..347704ce0a 100644 > --- a/gdb/testsuite/lib/gdb.exp > +++ b/gdb/testsuite/lib/gdb.exp > @@ -2679,6 +2679,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 {} { > -- > 2.17.1 >