[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.