summaryrefslogtreecommitdiff
path: root/gdbserver/server.cc
diff options
context:
space:
mode:
authorLuis Machado <luis.machado@linaro.org>2020-06-15 15:34:06 -0300
committerLuis Machado <luis.machado@linaro.org>2021-03-24 14:49:21 -0300
commit546b77fe78bb366bbec3c708ac371e2f553bbdae (patch)
tree83e9a4964c5abe2fce9a3f17de88e257b1533886 /gdbserver/server.cc
parent754487e200deb9fad3399556e838bb68eedbab18 (diff)
downloadbinutils-gdb-546b77fe78bb366bbec3c708ac371e2f553bbdae.tar.gz
GDBserver remote packet support for memory tagging
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: 2021-03-24 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.
Diffstat (limited to 'gdbserver/server.cc')
-rw-r--r--gdbserver/server.cc140
1 files changed, 140 insertions, 0 deletions
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index ea731d54689..5887133390a 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -556,6 +556,64 @@ 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
@@ -912,6 +970,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;
@@ -2076,6 +2160,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
@@ -2294,6 +2399,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. */
@@ -2411,6 +2522,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 ();
@@ -2603,6 +2717,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;
@@ -3822,6 +3961,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);