[PATCH v4 06/44] gdb, gdbserver, gdbsupport: add 'device' tag to XML target description

Markus Metzger <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
From: Nils-Christian Kempke <[email protected]>

Add <device> tag to the XML target description.  The tag is a list of
device attributes.  The extension enables passing device information
within the target description XML sent from gdbserver to gdb.

Co-authored-by: Tankut Baris Aktemur <[email protected]>
Reviewed-By: Eli Zaretskii <[email protected]>
---
 gdb/NEWS                    |  8 ++++++
 gdb/doc/gdb.texinfo         | 17 ++++++++++++
 gdb/features/gdb-target.dtd | 11 +++++++-
 gdb/target-descriptions.c   | 19 +++++++++++++
 gdb/xml-tdesc.c             | 36 +++++++++++++++++++++++++
 gdbserver/tdesc.cc          | 16 +++++++++++
 gdbserver/tdesc.h           |  3 +++
 gdbsupport/tdesc.cc         | 24 +++++++++++++++++
 gdbsupport/tdesc.h          | 54 +++++++++++++++++++++++++++++++++++++
 9 files changed, 187 insertions(+), 1 deletion(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 10c182067f9..0b949ae7825 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,14 @@
 
 *** Changes since GDB 18
 
+* Changed remote packets
+
+qXfer:features:read:target.xml
+
+  The XML that is sent as a response can now include a "device" element
+  that can be used for passing information when the remote inferior
+  represents a device, e.g. a GPU.
+
 *** Changes in GDB 18
 
 * Support for the Common Trace Format (CTF) has been removed.  GDB now
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 0030698dcee..ce4bbc48385 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -49423,6 +49423,7 @@ are explained further below.
   @r{[}@var{architecture}@r{]}
   @r{[}@var{osabi}@r{]}
   @r{[}@var{compatible}@r{]}
+  @r{[}@var{device}@r{]}
   @r{[}@var{feature}@dots{}@r{]}
 </target>
 @end smallexample
@@ -49520,6 +49521,22 @@ capability with @samp{<compatible>} is as follows:
   <compatible>spu</compatible>
 @end smallexample
 
+@subsection Device Information
+@cindex <device>
+
+A @samp{<device>} element can be used for passing device information
+for when, e.g.@: the remote target represents a device, such as a GPU.
+@value{GDBN} can then use this information to display it to the user
+for informative purposes or to execute device-specific functions
+appropriately.  The element contains a number of attributes, best
+shown with the example below.  All attributes are optional.
+
+@smallexample
+  <device vendor-id="0x8086"
+          target-id="0x56a1"
+          name="Intel(R) Arc(TM) A750 Graphics" />
+@end smallexample
+
 @subsection Features
 @cindex <feature>
 
diff --git a/gdb/features/gdb-target.dtd b/gdb/features/gdb-target.dtd
index 2c405af8add..e22a07f9b48 100644
--- a/gdb/features/gdb-target.dtd
+++ b/gdb/features/gdb-target.dtd
@@ -9,7 +9,9 @@
 <!-- The osabi and compatible elements were added post GDB 6.8.  The version
      wasn't bumped, since older GDBs silently ignore unknown elements.  -->
 
-<!ELEMENT target	(architecture?, osabi?, compatible*, feature*)>
+<!ELEMENT target
+	(architecture?, osabi?, compatible*, device?, feature*)>
+
 <!ATTLIST target
 	version		CDATA	#FIXED "1.0">
 
@@ -19,6 +21,13 @@
 
 <!ELEMENT compatible	(#PCDATA)>
 
+<!ELEMENT device	EMPTY>
+<!ATTLIST device
+	vendor-id	CDATA	#IMPLIED
+	target-id	CDATA	#IMPLIED
+	name		CDATA	#IMPLIED
+	>
+
 <!ELEMENT feature
 	((vector | flags | struct | union )*, reg*)>
 <!ATTLIST feature
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index e1821fe7114..6e1bc2fa5e7 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -355,6 +355,9 @@ struct target_desc : tdesc_element
   /* The list of compatible architectures reported by the target.  */
   std::vector<tdesc_compatible_info_up> compatible;
 
+  /* The device reported by the target, if any.  */
+  tdesc_device_up device;
+
   /* Any architecture-specific properties specified by the target.  */
   std::vector<property> properties;
 
@@ -633,6 +636,22 @@ tdesc_osabi_name (const struct target_desc *target_desc)
   return nullptr;
 }
 
+/* See gdbsupport/tdesc.h.  */
+
+void
+set_tdesc_device_info (target_desc *target_desc, tdesc_device *device)
+{
+  target_desc->device.reset (device);
+}
+
+/* See gdbsupport/tdesc.h.  */
+
+const tdesc_device *
+tdesc_device_info (const target_desc *target_desc)
+{
+  return target_desc->device.get ();
+}
+
 /* Return 1 if this target description includes any registers.  */
 
 int
diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c
index c0b1b635315..0481e16fab5 100644
--- a/gdb/xml-tdesc.c
+++ b/gdb/xml-tdesc.c
@@ -137,6 +137,33 @@ tdesc_end_compatible (struct gdb_xml_parser *parser,
   tdesc_add_compatible (data->tdesc, arch);
 }
 
+/* Handle the start of a <device> element and its value.  */
+
+static void
+tdesc_start_device (struct gdb_xml_parser *parser,
+		    const gdb_xml_element *element,
+		    void *user_data, std::vector<gdb_xml_value> &attributes)
+{
+  tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
+  tdesc_device *device = new tdesc_device ();
+
+  gdb_xml_value *attr;
+
+  attr = xml_find_attribute (attributes, "vendor-id");
+  if (attr != nullptr)
+    device->vendor_id = * (ULONGEST *) attr->value.get ();
+
+  attr = xml_find_attribute (attributes, "target-id");
+  if (attr != nullptr)
+    device->target_id = * (ULONGEST *) attr->value.get ();
+
+  attr = xml_find_attribute (attributes, "name");
+  if (attr != nullptr)
+    device->name = (char *) attr->value.get ();
+
+  set_tdesc_device_info (data->tdesc, device);
+}
+
 /* Handle the start of a <target> element.  */
 
 static void
@@ -587,6 +614,13 @@ static const struct gdb_xml_element feature_children[] = {
   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
 };
 
+static const struct gdb_xml_attribute device_attributes[] = {
+  { "vendor-id", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+  { "target-id", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+  { "name", GDB_XML_AF_OPTIONAL, NULL, NULL },
+  { NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
 static const struct gdb_xml_attribute target_attributes[] = {
   { "version", GDB_XML_AF_NONE, NULL, NULL },
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
@@ -599,6 +633,8 @@ static const struct gdb_xml_element target_children[] = {
     NULL, tdesc_end_osabi },
   { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
     NULL, tdesc_end_compatible },
+  { "device", device_attributes, NULL, GDB_XML_EF_OPTIONAL,
+    tdesc_start_device, NULL },
   { "feature", feature_attributes, feature_children,
     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
     tdesc_start_feature, NULL },
diff --git a/gdbserver/tdesc.cc b/gdbserver/tdesc.cc
index 1d5f52b8948..cb8aad84f54 100644
--- a/gdbserver/tdesc.cc
+++ b/gdbserver/tdesc.cc
@@ -190,6 +190,22 @@ set_tdesc_osabi (struct target_desc *target_desc, enum gdb_osabi osabi)
 
 /* See gdbsupport/tdesc.h.  */
 
+void
+set_tdesc_device_info (target_desc *target_desc, tdesc_device *device)
+{
+  target_desc->device.reset (device);
+}
+
+/* See gdbsupport/tdesc.h.  */
+
+const tdesc_device *
+tdesc_device_info (const target_desc *target_desc)
+{
+  return target_desc->device.get ();
+}
+
+/* See gdbsupport/tdesc.h.  */
+
 const char *
 tdesc_get_features_xml (const target_desc *tdesc)
 {
diff --git a/gdbserver/tdesc.h b/gdbserver/tdesc.h
index 076451f4815..ffff346cf09 100644
--- a/gdbserver/tdesc.h
+++ b/gdbserver/tdesc.h
@@ -60,6 +60,9 @@ struct target_desc final : tdesc_element
   /* The value of <osabi> element in the XML, replying GDB.  */
   gdb::unique_xmalloc_ptr<char> osabi;
 
+  /* The value of the <device> element in the XML, replying GDB.  */
+  tdesc_device_up device;
+
 public:
   target_desc ()
     : registers_size (0)
diff --git a/gdbsupport/tdesc.cc b/gdbsupport/tdesc.cc
index 4b6aa815c81..c6ce443dac4 100644
--- a/gdbsupport/tdesc.cc
+++ b/gdbsupport/tdesc.cc
@@ -417,6 +417,8 @@ void print_xml_feature::visit_pre (const target_desc *e)
   for (const auto &c : compatible_list)
     add_line ("<compatible>%s</compatible>",
 	      tdesc_compatible_info_arch_name (c));
+
+  this->visit (tdesc_device_info (e));
 #endif
 }
 
@@ -426,6 +428,28 @@ void print_xml_feature::visit_post (const target_desc *e)
   add_line ("</target>");
 }
 
+void
+print_xml_feature::visit (const tdesc_device *device)
+{
+  if (device == nullptr)
+    return;
+
+  std::string tmp = "<device";
+  if (device->vendor_id.has_value ())
+    string_appendf (tmp, " vendor-id=\"0x%04" PRIx32 "\"",
+		    *device->vendor_id);
+
+  if (device->target_id.has_value ())
+    string_appendf (tmp, " target-id=\"0x%04" PRIx32 "\"",
+		    *device->target_id);
+
+  if (!device->name.empty ())
+    string_appendf (tmp, " name=\"%s\"", device->name.c_str ());
+
+  string_appendf (tmp, "/>");
+  add_line (tmp);
+}
+
 /* See gdbsupport/tdesc.h.  */
 
 void
diff --git a/gdbsupport/tdesc.h b/gdbsupport/tdesc.h
index a2ef21987bf..1051a1a98fb 100644
--- a/gdbsupport/tdesc.h
+++ b/gdbsupport/tdesc.h
@@ -26,6 +26,7 @@ struct tdesc_type_builtin;
 struct tdesc_type_vector;
 struct tdesc_type_with_fields;
 struct tdesc_reg;
+struct tdesc_device;
 struct target_desc;
 
 /* The interface to visit different elements of target description.  */
@@ -56,6 +57,9 @@ class tdesc_element_visitor
 
   virtual void visit (const tdesc_reg *e)
   {}
+
+  virtual void visit (const tdesc_device *e)
+  {}
 };
 
 class tdesc_element
@@ -315,6 +319,48 @@ struct tdesc_feature : tdesc_element
 
 using tdesc_feature_up = std::unique_ptr<tdesc_feature>;
 
+/* The device information in a target description.  */
+
+struct tdesc_device : tdesc_element
+{
+  tdesc_device ()
+  {
+    name = "";
+  }
+
+  virtual ~tdesc_device () = default;
+
+  DISABLE_COPY_AND_ASSIGN (tdesc_device);
+
+  /* The id of the device vendor.  */
+  std::optional<uint32_t> vendor_id;
+
+  /* The id of the device, given by its vendor.  */
+  std::optional<uint32_t> target_id;
+
+  /* The name of the device.  */
+  std::string name;
+
+  void accept (tdesc_element_visitor &v) const override
+  {
+    v.visit (this);
+  }
+
+  bool operator== (const tdesc_device &other) const
+  {
+    return (vendor_id == other.vendor_id
+	    && target_id == other.target_id
+	    && name == other.name);
+  }
+
+  bool operator!= (const tdesc_device &other) const
+  {
+    return !(*this == other);
+  }
+};
+
+typedef std::unique_ptr<tdesc_device> tdesc_device_up;
+
 /* A deleter adapter for a target_desc.  There are different
    implementations of this deleter class in gdb and gdbserver because even
    though the target_desc name is shared between the two projects, the
@@ -349,6 +395,13 @@ void set_tdesc_osabi (target_desc *target_desc, enum gdb_osabi osabi);
    or NULL if no osabi was specified.  */
 const char *tdesc_osabi_name (const struct target_desc *target_desc);
 
+/* Set TARGET_DESC's device information.  */
+void set_tdesc_device_info (target_desc *target_desc, tdesc_device *device);
+
+/* Return the device information associated with this target
+   description or NULL if device info does not exist.  */
+const tdesc_device *tdesc_device_info (const target_desc *target_desc);
+
 /* Return the type associated with ID in the context of FEATURE, or
    NULL if none.  */
 struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
@@ -441,6 +494,7 @@ class print_xml_feature : public tdesc_element_visitor
   void visit (const tdesc_type_vector *type) override;
   void visit (const tdesc_type_with_fields *type) override;
   void visit (const tdesc_reg *reg) override;
+  void visit (const tdesc_device *device) override;
 
 private:
 
-- 
2.43.0

________________________________________
Intel Deutschland GmbH 

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany 

Tel: +49 (89) 99143-0 

www.intel.de 

Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman

Chairperson of the Supervisory Board: Sonja Pierer

Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.