/* 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 is_address_tagged (gdbarch *gdbarch, CORE_ADDR address) override;
};
static aarch64_linux_nat_target the_aarch64_linux_nat_target;
return false;
}
+bool
+aarch64_linux_nat_target::is_address_tagged (gdbarch *gdbarch, CORE_ADDR address)
+{
+ /* Here we take a detour going to linux-tdep layer to read the smaps file,
+ because currently there isn't a better way to get that information to
+ check if a given address is tagged or not.
+
+ In the future, if this check is made, for instance, available via PTRACE,
+ it will be possible to drop the smaps path in favor of a PTRACE one for
+ this check. */
+ return gdbarch_tagged_address_p (gdbarch, address);
+}
+
void _initialize_aarch64_linux_nat ();
void
_initialize_aarch64_linux_nat ()
/* 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);
-
/* 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. */
/* 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;
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,
bool fetch_memtags (CORE_ADDR address, size_t len,
gdb::byte_vector &tags, int type) override;
+ /* If the architecture supports it, check if ADDRESS is within a memory range
+ mapped with tags. For example, MTE tags for AArch64. */
+ bool is_address_tagged (gdbarch *gdbarch, CORE_ADDR address) override;
+
x86_xsave_layout fetch_x86_xsave_layout () override;
/* A few helpers. */
return false;
}
+bool
+core_target::is_address_tagged (gdbarch *gdbarch, CORE_ADDR address)
+{
+ return gdbarch_tagged_address_p (gdbarch, address);
+}
+
/* Implementation of the "fetch_x86_xsave_layout" target_ops method. */
x86_xsave_layout
/* 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
}
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);
""",
type="bool",
name="tagged_address_p",
- params=[("struct value *", "address")],
+ params=[("CORE_ADDR", "address")],
predefault="default_tagged_address_p",
invalid=False,
)
= value_from_ulongest (builtin_type (gdbarch)->builtin_data_ptr,
tag_laddr);
- if (gdbarch_tagged_address_p (gdbarch, v_addr))
+ if (target_is_address_tagged (gdbarch, value_as_address (v_addr)))
{
/* Fetch the allocation tag. */
struct value *tag
/* Returns true if memory tags should be validated. False otherwise. */
static bool
-should_validate_memtags (struct value *value)
+should_validate_memtags (gdbarch *gdbarch, struct value *value)
{
gdb_assert (value != nullptr && value->type () != nullptr);
return false;
/* We do. Check whether it includes any tags. */
- return gdbarch_tagged_address_p (current_inferior ()->arch (), value);
+ return target_is_address_tagged (gdbarch, value_as_address (value));
}
/* Helper for parsing arguments for print_command_1. */
{
gdbarch *arch = current_inferior ()->arch ();
- if (should_validate_memtags (val)
+ if (should_validate_memtags (arch, val)
&& !gdbarch_memtag_matches_p (arch, val))
{
/* Fetch the logical tag. */
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_is_address_tagged (arch, 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);
/* 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_is_address_tagged (current_inferior ()-> arch(), addr))
+ show_addr_not_tagged (addr);
if (!gdbarch_set_memtags (current_inferior ()->arch (), val, length, tags,
memtag_type::allocation))
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_is_address_tagged (arch, addr))
+ show_addr_not_tagged (addr);
/* Check if the tag is valid. */
if (!gdbarch_memtag_matches_p (arch, val))
bool store_memtags (CORE_ADDR address, size_t len,
const gdb::byte_vector &tags, int type) override;
+ bool is_address_tagged (gdbarch *gdbarch, CORE_ADDR address) override;
+
public: /* Remote specific methods. */
void remote_download_command_source (int num, ULONGEST addr,
return packet_check_result (rs->buf, true).status () == PACKET_OK;
}
+/* Implement the "is_address_tagged" target_ops method. */
+
+bool
+remote_target::is_address_tagged (gdbarch *gdbarch, CORE_ADDR address)
+{
+ return gdbarch_tagged_address_p (gdbarch, address);
+}
+
/* Return true if remote target T is non-stop. */
bool
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 is_address_tagged (gdbarch *arg0, CORE_ADDR arg1) override;
x86_xsave_layout fetch_x86_xsave_layout () override;
};
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 is_address_tagged (gdbarch *arg0, CORE_ADDR arg1) override;
x86_xsave_layout fetch_x86_xsave_layout () override;
};
return result;
}
+bool
+target_ops::is_address_tagged (gdbarch *arg0, CORE_ADDR arg1)
+{
+ return this->beneath ()->is_address_tagged (arg0, arg1);
+}
+
+bool
+dummy_target::is_address_tagged (gdbarch *arg0, CORE_ADDR arg1)
+{
+ tcomplain ();
+}
+
+bool
+debug_target::is_address_tagged (gdbarch *arg0, CORE_ADDR arg1)
+{
+ gdb_printf (gdb_stdlog, "-> %s->is_address_tagged (...)\n", this->beneath ()->shortname ());
+ bool result
+ = this->beneath ()->is_address_tagged (arg0, arg1);
+ gdb_printf (gdb_stdlog, "<- %s->is_address_tagged (", this->beneath ()->shortname ());
+ target_debug_print_gdbarch_p (arg0);
+ gdb_puts (", ", gdb_stdlog);
+ target_debug_print_CORE_ADDR (arg1);
+ 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 ()
{
return current_inferior ()->top_target ()->store_memtags (address, len, tags, type);
}
+bool
+target_is_address_tagged (gdbarch *gdbarch, CORE_ADDR address)
+{
+ return current_inferior ()->top_target ()->is_address_tagged (gdbarch, address);
+}
+
x86_xsave_layout
target_fetch_x86_xsave_layout ()
{
const gdb::byte_vector &tags, int type)
TARGET_DEFAULT_NORETURN (tcomplain ());
+ /* Returns true if ADDRESS is tagged, otherwise returns false. */
+ virtual bool is_address_tagged (gdbarch *gdbarch, 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 ());
extern bool target_store_memtags (CORE_ADDR address, size_t len,
const gdb::byte_vector &tags, int type);
+extern bool target_is_address_tagged (gdbarch *gdbarch, CORE_ADDR address);
+
extern x86_xsave_layout target_fetch_x86_xsave_layout ();
/* Command logging facility. */