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