From patchwork Thu Mar 28 07:00:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Romero X-Patchwork-Id: 783588 Delivered-To: patch@linaro.org Received: by 2002:a5d:4e01:0:b0:33e:7753:30bd with SMTP id p1csp2573163wrt; Thu, 28 Mar 2024 00:02:46 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXmVYE0Du3xCtcABeMV1x7Pzugjviz8mxXv7ZRxN6VB4bgVyBmJPR/nJgZWVO7iQw26KC4InygnSRs/FpXzvDtU X-Google-Smtp-Source: AGHT+IFLwnGe/BSNTiaFy2OK9WjScuL1/psB7z0blEsztsg53LY48ro0Poh/sR83i2vBeIEHahms X-Received: by 2002:ae9:c206:0:b0:78a:4214:c570 with SMTP id j6-20020ae9c206000000b0078a4214c570mr1936450qkg.48.1711609365870; Thu, 28 Mar 2024 00:02:45 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1711609365; cv=pass; d=google.com; s=arc-20160816; b=dVsPNyy2tlp+qwPwNrjdcxWfLeEYbGsl8tqOp+jwC2am1MYcBL09V0kDNmfwF19+Q9 Y0JkE3wIBxRjyYv3Tw5F7P9GLzCHjfVlRzJQ7MUMRdhxy/CvYgDN37x2OfGVji0NuWR5 k2YWWAHrHwEc/mXn4tLN/ZHTL7C6w7UVYSjyLOuhSe/6udv5o07XZ9X+e/TXHHOet6fm OAOs6UQxqPt3ib+qijLtAZZlm6QMUPEeZi0jDLSwdK+LKw/dqhNRHJBfMzcdGh373rTa onwf8UpMKy/oNpRJ4bbElkYNA5qTWITAKIMhE+aT40SBaflmAW5I+px/Rl5B8xz8VDTv 8SbA== 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=t9wpyNHtdNH1k7QzmkpmpbKaNXwp0hO7JeNHnXBiFrk=; fh=ip7+QkkM488k9wyzFaZPu3h7BUQARzj44zdeG2KNIXU=; b=eQ85wcaRPkqStoUaI5Crrn+u/kRtX6vgd0qLm1enZT3AlryH5sxMdsz2XdrFgWnJAG zxsowYFZsiEBxV50e3DFTicGnyaBCCsmgEAO/FOMmTXNaZ6tFX4SCHu6RDWmH4yLFsxn BwUpII0D4GUnXsMQ8lik6a+06IHuvKH9OQMYYp/YMi3c1xPWXVLElnkC3WGrbr/wjqYb 1l/ag9B9irU7fgU5Swk5N9VTa9gnlo7cFc3LH/itS4zUNMuR1LTBIkga7NkcqdBKZWbw KPhhkCsipx/7qE4YDmCpcs1cmgJPG5BawgCIZeUxZjd8Thq/k/B1pJb43KsIRRQSKqIf 8eRg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=lA7aJ6NU; 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 pc4-20020a05620a840400b00789f61e3e39si827224qkn.74.2024.03.28.00.02.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Mar 2024 00:02:45 -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=lA7aJ6NU; 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 796553858C31 for ; Thu, 28 Mar 2024 07:02:45 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id CF8CB385E451 for ; Thu, 28 Mar 2024 07:01:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF8CB385E451 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 CF8CB385E451 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::636 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711609307; cv=none; b=oI9jQFlcWyYOOI4hGp0+ahSC9CUBKaE700Ro2mypsz6L9vI2gH8gRorTfuqkwuspzpcjLbTt+GeIPjHxIPh5q7M6htCKUy9aTM0xANLTOfEe3uGxQ6xJB24izf97Ep3h6SV3XHz+fgoHU3QWkeuAtX6l4luH4bevh0OQkpqfAJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711609307; c=relaxed/simple; bh=v7pya4SfuGPtlHQGcSzcCqPuSwKTKACscHghXIMCWFE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=GnywogDP+FO9MGXeUEsuPmb5lxPTL1aKzB3TKMmN2wr4MUA8LrGFpIUKoY61jMPjppElBTiwd4qsVFkKbOTbpWfcSjCWPU8RUYnvOZkM0uYunBhOKXGga0WNDiSM4wSDPP5ci1Ebjtr0VkTyrDAlumLcRd9GpWDBdFOCzAjqMss= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1e0b889901bso6109545ad.1 for ; Thu, 28 Mar 2024 00:01:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711609295; x=1712214095; 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=t9wpyNHtdNH1k7QzmkpmpbKaNXwp0hO7JeNHnXBiFrk=; b=lA7aJ6NUxTvIMoEwjxam69Kia34+Q/0RGjLzHy8iQg6WRnvbhAkQ4T2pNC5RLm3HHi cvHgLF0FRegyL9lB6YG9up5hZSR++1qYld08fbG1AbIdJX6wCVqHp80SZALmgAEHmKuZ oNlLApnCeT89IhQYKdE5kB9ZoOILv7H35N6ZOTioEK7NVbeWBHXy2X8ddZaOVbD9rT57 Dxvy6ufUyEch027hfZV3Q8j1bft4nLgdoXQAiK5BZ+/NoXcbegTS9da+xy7jjrPrxwUt TVlpA8EpupjKUQZq44CHl/7PFpe9XlVKHtpGr+a/818ZtFexSaOu7TCdaLpCr3w/DRBc 0siw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711609295; x=1712214095; 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=t9wpyNHtdNH1k7QzmkpmpbKaNXwp0hO7JeNHnXBiFrk=; b=EMmDW8CtkAOQ0puIr3feObzjMH+iprJIckDn57ipIWMMbzjILR/FecgK1Oeuy0XnSn J1AXcnrLmrjswXxAHJK2fH8L9CaDuNp1m5ibCoz0aJQ7LynZAkF+krgTxXYsV4luVOIv C/qy7tkA3MC/hCEVrwbvmtg5kbVIQGTnToXGaDusP/SSRlNV6waihiIYLLJ/a7zKGasc 6YNf6PiVns1WBuxOrNvOtDewB8z+WuMvmSrxgmqxnx/nGMuEEgBQdWU7ITOjp4IdlHq+ o3j4Rdhcvmrf/n07Nm22C6HV0CtvOgUJ6evcdunj96SlSNIBkgCbOZWp823XWWF0EbmQ k3iw== X-Gm-Message-State: AOJu0YytS7fjNwwZ9CB84+teqxqwra2JPTyNc4NJrLOHmtKhPaa8gJPA RX4pwovPqwQMp9dd/p89Jq7wpUqaZJ1v4J5CTrwTtBwvEtemQz8+jLSzD3lxK5YJ6Vp5iQhEr9Q X X-Received: by 2002:a17:902:6f02:b0:1e0:d0e8:b083 with SMTP id w2-20020a1709026f0200b001e0d0e8b083mr1600675plk.51.1711609295315; Thu, 28 Mar 2024 00:01:35 -0700 (PDT) Received: from amd.. ([2804:7f0:b402:41b2:3e7c:3fff:fe7a:e83b]) by smtp.gmail.com with ESMTPSA id b15-20020a170902650f00b001e014627baasm754252plk.79.2024.03.28.00.01.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Mar 2024 00:01:34 -0700 (PDT) From: Gustavo Romero To: gdb-patches@sourceware.org Cc: luis.machado@arm.com, thiago.bauermann@linaro.org, gustavo.romero@linaro.org Subject: [PATCH 4/4] gdb: Add new remote packet to check if address is tagged Date: Thu, 28 Mar 2024 07:00:55 +0000 Message-Id: <20240328070055.2578783-5-gustavo.romero@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240328070055.2578783-1-gustavo.romero@linaro.org> References: <20240328070055.2578783-1-gustavo.romero@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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 This commit adds a new packet qMemTagAddrCheck allowing GDB remote targets to use it to query gdbservers if a given address is tagged. It also adds a new GDB remote feature, 'memory-tagging-check-add+', which must be advertised by the GDB servers to inform GDB they can reply to address checks via the new qMemTagAddrCheck remote packet. Currently, this address check is done via a read query, where the contents of /proc//smaps is read and the flags in there are inspected for MTE-related flags that indicate the address is in a tagged memory region. This is not ideal, for example, on QEMU gdbstub and in other cases, like in baremetal debugging, where there is no notion of any OS file like smaps. Hence, qMemTagAddrCheck packet allows check addresses in an OS-agnostic way. For supporting the new packet, a new target hook is introduced, check_memtag_addr, which is used instead of the gdbarch_tagged_address_p gdbarch hook in the upper layers (printcmd.c). The new target hook is then specialized per target, for remote.c, aarch64-linux-nat.c, and corelow.c targets (the current targets that are MTE-aware). The target hook in remote.c uses the qMemTagAddrCheck packet to check an address if the server advertised the 'memory-tagging-check-add+' feature, otherwise it falls back to using the current mechanism, i.e. it reads the /proc//smaps contents. In the aarch64-linux-nat.c and corelow.c the target hook uses the gdbarch_tagged_address_p gdbarch hook, so there is no change regarding how an address is checked in these targets. Just the gdbarch_tagged_address_p signature is changed for convenience, since target_check_memtag_addr takes the address to be checked as a CORE_ADDR type. Signed-off-by: Gustavo Romero --- gdb/aarch64-linux-nat.c | 8 +++++ gdb/aarch64-linux-tdep.c | 10 +++---- gdb/arch-utils.c | 2 +- gdb/arch-utils.h | 2 +- gdb/corelow.c | 8 +++++ gdb/gdbarch-gen.h | 4 +-- gdb/gdbarch.c | 2 +- gdb/gdbarch_components.py | 2 +- gdb/printcmd.c | 27 +++++++++-------- gdb/remote.c | 62 +++++++++++++++++++++++++++++++++++++++ gdb/target-delegates.c | 28 ++++++++++++++++++ gdb/target.c | 6 ++++ gdb/target.h | 6 ++++ 13 files changed, 143 insertions(+), 24 deletions(-) diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 3face34ce79..1c64df6af41 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -110,6 +110,8 @@ class aarch64_linux_nat_target final /* Write allocation tags to memory via PTRACE. */ bool store_memtags (CORE_ADDR address, size_t len, const gdb::byte_vector &tags, int type) override; + /* Check if an address is tagged. */ + bool check_memtag_addr (CORE_ADDR address) override; }; static aarch64_linux_nat_target the_aarch64_linux_nat_target; @@ -1071,6 +1073,12 @@ aarch64_linux_nat_target::store_memtags (CORE_ADDR address, size_t len, return false; } +bool +aarch64_linux_nat_target::check_memtag_addr (CORE_ADDR address) +{ + return gdbarch_tagged_address_p (current_inferior ()->arch (), address); +} + void _initialize_aarch64_linux_nat (); void _initialize_aarch64_linux_nat () diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index fc60e602748..2a47c3f0845 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -2451,17 +2451,15 @@ aarch64_mte_get_atag (CORE_ADDR address) /* Implement the tagged_address_p gdbarch method. */ static bool -aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, struct value *address) +aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address) { - gdb_assert (address != nullptr); - - CORE_ADDR addr = value_as_address (address); + gdb_assert (address); /* Remove the top byte for the memory range check. */ - addr = gdbarch_remove_non_address_bits (gdbarch, addr); + address = gdbarch_remove_non_address_bits (gdbarch, address); /* Check if the page that contains ADDRESS is mapped with PROT_MTE. */ - if (!linux_address_in_memtag_page (addr)) + if (!linux_address_in_memtag_page (address)) return false; /* We have a valid tag in the top byte of the 64-bit address. */ diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 456bfe971ff..cb149c36bc9 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -102,7 +102,7 @@ default_memtag_to_string (struct gdbarch *gdbarch, struct value *tag) /* See arch-utils.h */ bool -default_tagged_address_p (struct gdbarch *gdbarch, struct value *address) +default_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address) { /* By default, assume the address is untagged. */ return false; diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 2dcd8f6dc53..467be40c688 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -141,7 +141,7 @@ extern std::string default_memtag_to_string (struct gdbarch *gdbarch, struct value *tag); /* Default implementation of gdbarch_tagged_address_p. */ -bool default_tagged_address_p (struct gdbarch *gdbarch, struct value *address); +bool default_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address); /* Default implementation of gdbarch_memtag_matches_p. */ extern bool default_memtag_matches_p (struct gdbarch *gdbarch, diff --git a/gdb/corelow.c b/gdb/corelow.c index f4e8273d962..676738825fb 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -109,6 +109,8 @@ class core_target final : public process_stratum_target bool fetch_memtags (CORE_ADDR address, size_t len, gdb::byte_vector &tags, int type) override; + bool check_memtag_addr (CORE_ADDR address) override; + x86_xsave_layout fetch_x86_xsave_layout () override; /* A few helpers. */ @@ -1410,6 +1412,12 @@ core_target::fetch_memtags (CORE_ADDR address, size_t len, return false; } +bool +core_target::check_memtag_addr (CORE_ADDR address) +{ + return gdbarch_tagged_address_p (current_inferior ()->arch (), address); +} + /* Implementation of the "fetch_x86_xsave_layout" target_ops method. */ x86_xsave_layout diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index ebcff80bb9e..63fab26987f 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -707,8 +707,8 @@ extern void set_gdbarch_memtag_to_string (struct gdbarch *gdbarch, gdbarch_memta /* Return true if ADDRESS contains a tag and false otherwise. ADDRESS must be either a pointer or a reference type. */ -typedef bool (gdbarch_tagged_address_p_ftype) (struct gdbarch *gdbarch, struct value *address); -extern bool gdbarch_tagged_address_p (struct gdbarch *gdbarch, struct value *address); +typedef bool (gdbarch_tagged_address_p_ftype) (struct gdbarch *gdbarch, CORE_ADDR address); +extern bool gdbarch_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address); extern void set_gdbarch_tagged_address_p (struct gdbarch *gdbarch, gdbarch_tagged_address_p_ftype *tagged_address_p); /* Return true if the tag from ADDRESS matches the memory tag for that diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 9319571deba..2d92f604c49 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -3232,7 +3232,7 @@ set_gdbarch_memtag_to_string (struct gdbarch *gdbarch, } bool -gdbarch_tagged_address_p (struct gdbarch *gdbarch, struct value *address) +gdbarch_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->tagged_address_p != NULL); diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 7d913ade621..24e979431b6 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -1267,7 +1267,7 @@ must be either a pointer or a reference type. """, type="bool", name="tagged_address_p", - params=[("struct value *", "address")], + params=[("CORE_ADDR", "address")], predefault="default_tagged_address_p", invalid=False, ) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index ae4d640ccf2..c81c75afc5d 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1132,7 +1132,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) = value_from_ulongest (builtin_type (gdbarch)->builtin_data_ptr, tag_laddr); - if (gdbarch_tagged_address_p (current_inferior ()->arch (), v_addr)) + if (target_check_memtag_addr (value_as_address(v_addr))) { /* Fetch the allocation tag. */ struct value *tag @@ -1289,7 +1289,7 @@ should_validate_memtags (struct value *value) return false; /* We do. Check whether it includes any tags. */ - return gdbarch_tagged_address_p (current_inferior ()->arch (), value); + return target_check_memtag_addr (value_as_address(value)); } /* Helper for parsing arguments for print_command_1. */ @@ -2946,9 +2946,10 @@ memory_tag_print_tag_command (const char *args, enum memtag_type tag_type) flag, it is no use trying to access/manipulate its allocation tag. It is OK to manipulate the logical tag though. */ + CORE_ADDR addr = value_as_address(val); if (tag_type == memtag_type::allocation - && !gdbarch_tagged_address_p (arch, val)) - show_addr_not_tagged (value_as_address (val)); + && !target_check_memtag_addr(addr)) + show_addr_not_tagged (addr); value *tag_value = gdbarch_get_memtag (arch, val, tag_type); std::string tag = gdbarch_memtag_to_string (arch, tag_value); @@ -3104,8 +3105,9 @@ parse_set_allocation_tag_input (const char *args, struct value **val, /* If the address is not in a region memory mapped with a memory tagging flag, it is no use trying to access/manipulate its allocation tag. */ - if (!gdbarch_tagged_address_p (current_inferior ()->arch (), *val)) - show_addr_not_tagged (value_as_address (*val)); + CORE_ADDR addr = value_as_address (*val); + if (!target_check_memtag_addr (addr)) + show_addr_not_tagged (addr); } /* Implement the "memory-tag set-allocation-tag" command. @@ -3129,8 +3131,9 @@ memory_tag_set_allocation_tag_command (const char *args, int from_tty) /* If the address is not in a region memory mapped with a memory tagging flag, it is no use trying to manipulate its allocation tag. */ - if (!gdbarch_tagged_address_p (current_inferior ()->arch (), val)) { - show_addr_not_tagged (value_as_address(val)); + CORE_ADDR addr = value_as_address (val); + if (!target_check_memtag_addr (addr)) { + show_addr_not_tagged (addr); } if (!gdbarch_set_memtags (current_inferior ()->arch (), val, length, tags, @@ -3158,12 +3161,12 @@ memory_tag_check_command (const char *args, int from_tty) struct value *val = process_print_command_args (args, &print_opts, true); gdbarch *arch = current_inferior ()->arch (); + CORE_ADDR addr = value_as_address (val); + /* If the address is not in a region memory mapped with a memory tagging flag, it is no use trying to access/manipulate its allocation tag. */ - if (!gdbarch_tagged_address_p (arch, val)) - show_addr_not_tagged (value_as_address (val)); - - CORE_ADDR addr = value_as_address (val); + if (!target_check_memtag_addr (addr)) + show_addr_not_tagged (addr); /* Check if the tag is valid. */ if (!gdbarch_memtag_matches_p (arch, val)) diff --git a/gdb/remote.c b/gdb/remote.c index e278711df7b..264adb686f8 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -337,6 +337,9 @@ enum { packets and the tag violation stop replies. */ PACKET_memory_tagging_feature, + /* Support checking if an address is tagged via qMemTagAddrCheck packet. */ + PACKET_memory_tagging_check_addr_feature, + PACKET_MAX }; @@ -758,6 +761,10 @@ struct remote_features bool remote_memory_tagging_p () const { return packet_support (PACKET_memory_tagging_feature) == PACKET_ENABLE; } + bool remote_memory_tagging_check_addr_p () const + { return packet_support (PACKET_memory_tagging_check_addr_feature) == + PACKET_ENABLE; } + /* Reset all packets back to "unknown support". Called when opening a new connection to a remote target. */ void reset_all_packet_configs_support (); @@ -1084,6 +1091,8 @@ class remote_target : public process_stratum_target bool store_memtags (CORE_ADDR address, size_t len, const gdb::byte_vector &tags, int type) override; + bool check_memtag_addr (CORE_ADDR address) override; + public: /* Remote specific methods. */ void remote_download_command_source (int num, ULONGEST addr, @@ -5762,6 +5771,8 @@ static const struct protocol_feature remote_protocol_features[] = { { "no-resumed", PACKET_DISABLE, remote_supported_packet, PACKET_no_resumed }, { "memory-tagging", PACKET_DISABLE, remote_supported_packet, PACKET_memory_tagging_feature }, + { "memory-tagging-check-addr", PACKET_DISABLE, remote_supported_packet, + PACKET_memory_tagging_check_addr_feature }, }; static char *remote_support_xml; @@ -5873,6 +5884,10 @@ remote_target::remote_query_supported () != AUTO_BOOLEAN_FALSE) remote_query_supported_append (&q, "memory-tagging+"); + if (m_features.packet_set_cmd_state (PACKET_memory_tagging_check_addr_feature) + != AUTO_BOOLEAN_FALSE) + remote_query_supported_append (&q, "memory-tagging-check-addr+"); + /* Keep this one last to work around a gdbserver <= 7.10 bug in the qSupported:xmlRegisters=i386 handling. */ if (remote_support_xml != NULL @@ -15532,6 +15547,19 @@ create_store_memtags_request (gdb::char_vector &packet, CORE_ADDR address, strcpy (packet.data (), request.c_str ()); } +static void +create_check_memtag_addr_request (gdb::char_vector &packet, CORE_ADDR address) +{ + int addr_size = gdbarch_addr_bit (current_inferior ()->arch()) / 8; + + std::string request = string_printf ("qMemTagAddrCheck:%s", phex_nz (address, addr_size)); + + if (packet.size () < request.length ()) + error (_("Contents too big for packet qMemTagAddrCheck.")); + + strcpy (packet.data (), request.c_str ()); +} + /* Implement the "fetch_memtags" target_ops method. */ bool @@ -15573,6 +15601,36 @@ remote_target::store_memtags (CORE_ADDR address, size_t len, return packet_check_result (rs->buf).status () == PACKET_OK; } +bool +remote_target::check_memtag_addr (CORE_ADDR address) +{ + struct remote_state *rs = get_remote_state (); + + if (!m_features.remote_memory_tagging_check_addr_p ()) + /* Fallback to reading /proc//smaps for checking if an address is + tagged or not. */ + return gdbarch_tagged_address_p (current_inferior ()->arch (), address); + + create_check_memtag_addr_request (rs->buf, address); + + putpkt (rs->buf); + getpkt (&rs->buf); + + /* Check if reply is OK. */ + if ((packet_check_result (rs->buf.data ()) != PACKET_OK) || rs->buf.empty()) + return false; + + gdb_byte tagged_addr; + /* Convert only 2 hex digits, i.e. 1 byte in hex format. */ + hex2bin(rs->buf.data(), &tagged_addr , 1); + if (tagged_addr) + /* 01 means address is tagged. */ + return true; + else + /* 00 means address is not tagged. */ + return false; +} + /* Return true if remote target T is non-stop. */ bool @@ -16056,6 +16114,10 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (PACKET_memory_tagging_feature, "memory-tagging-feature", "memory-tagging-feature", 0); + add_packet_config_cmd (PACKET_memory_tagging_check_addr_feature, + "memory-tagging-check-addr-feature", + "memory-tagging-check-addr-feature", 0); + /* Assert that we've registered "set remote foo-packet" commands for all packet configs. */ { diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index 59ea70458ad..fbd9e3f65b4 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -197,6 +197,7 @@ struct dummy_target : public target_ops bool supports_memory_tagging () override; bool fetch_memtags (CORE_ADDR arg0, size_t arg1, gdb::byte_vector &arg2, int arg3) override; bool store_memtags (CORE_ADDR arg0, size_t arg1, const gdb::byte_vector &arg2, int arg3) override; + bool check_memtag_addr (CORE_ADDR arg0) override; x86_xsave_layout fetch_x86_xsave_layout () override; }; @@ -373,6 +374,7 @@ struct debug_target : public target_ops bool supports_memory_tagging () override; bool fetch_memtags (CORE_ADDR arg0, size_t arg1, gdb::byte_vector &arg2, int arg3) override; bool store_memtags (CORE_ADDR arg0, size_t arg1, const gdb::byte_vector &arg2, int arg3) override; + bool check_memtag_addr (CORE_ADDR arg0) override; x86_xsave_layout fetch_x86_xsave_layout () override; }; @@ -4562,6 +4564,32 @@ debug_target::store_memtags (CORE_ADDR arg0, size_t arg1, const gdb::byte_vector return result; } +bool +target_ops::check_memtag_addr (CORE_ADDR arg0) +{ + return this->beneath ()->check_memtag_addr (arg0); +} + +bool +dummy_target::check_memtag_addr (CORE_ADDR arg0) +{ + tcomplain (); +} + +bool +debug_target::check_memtag_addr (CORE_ADDR arg0) +{ + gdb_printf (gdb_stdlog, "-> %s->check_memtag_addr (...)\n", this->beneath ()->shortname ()); + bool result + = this->beneath ()->check_memtag_addr (arg0); + gdb_printf (gdb_stdlog, "<- %s->check_memtag_addr (", this->beneath ()->shortname ()); + target_debug_print_CORE_ADDR (arg0); + gdb_puts (") = ", gdb_stdlog); + target_debug_print_bool (result); + gdb_puts ("\n", gdb_stdlog); + return result; +} + x86_xsave_layout target_ops::fetch_x86_xsave_layout () { diff --git a/gdb/target.c b/gdb/target.c index 107a84b3ca1..938a0f76595 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -796,6 +796,12 @@ target_store_memtags (CORE_ADDR address, size_t len, return current_inferior ()->top_target ()->store_memtags (address, len, tags, type); } +bool +target_check_memtag_addr (CORE_ADDR address) +{ + return current_inferior ()->top_target ()->check_memtag_addr (address); +} + x86_xsave_layout target_fetch_x86_xsave_layout () { diff --git a/gdb/target.h b/gdb/target.h index c9eaff16346..bb64d32994e 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -1334,6 +1334,10 @@ struct target_ops const gdb::byte_vector &tags, int type) TARGET_DEFAULT_NORETURN (tcomplain ()); + /* Returns true if ADDRESS is tagged, otherwise returns false. */ + virtual bool check_memtag_addr (CORE_ADDR address) + TARGET_DEFAULT_NORETURN (tcomplain ()); + /* Return the x86 XSAVE extended state area layout. */ virtual x86_xsave_layout fetch_x86_xsave_layout () TARGET_DEFAULT_RETURN (x86_xsave_layout ()); @@ -2317,6 +2321,8 @@ extern bool target_fetch_memtags (CORE_ADDR address, size_t len, extern bool target_store_memtags (CORE_ADDR address, size_t len, const gdb::byte_vector &tags, int type); +extern bool target_check_memtag_addr (CORE_ADDR address); + extern x86_xsave_layout target_fetch_x86_xsave_layout (); /* Command logging facility. */