public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Luis Machado <luis.machado@linaro.org>
To: gdb-patches@sourceware.org, Alan.Hayward@arm.com
Cc: omair.javaid@linaro.org, catalin.marinas@arm.com,
	david.spickett@linaro.org, jose.marchesi@oracle.com
Subject: [PATCH 05/23] GDBserver remote packet support for memory tagging
Date: Wed, 15 Jul 2020 16:44:55 -0300	[thread overview]
Message-ID: <20200715194513.16641-6-luis.machado@linaro.org> (raw)
In-Reply-To: <20200715194513.16641-1-luis.machado@linaro.org>

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.
	(decode_M_packet): Use decode_m_packet_params.
	* remote-utils.h (decode_m_packet_params): New prototype.
	* server.cc (create_fmemtags_reply, parse_smemtags_request): New
	functions.
	(handle_general_set): Handle the QMemTags packet.
	(parse_fmemtags_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 |  40 ++++++------
 gdbserver/remote-utils.h  |   2 +
 gdbserver/server.cc       | 126 ++++++++++++++++++++++++++++++++++++++
 gdbserver/server.h        |   3 +
 gdbserver/target.cc       |  20 ++++++
 gdbserver/target.h        |  17 +++++
 6 files changed, 186 insertions(+), 22 deletions(-)

diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc
index c26668dc0f..5cf9872510 100644
--- a/gdbserver/remote-utils.cc
+++ b/gdbserver/remote-utils.cc
@@ -1302,10 +1302,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.  */
+
+char *
+decode_m_packet_params (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;
 
@@ -1315,39 +1319,31 @@ 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)
+{
+  decode_m_packet_params (from, mem_addr_ptr, len_ptr, '\0');
 }
 
 void
 decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
 		 unsigned char **to_p)
 {
-  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;
-    }
-
-  while ((ch = from[i++]) != ':')
-    {
-      *len_ptr = *len_ptr << 4;
-      *len_ptr |= fromhex (ch) & 0x0f;
-    }
+  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 1b31456798..1c82f40ad6 100644
--- a/gdbserver/remote-utils.h
+++ b/gdbserver/remote-utils.h
@@ -45,6 +45,8 @@ 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);
+char *decode_m_packet_params (char *from, CORE_ADDR *mem_addr_ptr,
+			      unsigned int *len_ptr, const char end_marker);
 void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr,
 		      unsigned int *len_ptr);
 void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index ab5363eb03..2fb2b399b2 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -545,12 +545,59 @@ handle_btrace_conf_general_set (char *own_buf)
   return 1;
 }
 
+/* Create the qMemTags packet reply given TAGS.  */
+
+static int
+create_fmemtags_reply (char *reply, const gdb::byte_vector &tags)
+{
+  /* It is an error to pass a zero-sized tag vector.  */
+  if (tags.size () == 0)
+    return 1;
+
+  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 1;
+
+  strcpy (reply, packet.c_str ());
+  return 0;
+}
+
+/* Parse the QMemTags request into ADDR, LEN and TAGS.
+
+   Return 0 if successful, non-zero otherwise.  */
+
+static int
+parse_smemtags_request (char *request, CORE_ADDR *addr, size_t *len,
+			gdb::byte_vector &tags)
+{
+  if (!startswith (request, "QMemTags:"))
+    return 1;
+
+  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 data.  */
+  tags = hex2bin (p);
+
+  return 0;
+}
+
 /* 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;
@@ -899,6 +946,30 @@ 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;
+
+      require_running_or_return (own_buf);
+
+      int ret = parse_smemtags_request (own_buf, &addr, &len, tags);
+
+      if (ret == 0)
+	ret = the_target->store_memtags (addr, len, tags);
+
+      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;
@@ -2119,6 +2190,26 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
   return (unsigned long long) crc;
 }
 
+/* Parse the qMemTags packet request into ADDR and LEN.
+
+   Return 0 if successful, non-zero otherwise.  */
+
+static int
+parse_fmemtags_request (char *request, CORE_ADDR *addr, size_t *len)
+{
+  if (!startswith (request, "qMemTags:"))
+    return 1;
+
+  char *p = request + strlen ("qMemTags:");
+
+  /* Read address and length.  */
+  unsigned int length = 0;
+  decode_m_packet (p, addr, &length);
+  *len = length;
+
+  return 0;
+}
+
 /* Add supported btrace packets to BUF.  */
 
 static void
@@ -2337,6 +2428,12 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 		     events.  */
 		  report_no_resumed = true;
 		}
+	      else if (strcmp (p, "memory-tagging+") == 0)
+		{
+		  /* GDB supports memory tagging features.  */
+		  if (target_supports_memory_tagging ())
+		    cs.memory_tagging_feature = true;
+		}
 	      else
 		{
 		  /* Move the unknown features all together.  */
@@ -2454,6 +2551,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 ();
@@ -2646,6 +2746,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;
+
+      require_running_or_return (own_buf);
+
+      int ret = parse_fmemtags_request (own_buf, &addr, &len);
+
+      if (ret == 0)
+	ret = the_target->fetch_memtags (addr, len, tags);
+
+      if (ret == 0)
+	ret = create_fmemtags_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;
@@ -3852,6 +3977,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 22228050a8..3d4a086e18 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 87f62a0b55..8beeeaee9e 100644
--- a/gdbserver/target.cc
+++ b/gdbserver/target.cc
@@ -463,6 +463,26 @@ process_stratum_target::supports_read_offsets ()
   return false;
 }
 
