1 /* XML target description support for GDB.
2 
3    Copyright (C) 2006-2024 Free Software Foundation, Inc.
4 
5    Contributed by CodeSourcery.
6 
7    This file is part of GDB.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21 
22 #include "target.h"
23 #include "target-descriptions.h"
24 #include "xml-support.h"
25 #include "xml-tdesc.h"
26 #include "osabi.h"
27 #include "filenames.h"
28 #include <unordered_map>
29 #include <string>
30 
31 /* Maximum sizes.
32    This is just to catch obviously wrong values.  */
33 #define MAX_FIELD_SIZE 65536
34 #define MAX_FIELD_BITSIZE (MAX_FIELD_SIZE * TARGET_CHAR_BIT)
35 #define MAX_VECTOR_SIZE 65536
36 
37 #if !defined(HAVE_LIBEXPAT)
38 
39 /* Parse DOCUMENT into a target description.  Or don't, since we don't have
40    an XML parser.  */
41 
42 static struct target_desc *
tdesc_parse_xml(const char * document,xml_fetch_another fetcher)43 tdesc_parse_xml (const char *document, xml_fetch_another fetcher)
44 {
45   static int have_warned;
46 
47   if (!have_warned)
48     {
49       have_warned = 1;
50       warning (_("Can not parse XML target description; XML support was "
51                      "disabled at compile time"));
52     }
53 
54   return NULL;
55 }
56 
57 #else /* HAVE_LIBEXPAT */
58 
59 /* A record of every XML description we have parsed.  We never discard
60    old descriptions, because we never discard gdbarches.  As long as we
61    have a gdbarch referencing this description, we want to have a copy
62    of it here, so that if we parse the same XML document again we can
63    return the same "struct target_desc *"; if they are not singletons,
64    then we will create unnecessary duplicate gdbarches.  See
65    gdbarch_list_lookup_by_info.  */
66 
67 static std::unordered_map<std::string, target_desc_up> xml_cache;
68 
69 /* Callback data for target description parsing.  */
70 
71 struct tdesc_parsing_data
72 {
73   /* The target description we are building.  */
74   struct target_desc *tdesc;
75 
76   /* The target feature we are currently parsing, or last parsed.  */
77   struct tdesc_feature *current_feature;
78 
79   /* The register number to use for the next register we see, if
80      it does not have its own.  This starts at zero.  */
81   int next_regnum;
82 
83   /* The struct or union we are currently parsing, or last parsed.  */
84   tdesc_type_with_fields *current_type;
85 
86   /* The byte size of the current struct/flags type, if specified.  Zero
87      if not specified.  Flags values must specify a size.  */
88   int current_type_size;
89 };
90 
91 /* Handle the end of an <architecture> element and its value.  */
92 
93 static void
tdesc_end_arch(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,const char * body_text)94 tdesc_end_arch (struct gdb_xml_parser *parser,
95                     const struct gdb_xml_element *element,
96                     void *user_data, const char *body_text)
97 {
98   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
99   const struct bfd_arch_info *arch;
100 
101   arch = bfd_scan_arch (body_text);
102   if (arch == NULL)
103     gdb_xml_error (parser, _("Target description specified unknown "
104                                    "architecture \"%s\""), body_text);
105   set_tdesc_architecture (data->tdesc, arch);
106 }
107 
108 /* Handle the end of an <osabi> element and its value.  */
109 
110 static void
tdesc_end_osabi(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,const char * body_text)111 tdesc_end_osabi (struct gdb_xml_parser *parser,
112                      const struct gdb_xml_element *element,
113                      void *user_data, const char *body_text)
114 {
115   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
116   enum gdb_osabi osabi;
117 
118   osabi = osabi_from_tdesc_string (body_text);
119   if (osabi == GDB_OSABI_UNKNOWN)
120     warning (_("Target description specified unknown osabi \"%s\""),
121                body_text);
122   else
123     set_tdesc_osabi (data->tdesc, osabi);
124 }
125 
126 /* Handle the end of a <compatible> element and its value.  */
127 
128 static void
tdesc_end_compatible(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,const char * body_text)129 tdesc_end_compatible (struct gdb_xml_parser *parser,
130                           const struct gdb_xml_element *element,
131                           void *user_data, const char *body_text)
132 {
133   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
134   const struct bfd_arch_info *arch;
135 
136   arch = bfd_scan_arch (body_text);
137   tdesc_add_compatible (data->tdesc, arch);
138 }
139 
140 /* Handle the start of a <target> element.  */
141 
142 static void
tdesc_start_target(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)143 tdesc_start_target (struct gdb_xml_parser *parser,
144                         const struct gdb_xml_element *element,
145                         void *user_data, std::vector<gdb_xml_value> &attributes)
146 {
147   char *version
148     = (char *) xml_find_attribute (attributes, "version")->value.get ();
149 
150   if (strcmp (version, "1.0") != 0)
151     gdb_xml_error (parser,
152                        _("Target description has unsupported version \"%s\""),
153                        version);
154 }
155 
156 /* Handle the start of a <feature> element.  */
157 
158 static void
tdesc_start_feature(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)159 tdesc_start_feature (struct gdb_xml_parser *parser,
160                          const struct gdb_xml_element *element,
161                          void *user_data, std::vector<gdb_xml_value> &attributes)
162 {
163   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
164   char *name = (char *) xml_find_attribute (attributes, "name")->value.get ();
165 
166   data->current_feature = tdesc_create_feature (data->tdesc, name);
167 }
168 
169 /* Handle the start of a <reg> element.  Fill in the optional
170    attributes and attach it to the containing feature.  */
171 
172 static void
tdesc_start_reg(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)173 tdesc_start_reg (struct gdb_xml_parser *parser,
174                      const struct gdb_xml_element *element,
175                      void *user_data, std::vector<gdb_xml_value> &attributes)
176 {
177   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
178   int ix = 0;
179   char *name, *group;
180   const char *type;
181   int bitsize, regnum, save_restore;
182 
183   int length = attributes.size ();
184 
185   name = (char *) attributes[ix++].value.get ();
186   bitsize = * (ULONGEST *) attributes[ix++].value.get ();
187 
188   if (ix < length && strcmp (attributes[ix].name, "regnum") == 0)
189     regnum = * (ULONGEST *) attributes[ix++].value.get ();
190   else
191     regnum = data->next_regnum;
192 
193   if (ix < length && strcmp (attributes[ix].name, "type") == 0)
194     type = (char *) attributes[ix++].value.get ();
195   else
196     type = "int";
197 
198   if (ix < length && strcmp (attributes[ix].name, "group") == 0)
199     group = (char *) attributes[ix++].value.get ();
200   else
201     group = NULL;
202 
203   if (ix < length && strcmp (attributes[ix].name, "save-restore") == 0)
204     save_restore = * (ULONGEST *) attributes[ix++].value.get ();
205   else
206     save_restore = 1;
207 
208   if (strcmp (type, "int") != 0
209       && strcmp (type, "float") != 0
210       && tdesc_named_type (data->current_feature, type) == NULL)
211     gdb_xml_error (parser, _("Register \"%s\" has unknown type \"%s\""),
212                        name, type);
213 
214   tdesc_create_reg (data->current_feature, name, regnum, save_restore, group,
215                         bitsize, type);
216 
217   data->next_regnum = regnum + 1;
218 }
219 
220 /* Handle the start of a <union> element.  Initialize the type and
221    record it with the current feature.  */
222 
223 static void
tdesc_start_union(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)224 tdesc_start_union (struct gdb_xml_parser *parser,
225                        const struct gdb_xml_element *element,
226                        void *user_data, std::vector<gdb_xml_value> &attributes)
227 {
228   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
229   char *id = (char *) xml_find_attribute (attributes, "id")->value.get ();
230 
231   data->current_type = tdesc_create_union (data->current_feature, id);
232   data->current_type_size = 0;
233 }
234 
235 /* Handle the start of a <struct> element.  Initialize the type and
236    record it with the current feature.  */
237 
238 static void
tdesc_start_struct(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)239 tdesc_start_struct (struct gdb_xml_parser *parser,
240                        const struct gdb_xml_element *element,
241                        void *user_data, std::vector<gdb_xml_value> &attributes)
242 {
243   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
244   char *id = (char *) xml_find_attribute (attributes, "id")->value.get ();
245   struct gdb_xml_value *attr;
246 
247   tdesc_type_with_fields *type_with_fields
248     = tdesc_create_struct (data->current_feature, id);
249   data->current_type = type_with_fields;
250   data->current_type_size = 0;
251 
252   attr = xml_find_attribute (attributes, "size");
253   if (attr != NULL)
254     {
255       ULONGEST size = * (ULONGEST *) attr->value.get ();
256 
257       if (size > MAX_FIELD_SIZE)
258           {
259             gdb_xml_error (parser,
260                                _("Struct size %s is larger than maximum (%d)"),
261                                pulongest (size), MAX_FIELD_SIZE);
262           }
263       tdesc_set_struct_size (type_with_fields, size);
264       data->current_type_size = size;
265     }
266 }
267 
268 static void
tdesc_start_flags(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)269 tdesc_start_flags (struct gdb_xml_parser *parser,
270                        const struct gdb_xml_element *element,
271                        void *user_data, std::vector<gdb_xml_value> &attributes)
272 {
273   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
274   char *id = (char *) xml_find_attribute (attributes, "id")->value.get ();
275   ULONGEST size = * (ULONGEST *)
276     xml_find_attribute (attributes, "size")->value.get ();
277 
278   if (size > MAX_FIELD_SIZE)
279     {
280       gdb_xml_error (parser,
281                          _("Flags size %s is larger than maximum (%d)"),
282                          pulongest (size), MAX_FIELD_SIZE);
283     }
284 
285   data->current_type = tdesc_create_flags (data->current_feature, id, size);
286   data->current_type_size = size;
287 }
288 
289 static void
tdesc_start_enum(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)290 tdesc_start_enum (struct gdb_xml_parser *parser,
291                       const struct gdb_xml_element *element,
292                       void *user_data, std::vector<gdb_xml_value> &attributes)
293 {
294   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
295   char *id = (char *) xml_find_attribute (attributes, "id")->value.get ();
296   int size = * (ULONGEST *)
297     xml_find_attribute (attributes, "size")->value.get ();
298 
299   if (size > MAX_FIELD_SIZE)
300     {
301       gdb_xml_error (parser,
302                          _("Enum size %s is larger than maximum (%d)"),
303                          pulongest (size), MAX_FIELD_SIZE);
304     }
305 
306   data->current_type = tdesc_create_enum (data->current_feature, id, size);
307   data->current_type_size = 0;
308 }
309 
310 /* Handle the start of a <field> element.  Attach the field to the
311    current struct, union or flags.  */
312 
313 static void
tdesc_start_field(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)314 tdesc_start_field (struct gdb_xml_parser *parser,
315                        const struct gdb_xml_element *element,
316                        void *user_data, std::vector<gdb_xml_value> &attributes)
317 {
318   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
319   struct gdb_xml_value *attr;
320   struct tdesc_type *field_type;
321   char *field_name, *field_type_id;
322   int start, end;
323 
324   field_name = (char *) xml_find_attribute (attributes, "name")->value.get ();
325 
326   attr = xml_find_attribute (attributes, "type");
327   if (attr != NULL)
328     {
329       field_type_id = (char *) attr->value.get ();
330       field_type = tdesc_named_type (data->current_feature, field_type_id);
331     }
332   else
333     {
334       field_type_id = NULL;
335       field_type = NULL;
336     }
337 
338   attr = xml_find_attribute (attributes, "start");
339   if (attr != NULL)
340     {
341       ULONGEST ul_start = * (ULONGEST *) attr->value.get ();
342 
343       if (ul_start > MAX_FIELD_BITSIZE)
344           {
345             gdb_xml_error (parser,
346                                _("Field start %s is larger than maximum (%d)"),
347                                pulongest (ul_start), MAX_FIELD_BITSIZE);
348           }
349       start = ul_start;
350     }
351   else
352     start = -1;
353 
354   attr = xml_find_attribute (attributes, "end");
355   if (attr != NULL)
356     {
357       ULONGEST ul_end = * (ULONGEST *) attr->value.get ();
358 
359       if (ul_end > MAX_FIELD_BITSIZE)
360           {
361             gdb_xml_error (parser,
362                                _("Field end %s is larger than maximum (%d)"),
363                                pulongest (ul_end), MAX_FIELD_BITSIZE);
364           }
365       end = ul_end;
366     }
367   else
368     end = -1;
369 
370   if (start != -1)
371     {
372       tdesc_type_with_fields *t = data->current_type;
373 
374       /* Older versions of gdb can't handle elided end values.
375            Stick with that for now, to help ensure backward compatibility.
376            E.g., If a newer gdbserver is talking to an older gdb.  */
377       if (end == -1)
378           gdb_xml_error (parser, _("Missing end value"));
379 
380       if (data->current_type_size == 0)
381           gdb_xml_error (parser,
382                            _("Bitfields must live in explicitly sized types"));
383 
384       if (field_type_id != NULL
385             && strcmp (field_type_id, "bool") == 0
386             && start != end)
387           {
388             gdb_xml_error (parser,
389                                _("Boolean fields must be one bit in size"));
390           }
391 
392       if (end >= 64)
393           gdb_xml_error (parser,
394                            _("Bitfield \"%s\" goes past "
395                                "64 bits (unsupported)"),
396                            field_name);
397 
398       /* Assume that the bit numbering in XML is "lsb-zero".  Most
399            architectures other than PowerPC use this ordering.  In the
400            future, we can add an XML tag to indicate "msb-zero" numbering.  */
401       if (start > end)
402           gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"),
403                            field_name);
404       if (end >= data->current_type_size * TARGET_CHAR_BIT)
405           gdb_xml_error (parser, _("Bitfield \"%s\" does not fit in struct"),
406                            field_name);
407 
408       if (field_type != NULL)
409           tdesc_add_typed_bitfield (t, field_name, start, end, field_type);
410       else if (start == end)
411           tdesc_add_flag (t, start, field_name);
412       else
413           tdesc_add_bitfield (t, field_name, start, end);
414     }
415   else if (start == -1 && end != -1)
416     gdb_xml_error (parser, _("End specified but not start"));
417   else if (field_type_id != NULL)
418     {
419       /* TDESC_TYPE_FLAGS values are explicitly sized, so the following test
420            catches adding non-bitfield types to flags as well.  */
421       if (data->current_type_size != 0)
422           gdb_xml_error (parser,
423                            _("Explicitly sized type cannot "
424                                "contain non-bitfield \"%s\""),
425                            field_name);
426 
427       if (field_type == NULL)
428           gdb_xml_error (parser, _("Field \"%s\" references undefined "
429                                          "type \"%s\""),
430                            field_name, field_type_id);
431 
432       tdesc_add_field (data->current_type, field_name, field_type);
433     }
434   else
435     gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"),
436                        field_name);
437 }
438 
439 /* Handle the start of an <evalue> element.  Attach the value to the
440    current enum.  */
441 
442 static void
tdesc_start_enum_value(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)443 tdesc_start_enum_value (struct gdb_xml_parser *parser,
444                               const struct gdb_xml_element *element,
445                               void *user_data, std::vector<gdb_xml_value> &attributes)
446 {
447   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
448   struct gdb_xml_value *attr;
449   char *field_name;
450   ULONGEST ul_value;
451   int value;
452 
453   field_name = (char *) xml_find_attribute (attributes, "name")->value.get ();
454 
455   attr = xml_find_attribute (attributes, "value");
456   ul_value = * (ULONGEST *) attr->value.get ();
457   if (ul_value > INT_MAX)
458     {
459       gdb_xml_error (parser,
460                          _("Enum value %s is larger than maximum (%d)"),
461                          pulongest (ul_value), INT_MAX);
462     }
463   value = ul_value;
464 
465   tdesc_add_enum_value (data->current_type, value, field_name);
466 }
467 
468 /* Handle the start of a <vector> element.  Initialize the type and
469    record it with the current feature.  */
470 
471 static void
tdesc_start_vector(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,std::vector<gdb_xml_value> & attributes)472 tdesc_start_vector (struct gdb_xml_parser *parser,
473                         const struct gdb_xml_element *element,
474                         void *user_data, std::vector<gdb_xml_value> &attributes)
475 {
476   struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data;
477   struct tdesc_type *field_type;
478   char *id, *field_type_id;
479   ULONGEST count;
480 
481   id = (char *) attributes[0].value.get ();
482   field_type_id = (char *) attributes[1].value.get ();
483   count = * (ULONGEST *) attributes[2].value.get ();
484 
485   if (count > MAX_VECTOR_SIZE)
486     {
487       gdb_xml_error (parser,
488                          _("Vector size %s is larger than maximum (%d)"),
489                          pulongest (count), MAX_VECTOR_SIZE);
490     }
491 
492   field_type = tdesc_named_type (data->current_feature, field_type_id);
493   if (field_type == NULL)
494     gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
495                        id, field_type_id);
496 
497   tdesc_create_vector (data->current_feature, id, field_type, count);
498 }
499 
500 /* The elements and attributes of an XML target description.  */
501 
502 static const struct gdb_xml_attribute field_attributes[] = {
503   { "name", GDB_XML_AF_NONE, NULL, NULL },
504   { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
505   { "start", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
506   { "end", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
507   { NULL, GDB_XML_AF_NONE, NULL, NULL }
508 };
509 
510 static const struct gdb_xml_attribute enum_value_attributes[] = {
511   { "name", GDB_XML_AF_NONE, NULL, NULL },
512   { "value", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
513   { NULL, GDB_XML_AF_NONE, NULL, NULL }
514 };
515 
516 static const struct gdb_xml_element struct_union_children[] = {
517   { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
518     tdesc_start_field, NULL },
519   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
520 };
521 
522 static const struct gdb_xml_element enum_children[] = {
523   { "evalue", enum_value_attributes, NULL, GDB_XML_EF_REPEATABLE,
524     tdesc_start_enum_value, NULL },
525   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
526 };
527 
528 static const struct gdb_xml_attribute reg_attributes[] = {
529   { "name", GDB_XML_AF_NONE, NULL, NULL },
530   { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
531   { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
532   { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
533   { "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
534   { "save-restore", GDB_XML_AF_OPTIONAL,
535     gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
536   { NULL, GDB_XML_AF_NONE, NULL, NULL }
537 };
538 
539 static const struct gdb_xml_attribute struct_union_attributes[] = {
540   { "id", GDB_XML_AF_NONE, NULL, NULL },
541   { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL},
542   { NULL, GDB_XML_AF_NONE, NULL, NULL }
543 };
544 
545 static const struct gdb_xml_attribute flags_attributes[] = {
546   { "id", GDB_XML_AF_NONE, NULL, NULL },
547   { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
548   { NULL, GDB_XML_AF_NONE, NULL, NULL }
549 };
550 
551 static const struct gdb_xml_attribute enum_attributes[] = {
552   { "id", GDB_XML_AF_NONE, NULL, NULL },
553   { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
554   { NULL, GDB_XML_AF_NONE, NULL, NULL }
555 };
556 
557 static const struct gdb_xml_attribute vector_attributes[] = {
558   { "id", GDB_XML_AF_NONE, NULL, NULL },
559   { "type", GDB_XML_AF_NONE, NULL, NULL },
560   { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
561   { NULL, GDB_XML_AF_NONE, NULL, NULL }
562 };
563 
564 static const struct gdb_xml_attribute feature_attributes[] = {
565   { "name", GDB_XML_AF_NONE, NULL, NULL },
566   { NULL, GDB_XML_AF_NONE, NULL, NULL }
567 };
568 
569 static const struct gdb_xml_element feature_children[] = {
570   { "reg", reg_attributes, NULL,
571     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
572     tdesc_start_reg, NULL },
573   { "struct", struct_union_attributes, struct_union_children,
574     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
575     tdesc_start_struct, NULL },
576   { "union", struct_union_attributes, struct_union_children,
577     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
578     tdesc_start_union, NULL },
579   { "flags", flags_attributes, struct_union_children,
580     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
581     tdesc_start_flags, NULL },
582   { "enum", enum_attributes, enum_children,
583     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
584     tdesc_start_enum, NULL },
585   { "vector", vector_attributes, NULL,
586     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
587     tdesc_start_vector, NULL },
588   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
589 };
590 
591 static const struct gdb_xml_attribute target_attributes[] = {
592   { "version", GDB_XML_AF_NONE, NULL, NULL },
593   { NULL, GDB_XML_AF_NONE, NULL, NULL }
594 };
595 
596 static const struct gdb_xml_element target_children[] = {
597   { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
598     NULL, tdesc_end_arch },
599   { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
600     NULL, tdesc_end_osabi },
601   { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
602     NULL, tdesc_end_compatible },
603   { "feature", feature_attributes, feature_children,
604     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
605     tdesc_start_feature, NULL },
606   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
607 };
608 
609 static const struct gdb_xml_element tdesc_elements[] = {
610   { "target", target_attributes, target_children, GDB_XML_EF_NONE,
611     tdesc_start_target, NULL },
612   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
613 };
614 
615 /* Parse DOCUMENT into a target description and return it.  */
616 
617 static struct target_desc *
tdesc_parse_xml(const char * document,xml_fetch_another fetcher)618 tdesc_parse_xml (const char *document, xml_fetch_another fetcher)
619 {
620   struct tdesc_parsing_data data;
621 
622   /* Expand all XInclude directives.  */
623   std::string expanded_text;
624 
625   if (!xml_process_xincludes (expanded_text,
626                                     _("target description"),
627                                     document, fetcher, 0))
628     {
629       warning (_("Could not load XML target description; ignoring"));
630       return NULL;
631     }
632 
633   /* Check for an exact match in the list of descriptions we have
634      previously parsed.  */
635   const auto it = xml_cache.find (expanded_text);
636   if (it != xml_cache.end ())
637     return it->second.get ();
638 
639   memset (&data, 0, sizeof (struct tdesc_parsing_data));
640   target_desc_up description = allocate_target_description ();
641   data.tdesc = description.get ();
642 
643   if (gdb_xml_parse_quick (_("target description"), "gdb-target.dtd",
644                                  tdesc_elements, expanded_text.c_str (), &data) == 0)
645     {
646       /* Parsed successfully.  */
647       xml_cache.emplace (std::move (expanded_text), std::move (description));
648       return data.tdesc;
649     }
650   else
651     {
652       warning (_("Could not load XML target description; ignoring"));
653       return NULL;
654     }
655 }
656 #endif /* HAVE_LIBEXPAT */
657 
658 
659 /* Read an XML target description from FILENAME.  Parse it, and return
660    the parsed description.  */
661 
662 const struct target_desc *
file_read_description_xml(const char * filename)663 file_read_description_xml (const char *filename)
664 {
665   std::optional<gdb::char_vector> tdesc_str
666     = xml_fetch_content_from_file (filename, NULL);
667   if (!tdesc_str)
668     {
669       warning (_("Could not open \"%s\""), filename);
670       return NULL;
671     }
672 
673   const std::string dirname = ldirname (filename);
674   auto fetch_another = [&dirname] (const char *name)
675     {
676       return xml_fetch_content_from_file (name, dirname.c_str ());
677     };
678 
679   return tdesc_parse_xml (tdesc_str->data (), fetch_another);
680 }
681 
682 /* Read a string representation of available features from the target,
683    using TARGET_OBJECT_AVAILABLE_FEATURES.  The returned string is
684    malloc allocated and NUL-terminated.  NAME should be a non-NULL
685    string identifying the XML document we want; the top level document
686    is "target.xml".  Other calls may be performed for the DTD or
687    for <xi:include>.  */
688 
689 static std::optional<gdb::char_vector>
fetch_available_features_from_target(const char * name,target_ops * ops)690 fetch_available_features_from_target (const char *name, target_ops *ops)
691 {
692   /* Read this object as a string.  This ensures that a NUL
693      terminator is added.  */
694   return target_read_stralloc (ops,
695                                      TARGET_OBJECT_AVAILABLE_FEATURES,
696                                      name);
697 }
698 
699 
700 /* Read an XML target description using OPS.  Parse it, and return the
701    parsed description.  */
702 
703 const struct target_desc *
target_read_description_xml(struct target_ops * ops)704 target_read_description_xml (struct target_ops *ops)
705 {
706   std::optional<gdb::char_vector> tdesc_str
707     = fetch_available_features_from_target ("target.xml", ops);
708   if (!tdesc_str)
709     return NULL;
710 
711   auto fetch_another = [ops] (const char *name)
712     {
713       return fetch_available_features_from_target (name, ops);
714     };
715 
716   return tdesc_parse_xml (tdesc_str->data (), fetch_another);
717 }
718 
719 /* Fetches an XML target description using OPS,  processing
720    includes, but not parsing it.  Used to dump whole tdesc
721    as a single XML file.  */
722 
723 std::optional<std::string>
target_fetch_description_xml(struct target_ops * ops)724 target_fetch_description_xml (struct target_ops *ops)
725 {
726 #if !defined(HAVE_LIBEXPAT)
727   static int have_warned;
728 
729   if (!have_warned)
730     {
731       have_warned = 1;
732       warning (_("Can not fetch XML target description; XML support was "
733                      "disabled at compile time"));
734     }
735 
736   return {};
737 #else
738   std::optional<gdb::char_vector>
739     tdesc_str = fetch_available_features_from_target ("target.xml", ops);
740   if (!tdesc_str)
741     return {};
742 
743   auto fetch_another = [ops] (const char *name)
744     {
745       return fetch_available_features_from_target (name, ops);
746     };
747   std::string output;
748   if (!xml_process_xincludes (output,
749                                     _("target description"),
750                                     tdesc_str->data (), fetch_another, 0))
751     {
752       warning (_("Could not load XML target description; ignoring"));
753       return {};
754     }
755   return output;
756 #endif
757 }
758 
759 /* See xml-tdesc.h.  */
760 
761 const struct target_desc *
string_read_description_xml(const char * xml)762 string_read_description_xml (const char *xml)
763 {
764   return tdesc_parse_xml (xml, [] (const char *href)
765     {
766       error (_("xincludes are unsupported with this method"));
767       return std::optional<gdb::char_vector> ();
768     });
769 }
770