public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
To: gdb-patches@sourceware.org
Cc: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Subject: [PATCH v3 6/8] gdb/remote: Parse tdesc field in stop reply and threads list XML
Date: Mon, 30 Jan 2023 04:45:16 +0000	[thread overview]
Message-ID: <20230130044518.3322695-7-thiago.bauermann@linaro.org> (raw)
In-Reply-To: <20230130044518.3322695-1-thiago.bauermann@linaro.org>

gdbserver added the concept of target description IDs to the remote
protocol and uses them in the threads list XML and in the 'T AA' stop
reply packet.  It also allows fetching a target description with a given
ID.  This patch is for the GDB-side support.  The target descriptions
obtained this way aren't yet used but will be in the next patch.

In the DTD for the threads list XML, add a "tdesc" attribute to the
<thread> node.  A tdesc_id field is added to the stop_reply and
thread_item structs.  An m_remote member is added to the
threads_listing_context struct, and to simplify its initialisation a
constructor is added as well.  This is to provide access to the remote
state in start_thread.

Finally, the remote_state object keeps a map of the target descriptions
that have been received from the target, keyed by their ID.  There are
also methods to get a target description given its ID, and to fetch target
descriptions for IDs that were mentioned by gdbserver but not yet
retrieved by GDB.  The latter gets called after parsing the response of
qXfer:threads:read and of the stop reply packet.
---
 gdb/features/threads.dtd |  1 +
 gdb/remote.c             | 85 +++++++++++++++++++++++++++++++++++++++-
 gdb/xml-tdesc.c          | 27 ++++++++++---
 gdb/xml-tdesc.h          |  6 +++
 4 files changed, 112 insertions(+), 7 deletions(-)

diff --git a/gdb/features/threads.dtd b/gdb/features/threads.dtd
index 036b2ce58837..3102d1352978 100644
--- a/gdb/features/threads.dtd
+++ b/gdb/features/threads.dtd
@@ -11,3 +11,4 @@
 
 <!ATTLIST thread id CDATA #REQUIRED>
 <!ATTLIST thread core CDATA #IMPLIED>
+<!ATTLIST thread tdesc CDATA #IMPLIED>
diff --git a/gdb/remote.c b/gdb/remote.c
index 218bca30d047..f1d1944414c3 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -80,6 +80,7 @@
 #include <unordered_map>
 #include "async-event.h"
 #include "gdbsupport/selftest.h"
+#include "xml-tdesc.h"
 
 /* The remote target.  */
 
@@ -238,6 +239,16 @@ class remote_state
   /* Get the remote arch state for GDBARCH.  */
   struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch);
 
+  /* Add new ID to the target description list.  The corresponding XML will be
+     requested soon.  */
+  void add_tdesc_id (ULONGEST id);
+
+  /* Get the target description corresponding to remote protocol ID.  */
+  const target_desc *get_tdesc (ULONGEST id) const;
+
+  /* Get the target descriptions we don't know about from the target.  */
+  void fetch_unknown_tdescs (remote_target *remote);
+
 public: /* data */
 
   /* A buffer to use for incoming packets, and its current size.  The
@@ -387,6 +398,10 @@ class remote_state
      support multi-process.  */
   std::unordered_map<struct gdbarch *, remote_arch_state>
     m_arch_states;
+
+  /* The target descriptions that have been received from the target.  The key
+     is the ID used to reference it in the remote protocol.  */
+  std::unordered_map<ULONGEST, const target_desc *> m_tdescs;
 };
 
 static const target_info remote_target_info = {
@@ -1009,6 +1024,9 @@ struct stop_reply : public notif_event
      fetch them is avoided).  */
   std::vector<cached_reg_t> regcache;
 
+  /* The target description ID communicated in the stop reply packet.  */
+  gdb::optional<ULONGEST> tdesc_id;
+
   enum target_stop_reason stop_reason;
 
   CORE_ADDR watch_data_address;
@@ -3689,6 +3707,9 @@ struct thread_item
 
   /* The thread handle associated with the thread.  */
   gdb::byte_vector thread_handle;
+
+  /* The ID of the thread's target description, if provided.  */
+  gdb::optional<ULONGEST> tdesc_id;
 };
 
 /* Context passed around to the various methods listing remote
@@ -3697,6 +3718,12 @@ struct thread_item
 
 struct threads_listing_context
 {
+  threads_listing_context (remote_target *remote)
+    : m_remote (remote)
+  {}
+
+  DISABLE_COPY_AND_ASSIGN (threads_listing_context);
+
   /* Return true if this object contains an entry for a thread with ptid
      PTID.  */
 
