From: Luis Machado <luis.machado@linaro.org>
To: gdb-patches@sourceware.org
Subject: [PATCH v5 05/25] GDBserver remote packet support for memory tagging
Date: Wed, 27 Jan 2021 17:20:52 -0300 [thread overview]
Message-ID: <20210127202112.2485702-6-luis.machado@linaro.org> (raw)
In-Reply-To: <20210127202112.2485702-1-luis.machado@linaro.org>
Updates on v4:
- Updated naming of helper functions.
- Updated return types from int to bool.
- Removed return type for functions not returning a value.
- Updated code documentation.
Updates on v2:
- Update target methods to contain a tag type field.
- Update remote packet processing to parse the type field.
--
This patch adds the generic remote bits to gdbserver so it can check for memory
tagging support and handle fetch tags and store tags requests.
gdbserver/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org>
* remote-utils.cc (decode_m_packet_params): Renamed from ...
(decode_m_packet): ... this, which now calls decode_m_packet_params.
Make char * param/return const char *.
(decode_M_packet): Use decode_m_packet_params and make char * param
const char *.
* remote-utils.h (decode_m_packet_params): New prototype.
(decode_m_packet): Constify char pointers.
(decode_M_packet): Likewise.
* server.cc (create_fetch_memtags_reply)
(parse_store_memtags_request): New
functions.
(handle_general_set): Handle the QMemTags packet.
(parse_fetch_memtags_request): New function.
(handle_query): Handle the qMemTags packet and advertise memory
tagging support.
(captured_main): Initialize memory tagging flag.
* server.h (struct client_state): Initialize memory tagging flag.
* target.cc (process_stratum_target::supports_memory_tagging)
(process_stratum_target::fetch_memtags)
(process_stratum_target::store_memtags): New methods.
* target.h: Include gdbsupport/byte-vector.h.
(class process_stratum_target) <supports_memory_tagging>
<fetch_memtags, store_memtags>: New class virtual methods.
(target_supports_memory_tagging): Define.
---
gdbserver/remote-utils.cc | 43 ++++++------
gdbserver/remote-utils.h | 7 +-
gdbserver/server.cc | 141 ++++++++++++++++++++++++++++++++++++++
gdbserver/server.h | 3 +
gdbserver/target.cc | 20 ++++++
gdbserver/target.h | 21 ++++++
6 files changed, 210 insertions(+), 25 deletions(-)
diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc
index cfdf1c1883..4e76f08ac5 100644
--- a/gdbserver/remote-utils.cc
+++ b/gdbserver/remote-utils.cc
@@ -1304,10 +1304,14 @@ prepare_resume_reply (char *buf, ptid_t ptid,
}
}
-void
-decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
+/* Decode ADDR and LEN from a parameter of the form "addr,len<x>", with <x>
+ being an end marker character. */
+
+const char *
+decode_m_packet_params (const char *from, CORE_ADDR *mem_addr_ptr,
+ unsigned int *len_ptr, const char end_marker)
{
- int i = 0, j = 0;
+ int i = 0;
char ch;
*mem_addr_ptr = *len_ptr = 0;
@@ -1317,39 +1321,32 @@ decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
*mem_addr_ptr |= fromhex (ch) & 0x0f;
}
- for (j = 0; j < 4; j++)
+ while ((ch = from[i++]) != end_marker)
{
- if ((ch = from[i++]) == 0)
- break;
*len_ptr = *len_ptr << 4;
*len_ptr |= fromhex (ch) & 0x0f;
}
+
+ return from + i;
}
void
-decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
- unsigned char **to_p)
+decode_m_packet (const char *from, CORE_ADDR *mem_addr_ptr,
+ unsigned int *len_ptr)
{
- int i = 0;
- char ch;
- *mem_addr_ptr = *len_ptr = 0;
-
- while ((ch = from[i++]) != ',')
- {
- *mem_addr_ptr = *mem_addr_ptr << 4;
- *mem_addr_ptr |= fromhex (ch) & 0x0f;
- }
+ decode_m_packet_params (from, mem_addr_ptr, len_ptr, '\0');
+}
- while ((ch = from[i++]) != ':')
- {
- *len_ptr = *len_ptr << 4;
- *len_ptr |= fromhex (ch) & 0x0f;
- }
+void
+decode_M_packet (const char *from, CORE_ADDR *mem_addr_ptr,
+ unsigned int *len_ptr, unsigned char **to_p)
+{
+ from = decode_m_packet_params (from, mem_addr_ptr, len_ptr, ':');
if (*to_p == NULL)
*to_p = (unsigned char *) xmalloc (*len_ptr);
- hex2bin (&from[i++], *to_p, *len_ptr);
+ hex2bin (from, *to_p, *len_ptr);
}
int
diff --git a/gdbserver/remote-utils.h b/gdbserver/remote-utils.h
index 5a8e764cbc..59d77b750c 100644
--- a/gdbserver/remote-utils.h
+++ b/gdbserver/remote-utils.h
@@ -45,9 +45,12 @@ void prepare_resume_reply (char *buf, ptid_t ptid,
const char *decode_address_to_semicolon (CORE_ADDR *addrp, const char *start);
void decode_address (CORE_ADDR *addrp, const char *start, int len);
-void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr,
+const char *decode_m_packet_params (const char *from, CORE_ADDR *mem_addr_ptr,
+ unsigned int *len_ptr,
+ const char end_marker);
+void decode_m_packet (const char *from, CORE_ADDR * mem_addr_ptr,
unsigned int *len_ptr);
-void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
+void decode_M_packet (const char *from, CORE_ADDR * mem_addr_ptr,
unsigned int *len_ptr, unsigned char **to_p);
int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr,
unsigned int *len_ptr, unsigned char **to_p);
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 77e89fe6ed..69635742a8 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -547,12 +547,71 @@ handle_btrace_conf_general_set (char *own_buf)
return 1;
}
+/* Create the qMemTags packet reply given TAGS.
+
+ Returns true if parsing succeeded and false otherwise. */
+
+static bool
+create_fetch_memtags_reply (char *reply, const gdb::byte_vector &tags)
+{
+ /* It is an error to pass a zero-sized tag vector. */
+ gdb_assert (tags.size () != 0);
+
+ std::string packet ("m");
+
+ /* Write the tag data. */
+ packet += bin2hex (tags.data (), tags.size ());
+
+ /* Check if the reply is too big for the packet to handle. */
+ if (PBUFSIZ < packet.size ())
+ return false;
+
+ strcpy (reply, packet.c_str ());
+ return true;
+}
+
+/* Parse the QMemTags request into ADDR, LEN and TAGS.
+
+ Returns true if parsing succeeded and false otherwise. */
+
+static bool
+parse_store_memtags_request (char *request, CORE_ADDR *addr, size_t *len,
+ gdb::byte_vector &tags, int *type)
+{
+ gdb_assert (startswith (request, "QMemTags:"));
+
+ const char *p = request + strlen ("QMemTags:");
+
+ /* Read address and length. */
+ unsigned int length = 0;
+ p = decode_m_packet_params (p, addr, &length, ':');
+ *len = length;
+
+ /* Read the tag type. */
+ ULONGEST tag_type = 0;
+ p = unpack_varlen_hex (p, &tag_type);
+ *type = (int) tag_type;
+
+ /* Make sure there is a colon after the type. */
+ if (*p != ':')
+ return false;
+
+ /* Skip the colon. */
+ p++;
+
+ /* Read the tag data. */
+ tags = hex2bin (p);
+
+ return true;
+}
+
/* Handle all of the extended 'Q' packets. */
static void
handle_general_set (char *own_buf)
{
client_state &cs = get_client_state ();
+
if (startswith (own_buf, "QPassSignals:"))
{
int numsigs = (int) GDB_SIGNAL_LAST, i;
@@ -903,6 +962,32 @@ handle_general_set (char *own_buf)
return;
}
+
+ /* Handle store memory tags packets. */
+ if (startswith (own_buf, "QMemTags:")
+ && target_supports_memory_tagging ())
+ {
+ gdb::byte_vector tags;
+ CORE_ADDR addr = 0;
+ size_t len = 0;
+ int type = 0;
+
+ require_running_or_return (own_buf);
+
+ int ret = parse_store_memtags_request (own_buf, &addr, &len, tags,
+ &type);
+
+ if (ret == 0)
+ ret = the_target->store_memtags (addr, len, tags, type);
+
+ if (ret)
+ write_enn (own_buf);
+ else
+ write_ok (own_buf);
+
+ return;
+ }
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
@@ -2066,6 +2151,27 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
return (unsigned long long) crc;
}
+/* Parse the qMemTags packet request into ADDR and LEN. */
+
+static void
+parse_fetch_memtags_request (char *request, CORE_ADDR *addr, size_t *len,
+ int *type)
+{
+ gdb_assert (startswith (request, "qMemTags:"));
+
+ const char *p = request + strlen ("qMemTags:");
+
+ /* Read address and length. */
+ unsigned int length = 0;
+ p = decode_m_packet_params (p, addr, &length, ':');
+ *len = length;
+
+ /* Read the tag type. */
+ ULONGEST tag_type = 0;
+ p = unpack_varlen_hex (p, &tag_type);
+ *type = (int) tag_type;
+}
+
/* Add supported btrace packets to BUF. */
static void
@@ -2284,6 +2390,12 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
events. */
report_no_resumed = true;
}
+ else if (feature == "memory-tagging+")
+ {
+ /* GDB supports memory tagging features. */
+ if (target_supports_memory_tagging ())
+ cs.memory_tagging_feature = true;
+ }
else
{
/* Move the unknown features all together. */
@@ -2401,6 +2513,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
strcat (own_buf, ";no-resumed+");
+ if (target_supports_memory_tagging ())
+ strcat (own_buf, ";memory-tagging+");
+
/* Reinitialize components as needed for the new connection. */
hostio_handle_new_gdb_connection ();
target_handle_new_gdb_connection ();
@@ -2593,6 +2708,31 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_tracepoints () && handle_tracepoint_query (own_buf))
return;
+ /* Handle fetch memory tags packets. */
+ if (startswith (own_buf, "qMemTags:")
+ && target_supports_memory_tagging ())
+ {
+ gdb::byte_vector tags;
+ CORE_ADDR addr = 0;
+ size_t len = 0;
+ int type = 0;
+
+ require_running_or_return (own_buf);
+
+ parse_fetch_memtags_request (own_buf, &addr, &len, &type);
+
+ int ret = the_target->fetch_memtags (addr, len, tags, type);
+
+ if (ret)
+ ret = create_fetch_memtags_reply (own_buf, tags);
+
+ if (ret)
+ write_enn (own_buf);
+
+ *new_packet_len_p = strlen (own_buf);
+ return;
+ }
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
@@ -3811,6 +3951,7 @@ captured_main (int argc, char *argv[])
cs.swbreak_feature = 0;
cs.hwbreak_feature = 0;
cs.vCont_supported = 0;
+ cs.memory_tagging_feature = false;
remote_open (port);
diff --git a/gdbserver/server.h b/gdbserver/server.h
index 416544c1f3..3e280732a8 100644
--- a/gdbserver/server.h
+++ b/gdbserver/server.h
@@ -190,6 +190,9 @@ struct client_state
int current_traceframe = -1;
+ /* If true, memory tagging features are supported. */
+ bool memory_tagging_feature = false;
+
};
client_state &get_client_state ();
diff --git a/gdbserver/target.cc b/gdbserver/target.cc
index 4c6f77501b..1f2159714b 100644
--- a/gdbserver/target.cc
+++ b/gdbserver/target.cc
@@ -464,6 +464,26 @@ process_stratum_target::supports_read_offsets ()
return false;
}
+bool
+process_stratum_target::supports_memory_tagging ()
+{
+ return false;
+}
+
+bool
+process_stratum_target::fetch_memtags (CORE_ADDR address, size_t len,
+ gdb::byte_vector &tags, int type)
+{
+ gdb_assert_not_reached ("target op fetch_memtags not supported");
+}
+
+bool
+process_stratum_target::store_memtags (CORE_ADDR address, size_t len,
+ const gdb::byte_vector &tags, int type)
+{
+ gdb_assert_not_reached ("target op store_memtags not supported");
+}
+
int
process_stratum_target::read_offsets (CORE_ADDR *text, CORE_ADDR *data)
{
diff --git a/gdbserver/target.h b/gdbserver/target.h
index 336ee5ad9d..2831a6ce7c 100644
--- a/gdbserver/target.h
+++ b/gdbserver/target.h
@@ -30,6 +30,7 @@
#include "gdbsupport/array-view.h"
#include "gdbsupport/btrace-common.h"
#include <vector>
+#include "gdbsupport/byte-vector.h"
struct emit_ops;
struct buffer;
@@ -499,6 +500,23 @@ class process_stratum_target
/* Return tdesc index for IPA. */
virtual int get_ipa_tdesc_idx ();
+
+ /* Returns true if the target supports memory tagging facilities. */
+ virtual bool supports_memory_tagging ();
+
+ /* Return the allocated memory tags of type TYPE associated with
+ [ADDRESS, ADDRESS + LEN) in TAGS.
+
+ Returns true if successful and false otherwise. */
+ virtual bool fetch_memtags (CORE_ADDR address, size_t len,
+ gdb::byte_vector &tags, int type);
+
+ /* Write the allocation tags of type TYPE contained in TAGS to the
+ memory range [ADDRESS, ADDRESS + LEN).
+
+ Returns true if successful and false otherwise. */
+ virtual bool store_memtags (CORE_ADDR address, size_t len,
+ const gdb::byte_vector &tags, int type);
};
extern process_stratum_target *the_target;
@@ -525,6 +543,9 @@ int kill_inferior (process_info *proc);
#define target_supports_exec_events() \
the_target->supports_exec_events ()
+#define target_supports_memory_tagging() \
+ the_target->supports_memory_tagging ()
+
#define target_handle_new_gdb_connection() \
the_target->handle_new_gdb_connection ()
--
2.25.1
next prev parent reply other threads:[~2021-01-27 20:21 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-27 20:20 [PATCH v5 00/25] Memory Tagging Support + AArch64 Linux implementation Luis Machado
2021-01-27 20:20 ` [PATCH v5 01/25] New target methods for memory tagging support Luis Machado
2021-01-27 23:26 ` Lancelot SIX
2021-01-28 10:02 ` Luis Machado
2021-02-05 2:31 ` Simon Marchi
2021-01-27 20:20 ` [PATCH v5 02/25] New gdbarch memory tagging hooks Luis Machado
2021-02-05 2:38 ` Simon Marchi
2021-02-05 3:58 ` Simon Marchi
2021-01-27 20:20 ` [PATCH v5 03/25] Add GDB-side remote target support for memory tagging Luis Machado
2021-02-05 2:48 ` Simon Marchi
2021-01-27 20:20 ` [PATCH v5 04/25] Unit testing for GDB-side remote memory tagging handling Luis Machado
2021-02-05 2:50 ` Simon Marchi
2021-01-27 20:20 ` Luis Machado [this message]
2021-02-05 2:56 ` [PATCH v5 05/25] GDBserver remote packet support for memory tagging Simon Marchi
2021-02-05 12:38 ` Luis Machado
2021-01-27 20:20 ` [PATCH v5 06/25] Unit tests for gdbserver memory tagging remote packets Luis Machado
2021-01-27 20:20 ` [PATCH v5 07/25] Documentation for " Luis Machado
2021-01-28 3:30 ` Eli Zaretskii
2021-01-28 9:58 ` Luis Machado
2021-01-27 20:20 ` [PATCH v5 08/25] AArch64: Add MTE CPU feature check support Luis Machado
2021-02-05 3:05 ` Simon Marchi
2021-01-27 20:20 ` [PATCH v5 09/25] AArch64: Add target description/feature for MTE registers Luis Machado
2021-01-27 20:20 ` [PATCH v5 10/25] AArch64: Add MTE register set support for GDB and gdbserver Luis Machado
2021-01-27 20:20 ` [PATCH v5 11/25] AArch64: Add MTE ptrace requests Luis Machado
2021-02-05 3:13 ` Simon Marchi
2021-01-27 20:20 ` [PATCH v5 12/25] AArch64: Implement memory tagging target methods for AArch64 Luis Machado
2021-02-05 3:30 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 13/25] Convert char array to std::string in linux_find_memory_regions_full Luis Machado
2021-02-05 3:32 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 14/25] Refactor parsing of /proc/<pid>/smaps Luis Machado
2021-02-05 3:38 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 15/25] AArch64: Implement the memory tagging gdbarch hooks Luis Machado
2021-02-05 4:09 ` Simon Marchi
2021-02-05 14:05 ` Luis Machado
2021-01-27 20:21 ` [PATCH v5 16/25] AArch64: Add unit testing for logical tag set/get operations Luis Machado
2021-01-27 20:21 ` [PATCH v5 17/25] AArch64: Report tag violation error information Luis Machado
2021-02-05 4:22 ` Simon Marchi
2021-02-05 14:59 ` Luis Machado
2021-02-05 16:13 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 18/25] AArch64: Add gdbserver MTE support Luis Machado
2021-01-27 20:21 ` [PATCH v5 19/25] AArch64: Add MTE register set support for core files Luis Machado
2021-01-27 20:21 ` [PATCH v5 20/25] New memory-tag commands Luis Machado
2021-02-05 4:49 ` Simon Marchi
2021-02-05 4:52 ` Simon Marchi
2021-02-08 18:59 ` Luis Machado
2021-03-23 21:46 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 21/25] Documentation for the new mtag commands Luis Machado
2021-01-28 3:31 ` Eli Zaretskii
2021-02-05 4:50 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 22/25] Extend "x" and "print" commands to support memory tagging Luis Machado
2021-02-05 5:02 ` Simon Marchi
2021-01-27 20:21 ` [PATCH v5 23/25] Document new "x" and "print" memory tagging extensions Luis Machado
2021-01-28 3:31 ` Eli Zaretskii
2021-02-05 5:04 ` Simon Marchi
2021-02-08 20:44 ` Luis Machado
2021-01-27 20:21 ` [PATCH v5 24/25] Add NEWS entry Luis Machado
2021-01-28 3:32 ` Eli Zaretskii
2021-02-05 5:06 ` Simon Marchi
2021-02-08 20:44 ` Luis Machado
2021-01-27 20:21 ` [PATCH v5 25/25] Add memory tagging testcases Luis Machado
2021-02-04 14:18 ` [PING] [PATCH v5 00/25] Memory Tagging Support + AArch64 Linux implementation Luis Machado
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210127202112.2485702-6-luis.machado@linaro.org \
--to=luis.machado@linaro.org \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).