+bool
+process_stratum_target::supports_memory_tagging ()
+{
+  return false;
+}
+
+int
+process_stratum_target::fetch_memtags (CORE_ADDR address, size_t len,
+				       gdb::byte_vector &tags)
+{
+  return 0;
+}
+
+int
+process_stratum_target::store_memtags (CORE_ADDR address, size_t len,
+				       const gdb::byte_vector &tags)
+{
+  return 0;
+}
+
 int
 process_stratum_target::read_offsets (CORE_ADDR *text, CORE_ADDR *data)
 {
diff --git a/gdbserver/target.h b/gdbserver/target.h
index 13f069f772..f85c876fa3 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,19 @@ 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 associated with
+     [ADDRESS, ADDRESS + LEN) in TAGS.  */
+  virtual int fetch_memtags (CORE_ADDR address, size_t len,
+			     gdb::byte_vector &tags);
+
+  /* Write the allocation tags contained in TAGS to the memory range
+     [ADDRESS, ADDRESS + LEN).  */
+  virtual int store_memtags (CORE_ADDR address, size_t len,
+			     const gdb::byte_vector &tags);
 };
 
 extern process_stratum_target *the_target;
@@ -525,6 +539,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.17.1


  parent reply	other threads:[~2020-07-15 19:46 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-15 19:44 [PATCH 00/23] Memory Tagging Support + AArch64 Linux implementation Luis Machado
2020-07-15 19:44 ` [PATCH 01/23] New target methods for memory tagging support Luis Machado
2020-07-15 19:44 ` [PATCH 02/23] New gdbarch memory tagging hooks Luis Machado
2020-07-15 19:44 ` [PATCH 03/23] Add GDB-side remote target support for memory tagging Luis Machado
2020-07-15 19:44 ` [PATCH 04/23] Unit testing for GDB-side remote memory tagging handling Luis Machado
2020-07-15 19:44 ` Luis Machado [this message]
2020-07-15 19:44 ` [PATCH 06/23] Unit tests for gdbserver memory tagging remote packets Luis Machado
2020-07-15 19:44 ` [PATCH 07/23] Documentation for " Luis Machado
2020-07-17  5:54   ` Eli Zaretskii
2020-07-17 14:20     ` Luis Machado
2020-07-15 19:44 ` [PATCH 08/23] AArch64: Add MTE CPU feature check support Luis Machado
2020-07-15 19:44 ` [PATCH 09/23] AArch64: Add target description/feature for MTE registers Luis Machado
2020-07-15 19:45 ` [PATCH 10/23] AArch64: Add MTE register set support for GDB and gdbserver Luis Machado
2020-07-15 19:45 ` [PATCH 11/23] AArch64: Add MTE ptrace requests Luis Machado
2020-07-15 19:45 ` [PATCH 12/23] AArch64: Implement memory tagging target methods for AArch64 Luis Machado
2020-07-15 19:45 ` [PATCH 13/23] Refactor parsing of /proc/<pid>/smaps Luis Machado
2020-07-15 19:45 ` [PATCH 14/23] AArch64: Implement the memory tagging gdbarch hooks Luis Machado
2020-07-15 19:45 ` [PATCH 15/23] AArch64: Add unit testing for logical tag set/get operations Luis Machado
2020-07-15 19:45 ` [PATCH 16/23] AArch64: Report tag violation error information Luis Machado
2020-07-15 19:45 ` [PATCH 17/23] AArch64: Add gdbserver MTE support Luis Machado
2020-07-15 19:45 ` [PATCH 18/23] New mtag commands Luis Machado
2020-07-15 19:45 ` [PATCH 19/23] Documentation for the new " Luis Machado
2020-07-17  6:11   ` Eli Zaretskii
2020-07-17 14:20     ` Luis Machado
2020-07-17 14:29       ` Eli Zaretskii
2020-07-17 15:08         ` Luis Machado
2020-07-15 19:45 ` [PATCH 20/23] Extend "x" and "print" commands to support memory tagging Luis Machado
2020-07-15 19:45 ` [PATCH 21/23] Document new "x" and "print" memory tagging extensions Luis Machado
2020-07-17  6:16   ` Eli Zaretskii
2020-07-17 14:20     ` Luis Machado
2020-07-17 14:31       ` Eli Zaretskii
2020-07-15 19:45 ` [PATCH 22/23] Add NEWS entry Luis Machado
2020-07-17  6:18   ` Eli Zaretskii
2020-07-17 14:20     ` Luis Machado
2020-07-15 19:45 ` [PATCH 23/23] Add memory tagging testcases Luis Machado
2020-07-16 16:49 ` [PATCH 00/23] Memory Tagging Support + AArch64 Linux implementation Alan Hayward
2020-07-17 12:33   ` Luis Machado
2020-07-17 22:02 ` John Baldwin
2020-07-23 13:59   ` Luis Machado
2020-07-23 16:48     ` John Baldwin
2020-07-24 16:10       ` David Spickett
2020-07-23 14:59 ` 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=20200715194513.16641-6-luis.machado@linaro.org \
    --to=luis.machado@linaro.org \
    --cc=Alan.Hayward@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=david.spickett@linaro.org \
    --cc=gdb-patches@sourceware.org \
    --cc=jose.marchesi@oracle.com \
    --cc=omair.javaid@linaro.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).