* opencl-lang.c (STRINGIFY): Rename to OCL_STRING.
[deliverable/binutils-gdb.git] / gdb / xml-tdesc.c
CommitLineData
23181151
DJ
1/* XML target description support for GDB.
2
7b6bb8da 3 Copyright (C) 2006, 2008, 2009, 2010, 2011 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"
23181151 28
108546a0
DJ
29#include "filenames.h"
30
23181151
DJ
31#include "gdb_assert.h"
32
33#if !defined(HAVE_LIBEXPAT)
34
35/* Parse DOCUMENT into a target description. Or don't, since we don't have
36 an XML parser. */
37
38static struct target_desc *
108546a0
DJ
39tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
40 void *fetcher_baton)
23181151
DJ
41{
42 static int have_warned;
43
44 if (!have_warned)
45 {
46 have_warned = 1;
47 warning (_("Can not parse XML target description; XML support was "
48 "disabled at compile time"));
49 }
50
51 return NULL;
52}
53
54#else /* HAVE_LIBEXPAT */
55
fc6e0168
DJ
56/* A record of every XML description we have parsed. We never discard
57 old descriptions, because we never discard gdbarches. As long as we
58 have a gdbarch referencing this description, we want to have a copy
59 of it here, so that if we parse the same XML document again we can
60 return the same "struct target_desc *"; if they are not singletons,
61 then we will create unnecessary duplicate gdbarches. See
62 gdbarch_list_lookup_by_info. */
63
64struct tdesc_xml_cache
65{
66 const char *xml_document;
67 struct target_desc *tdesc;
68};
69typedef struct tdesc_xml_cache tdesc_xml_cache_s;
70DEF_VEC_O(tdesc_xml_cache_s);
71
72static VEC(tdesc_xml_cache_s) *xml_cache;
73
23181151
DJ
74/* Callback data for target description parsing. */
75
76struct tdesc_parsing_data
77{
78 /* The target description we are building. */
79 struct target_desc *tdesc;
123dc839
DJ
80
81 /* The target feature we are currently parsing, or last parsed. */
82 struct tdesc_feature *current_feature;
83
84 /* The register number to use for the next register we see, if
85 it does not have its own. This starts at zero. */
86 int next_regnum;
87
f5dff777
DJ
88 /* The struct or union we are currently parsing, or last parsed. */
89 struct tdesc_type *current_type;
90
91 /* The byte size of the current struct type, if specified. Zero
92 if not specified. */
93 int current_type_size;
94
95 /* Whether the current type is a flags type. */
96 int current_type_is_flags;
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{
106 struct tdesc_parsing_data *data = user_data;
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{
123 struct tdesc_parsing_data *data = user_data;
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{
141 struct tdesc_parsing_data *data = user_data;
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{
1780a0ed
DJ
155 char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;
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{
170 struct tdesc_parsing_data *data = user_data;
171 char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
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{
184 struct tdesc_parsing_data *data = user_data;
185 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
186 int ix = 0, length;
187 char *name, *group, *type;
188 int bitsize, regnum, save_restore;
189
190 length = VEC_length (gdb_xml_value_s, attributes);
191
192 name = attrs[ix++].value;
193 bitsize = * (ULONGEST *) attrs[ix++].value;
194
195 if (ix < length && strcmp (attrs[ix].name, "regnum") == 0)
196 regnum = * (ULONGEST *) attrs[ix++].value;
197 else
198 regnum = data->next_regnum;
199
200 if (ix < length && strcmp (attrs[ix].name, "type") == 0)
201 type = attrs[ix++].value;
202 else
203 type = "int";
204
205 if (ix < length && strcmp (attrs[ix].name, "group") == 0)
206 group = attrs[ix++].value;
207 else
208 group = NULL;
209
210 if (ix < length && strcmp (attrs[ix].name, "save-restore") == 0)
211 save_restore = * (ULONGEST *) attrs[ix++].value;
212 else
213 save_restore = 1;
214
215 if (strcmp (type, "int") != 0
216 && strcmp (type, "float") != 0
217 && tdesc_named_type (data->current_feature, type) == NULL)
218 gdb_xml_error (parser, _("Register \"%s\" has unknown type \"%s\""),
219 name, type);
220
221 tdesc_create_reg (data->current_feature, name, regnum, save_restore, group,
222 bitsize, type);
223
224 data->next_regnum = regnum + 1;
225}
226
227/* Handle the start of a <union> element. Initialize the type and
228 record it with the current feature. */
229
230static void
231tdesc_start_union (struct gdb_xml_parser *parser,
232 const struct gdb_xml_element *element,
233 void *user_data, VEC(gdb_xml_value_s) *attributes)
234{
235 struct tdesc_parsing_data *data = user_data;
236 char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
123dc839 237
f5dff777
DJ
238 data->current_type = tdesc_create_union (data->current_feature, id);
239 data->current_type_size = 0;
240 data->current_type_is_flags = 0;
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{
251 struct tdesc_parsing_data *data = user_data;
252 char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
253 struct tdesc_type *type;
254
255 type = tdesc_create_struct (data->current_feature, id);
256 data->current_type = type;
257 data->current_type_size = 0;
258 data->current_type_is_flags = 0;
259
260 if (VEC_length (gdb_xml_value_s, attributes) > 1)
261 {
262 int size = (int) * (ULONGEST *)
263 VEC_index (gdb_xml_value_s, attributes, 1)->value;
a109c7c1 264
f5dff777
DJ
265 tdesc_set_struct_size (type, size);
266 data->current_type_size = size;
267 }
268}
269
270static void
271tdesc_start_flags (struct gdb_xml_parser *parser,
272 const struct gdb_xml_element *element,
273 void *user_data, VEC(gdb_xml_value_s) *attributes)
274{
275 struct tdesc_parsing_data *data = user_data;
276 char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
277 int length = (int) * (ULONGEST *)
278 VEC_index (gdb_xml_value_s, attributes, 1)->value;
279 struct tdesc_type *type;
280
281 type = tdesc_create_flags (data->current_feature, id, length);
282
283 data->current_type = type;
284 data->current_type_size = 0;
285 data->current_type_is_flags = 1;
123dc839
DJ
286}
287
288/* Handle the start of a <field> element. Attach the field to the
f5dff777 289 current struct or union. */
123dc839
DJ
290
291static void
292tdesc_start_field (struct gdb_xml_parser *parser,
293 const struct gdb_xml_element *element,
294 void *user_data, VEC(gdb_xml_value_s) *attributes)
295{
296 struct tdesc_parsing_data *data = user_data;
f5dff777 297 int ix = 0, length;
123dc839 298 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
ad068eab 299 struct tdesc_type *field_type;
123dc839 300 char *field_name, *field_type_id;
f5dff777 301 int start, end;
123dc839 302
f5dff777 303 length = VEC_length (gdb_xml_value_s, attributes);
123dc839 304
f5dff777 305 field_name = attrs[ix++].value;
123dc839 306
f5dff777
DJ
307 if (ix < length && strcmp (attrs[ix].name, "type") == 0)
308 field_type_id = attrs[ix++].value;
309 else
310 field_type_id = NULL;
311
312 if (ix < length && strcmp (attrs[ix].name, "start") == 0)
313 start = * (ULONGEST *) attrs[ix++].value;
314 else
315 start = -1;
316
317 if (ix < length && strcmp (attrs[ix].name, "end") == 0)
318 end = * (ULONGEST *) attrs[ix++].value;
319 else
320 end = -1;
321
322 if (field_type_id != NULL)
323 {
324 if (data->current_type_is_flags)
325 gdb_xml_error (parser, _("Cannot add typed field \"%s\" to flags"),
326 field_name);
327 if (data->current_type_size != 0)
328 gdb_xml_error (parser,
3e43a32a
MS
329 _("Explicitly sized type can not "
330 "contain non-bitfield \"%s\""),
f5dff777
DJ
331 field_name);
332
333 field_type = tdesc_named_type (data->current_feature, field_type_id);
334 if (field_type == NULL)
335 gdb_xml_error (parser, _("Field \"%s\" references undefined "
336 "type \"%s\""),
337 field_name, field_type_id);
338
339 tdesc_add_field (data->current_type, field_name, field_type);
340 }
341 else if (start != -1 && end != -1)
342 {
343 struct tdesc_type *t = data->current_type;
344
345 if (data->current_type_is_flags)
346 tdesc_add_flag (t, start, field_name);
347 else
348 {
349 if (data->current_type_size == 0)
350 gdb_xml_error (parser,
3e43a32a
MS
351 _("Implicitly sized type can "
352 "not contain bitfield \"%s\""),
f5dff777
DJ
353 field_name);
354
355 if (end >= 64)
356 gdb_xml_error (parser,
3e43a32a
MS
357 _("Bitfield \"%s\" goes past "
358 "64 bits (unsupported)"),
f5dff777
DJ
359 field_name);
360
361 /* Assume that the bit numbering in XML is "lsb-zero". Most
362 architectures other than PowerPC use this ordering. In
363 the future, we can add an XML tag to indicate "msb-zero"
364 numbering. */
365 if (start > end)
366 gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"),
367 field_name);
368
369 if (end >= data->current_type_size * TARGET_CHAR_BIT)
3e43a32a
MS
370 gdb_xml_error (parser,
371 _("Bitfield \"%s\" does not fit in struct"));
f5dff777
DJ
372
373 tdesc_add_bitfield (t, field_name, start, end);
374 }
375 }
376 else
377 gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"),
378 field_name);
123dc839
DJ
379}
380
381/* Handle the start of a <vector> element. Initialize the type and
382 record it with the current feature. */
383
384static void
385tdesc_start_vector (struct gdb_xml_parser *parser,
386 const struct gdb_xml_element *element,
387 void *user_data, VEC(gdb_xml_value_s) *attributes)
388{
389 struct tdesc_parsing_data *data = user_data;
390 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
ad068eab 391 struct tdesc_type *field_type;
123dc839
DJ
392 char *id, *field_type_id;
393 int count;
394
395 id = attrs[0].value;
396 field_type_id = attrs[1].value;
397 count = * (ULONGEST *) attrs[2].value;
398
399 field_type = tdesc_named_type (data->current_feature, field_type_id);
400 if (field_type == NULL)
401 gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
402 id, field_type_id);
403
ad068eab 404 tdesc_create_vector (data->current_feature, id, field_type, count);
123dc839
DJ
405}
406
23181151
DJ
407/* The elements and attributes of an XML target description. */
408
123dc839
DJ
409static const struct gdb_xml_attribute field_attributes[] = {
410 { "name", GDB_XML_AF_NONE, NULL, NULL },
f5dff777
DJ
411 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
412 { "start", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
413 { "end", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
123dc839
DJ
414 { NULL, GDB_XML_AF_NONE, NULL, NULL }
415};
416
f5dff777 417static const struct gdb_xml_element struct_union_children[] = {
123dc839
DJ
418 { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
419 tdesc_start_field, NULL },
420 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
421};
422
423static const struct gdb_xml_attribute reg_attributes[] = {
424 { "name", GDB_XML_AF_NONE, NULL, NULL },
425 { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
426 { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
427 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
428 { "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
429 { "save-restore", GDB_XML_AF_OPTIONAL,
430 gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
431 { NULL, GDB_XML_AF_NONE, NULL, NULL }
432};
433
f5dff777 434static const struct gdb_xml_attribute struct_union_attributes[] = {
123dc839 435 { "id", GDB_XML_AF_NONE, NULL, NULL },
f5dff777
DJ
436 { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL},
437 { NULL, GDB_XML_AF_NONE, NULL, NULL }
438};
439
440static const struct gdb_xml_attribute flags_attributes[] = {
441 { "id", GDB_XML_AF_NONE, NULL, NULL },
442 { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
123dc839
DJ
443 { NULL, GDB_XML_AF_NONE, NULL, NULL }
444};
445
446static const struct gdb_xml_attribute vector_attributes[] = {
447 { "id", GDB_XML_AF_NONE, NULL, NULL },
448 { "type", GDB_XML_AF_NONE, NULL, NULL },
449 { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
450 { NULL, GDB_XML_AF_NONE, NULL, NULL }
451};
452
453static const struct gdb_xml_attribute feature_attributes[] = {
454 { "name", GDB_XML_AF_NONE, NULL, NULL },
455 { NULL, GDB_XML_AF_NONE, NULL, NULL }
456};
457
458static const struct gdb_xml_element feature_children[] = {
459 { "reg", reg_attributes, NULL,
460 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
461 tdesc_start_reg, NULL },
f5dff777
DJ
462 { "struct", struct_union_attributes, struct_union_children,
463 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
464 tdesc_start_struct, NULL },
465 { "union", struct_union_attributes, struct_union_children,
123dc839 466 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
ad068eab 467 tdesc_start_union, NULL },
f5dff777
DJ
468 { "flags", flags_attributes, struct_union_children,
469 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
470 tdesc_start_flags, NULL },
123dc839
DJ
471 { "vector", vector_attributes, NULL,
472 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
473 tdesc_start_vector, NULL },
474 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
475};
476
1780a0ed
DJ
477static const struct gdb_xml_attribute target_attributes[] = {
478 { "version", GDB_XML_AF_NONE, NULL, NULL },
479 { NULL, GDB_XML_AF_NONE, NULL, NULL }
480};
481
123dc839 482static const struct gdb_xml_element target_children[] = {
23181151
DJ
483 { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
484 NULL, tdesc_end_arch },
08d16641
PA
485 { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
486 NULL, tdesc_end_osabi },
e35359c5
UW
487 { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
488 NULL, tdesc_end_compatible },
123dc839
DJ
489 { "feature", feature_attributes, feature_children,
490 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
491 tdesc_start_feature, NULL },
23181151
DJ
492 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
493};
494
123dc839 495static const struct gdb_xml_element tdesc_elements[] = {
1780a0ed
DJ
496 { "target", target_attributes, target_children, GDB_XML_EF_NONE,
497 tdesc_start_target, NULL },
23181151
DJ
498 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
499};
500
501/* Parse DOCUMENT into a target description and return it. */
502
503static struct target_desc *
108546a0
DJ
504tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
505 void *fetcher_baton)
23181151
DJ
506{
507 struct cleanup *back_to, *result_cleanup;
23181151 508 struct tdesc_parsing_data data;
fc6e0168 509 struct tdesc_xml_cache *cache;
108546a0 510 char *expanded_text;
fc6e0168 511 int ix;
23181151 512
108546a0
DJ
513 /* Expand all XInclude directives. */
514 expanded_text = xml_process_xincludes (_("target description"),
515 document, fetcher, fetcher_baton, 0);
516 if (expanded_text == NULL)
517 {
518 warning (_("Could not load XML target description; ignoring"));
519 return NULL;
520 }
23181151 521
fc6e0168
DJ
522 /* Check for an exact match in the list of descriptions we have
523 previously parsed. strcmp is a slightly inefficient way to
524 do this; an SHA-1 checksum would work as well. */
525 for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
526 if (strcmp (cache->xml_document, expanded_text) == 0)
527 {
528 xfree (expanded_text);
529 return cache->tdesc;
530 }
531
532 back_to = make_cleanup (null_cleanup, NULL);
23181151 533
108546a0 534 memset (&data, 0, sizeof (struct tdesc_parsing_data));
23181151
DJ
535 data.tdesc = allocate_target_description ();
536 result_cleanup = make_cleanup_free_target_description (data.tdesc);
fc6e0168 537 make_cleanup (xfree, expanded_text);
23181151 538
efc0eabd
PA
539 if (gdb_xml_parse_quick (_("target description"), "gdb-target.dtd",
540 tdesc_elements, expanded_text, &data) == 0)
23181151
DJ
541 {
542 /* Parsed successfully. */
fc6e0168
DJ
543 struct tdesc_xml_cache new_cache;
544
545 new_cache.xml_document = expanded_text;
546 new_cache.tdesc = data.tdesc;
547 VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
23181151
DJ
548 discard_cleanups (result_cleanup);
549 do_cleanups (back_to);
550 return data.tdesc;
551 }
552 else
553 {
554 warning (_("Could not load XML target description; ignoring"));
555 do_cleanups (back_to);
556 return NULL;
557 }
558}
23181151
DJ
559#endif /* HAVE_LIBEXPAT */
560\f
561
23181151
DJ
562/* Read an XML target description from FILENAME. Parse it, and return
563 the parsed description. */
564
565const struct target_desc *
566file_read_description_xml (const char *filename)
567{
568 struct target_desc *tdesc;
569 char *tdesc_str;
570 struct cleanup *back_to;
108546a0 571 char *dirname;
23181151 572
a96d9b2e 573 tdesc_str = xml_fetch_content_from_file (filename, NULL);
23181151 574 if (tdesc_str == NULL)
108546a0
DJ
575 {
576 warning (_("Could not open \"%s\""), filename);
577 return NULL;
578 }
23181151
DJ
579
580 back_to = make_cleanup (xfree, tdesc_str);
108546a0 581
e1024ff1
DJ
582 dirname = ldirname (filename);
583 if (dirname != NULL)
584 make_cleanup (xfree, dirname);
108546a0 585
a96d9b2e 586 tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
23181151
DJ
587 do_cleanups (back_to);
588
589 return tdesc;
590}
591
108546a0
DJ
592/* Read a string representation of available features from the target,
593 using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is
594 malloc allocated and NUL-terminated. NAME should be a non-NULL
595 string identifying the XML document we want; the top level document
596 is "target.xml". Other calls may be performed for the DTD or
597 for <xi:include>. */
598
599static char *
600fetch_available_features_from_target (const char *name, void *baton_)
601{
602 struct target_ops *ops = baton_;
603
604 /* Read this object as a string. This ensures that a NUL
605 terminator is added. */
606 return target_read_stralloc (ops,
607 TARGET_OBJECT_AVAILABLE_FEATURES,
608 name);
609}
610\f
611
23181151
DJ
612/* Read an XML target description using OPS. Parse it, and return the
613 parsed description. */
614
615const struct target_desc *
616target_read_description_xml (struct target_ops *ops)
617{
618 struct target_desc *tdesc;
619 char *tdesc_str;
620 struct cleanup *back_to;
621
108546a0 622 tdesc_str = fetch_available_features_from_target ("target.xml", ops);
23181151
DJ
623 if (tdesc_str == NULL)
624 return NULL;
625
626 back_to = make_cleanup (xfree, tdesc_str);
108546a0
DJ
627 tdesc = tdesc_parse_xml (tdesc_str,
628 fetch_available_features_from_target,
629 ops);
23181151
DJ
630 do_cleanups (back_to);
631
632 return tdesc;
633}
This page took 0.630863 seconds and 4 git commands to generate.