@@ -3733,6 +3760,9 @@ struct threads_listing_context
 
   /* The threads found on the remote target.  */
   std::vector<thread_item> items;
+
+  /* The remote target associated with this context.  */
+  remote_target *m_remote;
 };
 
 static int
@@ -3814,6 +3844,13 @@ start_thread (struct gdb_xml_parser *parser,
   attr = xml_find_attribute (attributes, "handle");
   if (attr != NULL)
     item.thread_handle = hex2bin ((const char *) attr->value.get ());
+
+  attr = xml_find_attribute (attributes, "tdesc");
+  if (attr != NULL)
+    {
+      item.tdesc_id = *(ULONGEST *) attr->value.get ();
+      data->m_remote->get_remote_state ()->add_tdesc_id (*item.tdesc_id);
+    }
 }
 
 static void
@@ -3833,6 +3870,7 @@ const struct gdb_xml_attribute thread_attributes[] = {
   { "core", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
   { "name", GDB_XML_AF_OPTIONAL, NULL, NULL },
   { "handle", GDB_XML_AF_OPTIONAL, NULL, NULL },
+  { "tdesc", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
@@ -3870,6 +3908,7 @@ remote_target::remote_get_threads_with_qxfer (threads_listing_context *context)
 	{
 	  gdb_xml_parse_quick (_("threads"), "threads.dtd",
 			       threads_elements, xml->data (), context);
+	  get_remote_state ()->fetch_unknown_tdescs (this);
 	}
 
       return 1;
@@ -3937,7 +3976,7 @@ has_single_non_exited_thread (inferior *inf)
 void
 remote_target::update_thread_list ()
 {
-  struct threads_listing_context context;
+  struct threads_listing_context context (this);
   int got_list = 0;
 
   /* We have a few different mechanisms to fetch the thread list.  Try
@@ -7223,7 +7262,11 @@ remote_notif_stop_parse (remote_target *remote,
 			 struct notif_client *self, const char *buf,
 			 struct notif_event *event)
 {
-  remote->remote_parse_stop_reply (buf, (struct stop_reply *) event);
+  struct stop_reply *stop_reply = (struct stop_reply *) event;
+
+  remote->remote_parse_stop_reply (buf, stop_reply);
+
+  stop_reply->rs->fetch_unknown_tdescs (remote);
 }
 
 static void
@@ -7516,6 +7559,36 @@ strprefix (const char *p, const char *pend, const char *prefix)
   return *prefix == '\0';
 }
 
+void
+remote_state::add_tdesc_id (ULONGEST id)
+{
+  /* Check whether the ID was already added.  */
+  if (m_tdescs.find (id) != m_tdescs.cend ())
+    return;
+
+  m_tdescs[id] = nullptr;
+}
+
+const target_desc *
+remote_state::get_tdesc (ULONGEST id) const
+{
+  auto found = m_tdescs.find (id);
+
+  /* Check if the given ID was already provided.  */
+  if (found == m_tdescs.cend ())
+    return nullptr;
+
+  return found->second;
+}
+
+void
+remote_state::fetch_unknown_tdescs (remote_target *remote)
+{
+  for (auto &pair : m_tdescs)
+    if (pair.second == nullptr)
+      m_tdescs[pair.first] = target_read_description_xml (remote, pair.first);
+}
+
 /* Parse the stop reply in BUF.  Either the function succeeds, and the
    result is stored in EVENT, or throws an error.  */
 
@@ -7674,6 +7747,14 @@ Packet: '%s'\n"),
 	      event->ws.set_thread_created ();
 	      p = strchrnul (p1 + 1, ';');
 	    }
+	  else if (strprefix (p, p1, "tdesc"))
+	    {
+	      ULONGEST tdesc_id;
+
+	      p = unpack_varlen_hex (++p1, &tdesc_id);
+	      event->rs->add_tdesc_id (tdesc_id);
+	      event->tdesc_id = tdesc_id;
+	    }
 	  else
 	    {
 	      ULONGEST pnum;
diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c
index ba7154c5d56f..302863e12365 100644
--- a/gdb/xml-tdesc.c
+++ b/gdb/xml-tdesc.c
@@ -698,14 +698,13 @@ fetch_available_features_from_target (const char *name, target_ops *ops)
 }
 \f
 
-/* Read an XML target description using OPS.  Parse it, and return the
-   parsed description.  */
+/* Actual implementation of the target_read_description_xml variants.  */
 
-const struct target_desc *
-target_read_description_xml (struct target_ops *ops)
+static const struct target_desc *
+target_read_description_xml (struct target_ops *ops, const char *desc_name)
 {
   gdb::optional<gdb::char_vector> tdesc_str
-    = fetch_available_features_from_target ("target.xml", ops);
+    = fetch_available_features_from_target (desc_name, ops);
   if (!tdesc_str)
     return NULL;
 
@@ -717,6 +716,24 @@ target_read_description_xml (struct target_ops *ops)
   return tdesc_parse_xml (tdesc_str->data (), fetch_another);
 }
 
+/* See xml-tdesc.h.  */
+
+const struct target_desc *
+target_read_description_xml (struct target_ops *ops)
+{
+  return target_read_description_xml (ops, "target.xml");
+}
+
+/* See xml-tdesc.h.  */
+
+const struct target_desc *
+target_read_description_xml (struct target_ops *ops, ULONGEST id)
+{
+  std::string desc_name = string_printf ("target-id-%" PRIu64 ".xml", id);
+
+  return target_read_description_xml (ops, desc_name.c_str ());
+}
+
 /* Fetches an XML target description using OPS,  processing
    includes, but not parsing it.  Used to dump whole tdesc
    as a single XML file.  */
diff --git a/gdb/xml-tdesc.h b/gdb/xml-tdesc.h
index 0fbfc7e043e9..c7cc97c5dfc0 100644
--- a/gdb/xml-tdesc.h
+++ b/gdb/xml-tdesc.h
@@ -38,6 +38,12 @@ const struct target_desc *file_read_description_xml (const char *filename);
 
 const struct target_desc *target_read_description_xml (struct target_ops *);
 
+/* Read an XML target description with the given ID using OPS.  Parse it, and
+   return the parsed description.  */
+
+const struct target_desc *target_read_description_xml (struct target_ops *ops,
+						       ULONGEST id);
+
 /* Fetches an XML target description using OPS, processing includes,
    but not parsing it.  Used to dump whole tdesc as a single XML file.
    Returns the description on success, and a disengaged optional

  parent reply	other threads:[~2023-01-30  4:45 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-30  4:45 [PATCH v3 0/8] gdbserver improvements for AArch64 SVE support Thiago Jung Bauermann
2023-01-30  4:45 ` [PATCH v3 1/8] gdbserver: Add assert in find_register_by_number Thiago Jung Bauermann
2023-01-31 17:05   ` Simon Marchi
2023-01-31 19:49     ` Thiago Jung Bauermann
2023-02-01 15:43       ` Simon Marchi
2023-01-30  4:45 ` [PATCH v3 2/8] gdbserver: Add PID parameter to linux_get_auxv and linux_get_hwcap Thiago Jung Bauermann
2023-02-01  9:07   ` Luis Machado
2023-02-01 10:54   ` Andrew Burgess
2023-02-01 16:01     ` Simon Marchi
2023-02-01 19:33       ` Thiago Jung Bauermann
2023-02-01 19:53         ` Simon Marchi
2023-02-01 21:55           ` Thiago Jung Bauermann
2023-02-06 19:54   ` Pedro Alves
2023-02-06 20:16     ` Simon Marchi
2023-02-07 15:19       ` Pedro Alves
2023-02-07 21:47         ` Thiago Jung Bauermann
2023-02-09  1:31           ` Simon Marchi
2023-02-10  3:54             ` Thiago Jung Bauermann
2023-02-07 22:28     ` Thiago Jung Bauermann
2023-01-30  4:45 ` [PATCH v3 3/8] gdbserver/linux-aarch64: Factor out function to get aarch64_features Thiago Jung Bauermann
2023-02-01  8:59   ` Luis Machado
2023-02-01 16:04     ` Simon Marchi
2023-02-01 22:13       ` Thiago Jung Bauermann
2023-01-30  4:45 ` [PATCH v3 4/8] gdbserver/linux-aarch64: When thread stops, update its target description Thiago Jung Bauermann
2023-02-01  9:05   ` Luis Machado
2023-02-01 11:06   ` Andrew Burgess
2023-02-01 16:21     ` Simon Marchi
2023-02-01 16:32       ` Luis Machado
2023-02-02  2:54         ` Thiago Jung Bauermann
2023-02-02  3:47           ` Simon Marchi
2023-02-03  3:47             ` Thiago Jung Bauermann
2023-02-03 11:13               ` Luis Machado
2023-02-04 15:26                 ` Thiago Jung Bauermann
2023-02-03 11:11             ` Luis Machado
2023-02-04 15:21               ` Thiago Jung Bauermann
2023-02-06  9:07                 ` Luis Machado
2023-02-06 12:15                   ` Thiago Jung Bauermann
2023-02-06 20:29                 ` Pedro Alves
2023-02-07  8:11                   ` Luis Machado
2023-02-07 14:39                     ` Thiago Jung Bauermann
2023-02-03 10:57           ` Luis Machado
2023-02-04  6:18             ` Thiago Jung Bauermann
2023-02-06 20:26           ` Pedro Alves
2023-02-07 21:06             ` Thiago Jung Bauermann
2023-02-09  2:46               ` Simon Marchi
2023-02-10  3:29                 ` Thiago Jung Bauermann
2023-02-10 14:56                   ` Luis Machado
2023-02-10 15:04                     ` Tom Tromey
2023-02-10 15:28                       ` Luis Machado
2023-02-10 17:26                       ` Thiago Jung Bauermann
2023-02-10 21:01                         ` Simon Marchi
2023-01-30  4:45 ` [PATCH v3 5/8] gdbserver: Transmit target description ID in thread list and stop reply Thiago Jung Bauermann
2023-01-30 12:52   ` Eli Zaretskii
2023-01-30 14:05     ` Thiago Jung Bauermann
2023-02-01  9:39   ` Luis Machado
2023-02-01 12:07   ` Andrew Burgess
2023-02-01 13:03     ` Eli Zaretskii
2023-02-01 17:37     ` Simon Marchi
2023-02-02 20:36       ` Thiago Jung Bauermann
2023-02-02 20:56         ` Simon Marchi
2023-02-01 20:46     ` Simon Marchi
2023-02-02 21:43       ` Thiago Jung Bauermann
2023-02-01 14:51   ` Andrew Burgess
2023-02-01 17:03     ` Simon Marchi
2023-02-02 19:52       ` Thiago Jung Bauermann
2023-02-02 20:51         ` Simon Marchi
2023-02-03  2:44           ` Thiago Jung Bauermann
2023-02-03 16:29             ` Andrew Burgess
2023-02-04  6:08               ` Thiago Jung Bauermann
2023-02-03 11:22       ` Luis Machado
2023-02-03 12:50         ` Simon Marchi
2023-01-30  4:45 ` Thiago Jung Bauermann [this message]
2023-02-01  9:52   ` [PATCH v3 6/8] gdb/remote: Parse tdesc field in stop reply and threads list XML Luis Machado
2023-02-05  0:06     ` Thiago Jung Bauermann
2023-02-06  9:10       ` Luis Machado
2023-02-01 14:32   ` Andrew Burgess
2023-02-01 19:50     ` Simon Marchi
2023-02-01 20:16       ` Simon Marchi
2023-02-03 11:27         ` Luis Machado
2023-02-03 13:19           ` Simon Marchi
2023-02-03 16:33             ` Andrew Burgess
2023-01-30  4:45 ` [PATCH v3 7/8] gdb/aarch64: Detect vector length changes when debugging remotely Thiago Jung Bauermann
2023-02-01  9:58   ` Luis Machado
2023-02-01 15:26   ` Andrew Burgess
2023-02-01 20:20     ` Simon Marchi
2023-02-03 11:31       ` Luis Machado
2023-02-03 16:38       ` Andrew Burgess
2023-02-03 19:07         ` Simon Marchi
2023-01-30  4:45 ` [PATCH v3 8/8] gdb/testsuite: Add test to exercise multi-threaded AArch64 SVE inferiors Thiago Jung Bauermann
2023-02-01 10:10   ` Luis Machado
2023-02-06 19:11 ` [PATCH v3 0/8] gdbserver improvements for AArch64 SVE support Pedro Alves
2023-02-06 20:05   ` Simon Marchi
2023-02-06 21:06     ` Pedro Alves
2023-02-07 13:49       ` Simon Marchi

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=20230130044518.3322695-7-thiago.bauermann@linaro.org \
    --to=thiago.bauermann@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).