From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id XYcqJBeusl9wZQAAWB0awg (envelope-from ) for ; Mon, 16 Nov 2020 11:51:35 -0500 Received: by simark.ca (Postfix, from userid 112) id 899DB1F08B; Mon, 16 Nov 2020 11:51:35 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [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 DEEE31E58F for ; Mon, 16 Nov 2020 11:51:33 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7B7CC3958C2A; Mon, 16 Nov 2020 16:51:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7B7CC3958C2A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1605545493; bh=kTgjauAQ6nmRkVM6831qsu/fuMHlUCqrmQyLVpWVDI8=; h=Subject:To:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=CaXvXIafekl2K9nMpf/jURDGmmPXXywQnTQdTZFaiS+j66INvFFZ83ruGs+yjb/nY FPyTP09OQZPcbdCbWJdhA03ZIzbk/cXRscCPhnM6PIa/n+7A7HTHLRwARem91hZtaa DVw05LsYvpnMr1sBVxdAfmjOa4JJiq8y026lkN9o= Received: from mail-qt1-x844.google.com (mail-qt1-x844.google.com [IPv6:2607:f8b0:4864:20::844]) by sourceware.org (Postfix) with ESMTPS id E72033854827 for ; Mon, 16 Nov 2020 16:51:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E72033854827 Received: by mail-qt1-x844.google.com with SMTP id j31so13312976qtb.8 for ; Mon, 16 Nov 2020 08:51:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=kTgjauAQ6nmRkVM6831qsu/fuMHlUCqrmQyLVpWVDI8=; b=G1EfUvV3FgSjbZKiPK71yoGC7V0yqLB5EfvbY6N31AZt1J0IUAdEA6LYNcUcrC2Nxl 09DXIuOaKLkW0UqM5oLlQ/1ZNSlek4v5vFm8RVU6gygMPn3i3C/i81YSJyhLM/R5/vuG qAG8jtoQHIYgcODVKzapeGkC1ojQC3zAbPNWsC5r/dHkBFurfzM2ubvO3OYW1XnmBLsl 4KMKVI1giAu2TleP0JpxFM5pBoK9UUDETjSZBLRqbcwkVOWU8yX4pwQweTXs3s0DPHAq udtwTjHINvrBvV7FOn7As+6Nz0iJBqwMKAlkUKeMv0OvMj1s9RavqHcqHuJxXg3n9qUP Y2CA== X-Gm-Message-State: AOAM533x5VwbXyiCFP9UoZlW/yUsPuBm/R8zrKZQVarSF8C74kCgsjeS pc/vxuAoC4/jmntwQA9Xsq9mbg== X-Google-Smtp-Source: ABdhPJzzQNYQmowKgo5WbP6xV1Xae68dxVgkppH67NebAikjvdUXJD4YmThGUhoRMKEbjLcklZlZZQ== X-Received: by 2002:ac8:705b:: with SMTP id y27mr14939849qtm.192.1605545487956; Mon, 16 Nov 2020 08:51:27 -0800 (PST) Received: from ?IPv6:2804:7f0:8284:1487:34cb:6ef2:6b7f:4db2? ([2804:7f0:8284:1487:34cb:6ef2:6b7f:4db2]) by smtp.gmail.com with ESMTPSA id u24sm12164346qtv.83.2020.11.16.08.51.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 16 Nov 2020 08:51:27 -0800 (PST) Subject: Re: [PATCH v3 24/24] Add memory tagging testcases To: David Spickett References: <20201109170435.15766-1-luis.machado@linaro.org> <20201109170435.15766-25-luis.machado@linaro.org> Message-ID: Date: Mon, 16 Nov 2020 13:51:24 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit 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: Luis Machado via Gdb-patches Reply-To: Luis Machado Cc: gdb-patches@sourceware.org Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" On 11/16/20 12:47 PM, David Spickett wrote: > (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. > Indeed. Fixed now. > 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 >>