gdb/
[deliverable/binutils-gdb.git] / gdb / xml-tdesc.c
CommitLineData
23181151
DJ
1/* XML target description support for GDB.
2
4c38e0a4 3 Copyright (C) 2006, 2008, 2009, 2010 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,
329 _("Explicitly sized type can not contain non-bitfield \"%s\""),
330 field_name);
331
332 field_type = tdesc_named_type (data->current_feature, field_type_id);
333 if (field_type == NULL)
334 gdb_xml_error (parser, _("Field \"%s\" references undefined "
335 "type \"%s\""),
336 field_name, field_type_id);
337
338 tdesc_add_field (data->current_type, field_name, field_type);
339 }
340 else if (start != -1 && end != -1)
341 {
342 struct tdesc_type *t = data->current_type;
343
344 if (data->current_type_is_flags)
345 tdesc_add_flag (t, start, field_name);
346 else
347 {
348 if (data->current_type_size == 0)
349 gdb_xml_error (parser,
350 _("Implicitly sized type can not contain bitfield \"%s\""),
351 field_name);
352
353 if (end >= 64)
354 gdb_xml_error (parser,
355 _("Bitfield \"%s\" goes past 64 bits (unsupported)"),
356 field_name);
357
358 /* Assume that the bit numbering in XML is "lsb-zero". Most
359 architectures other than PowerPC use this ordering. In
360 the future, we can add an XML tag to indicate "msb-zero"
361 numbering. */
362 if (start > end)
363 gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"),
364 field_name);
365
366 if (end >= data->current_type_size * TARGET_CHAR_BIT)
367 gdb_xml_error (parser, _("Bitfield \"%s\" does not fit in struct"));
368
369 tdesc_add_bitfield (t, field_name, start, end);
370 }
371 }
372 else
373 gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"),
374 field_name);
123dc839
DJ
375}
376
377/* Handle the start of a <vector> element. Initialize the type and
378 record it with the current feature. */
379
380static void
381tdesc_start_vector (struct gdb_xml_parser *parser,
382 const struct gdb_xml_element *element,
383 void *user_data, VEC(gdb_xml_value_s) *attributes)
384{
385 struct tdesc_parsing_data *data = user_data;
386 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
ad068eab 387 struct tdesc_type *field_type;
123dc839
DJ
388 char *id, *field_type_id;
389 int count;
390
391 id = attrs[0].value;
392 field_type_id = attrs[1].value;
393 count = * (ULONGEST *) attrs[2].value;
394
395 field_type = tdesc_named_type (data->current_feature, field_type_id);
396 if (field_type == NULL)
397 gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
398 id, field_type_id);
399
ad068eab 400 tdesc_create_vector (data->current_feature, id, field_type, count);
123dc839
DJ
401}
402
23181151
DJ
403/* The elements and attributes of an XML target description. */
404
123dc839
DJ
405static const struct gdb_xml_attribute field_attributes[] = {
406 { "name", GDB_XML_AF_NONE, NULL, NULL },
f5dff777
DJ
407 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
408 { "start", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
409 { "end", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
123dc839
DJ
410 { NULL, GDB_XML_AF_NONE, NULL, NULL }
411};
412
f5dff777 413static const struct gdb_xml_element struct_union_children[] = {
123dc839
DJ
414 { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
415 tdesc_start_field, NULL },
416 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
417};
418
419static const struct gdb_xml_attribute reg_attributes[] = {
420 { "name", GDB_XML_AF_NONE, NULL, NULL },
421 { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
422 { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
423 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
424 { "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
425 { "save-restore", GDB_XML_AF_OPTIONAL,
426 gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
427 { NULL, GDB_XML_AF_NONE, NULL, NULL }
428};
429
f5dff777 430static const struct gdb_xml_attribute struct_union_attributes[] = {
123dc839 431 { "id", GDB_XML_AF_NONE, NULL, NULL },
f5dff777
DJ
432 { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL},
433 { NULL, GDB_XML_AF_NONE, NULL, NULL }
434};
435
436static const struct gdb_xml_attribute flags_attributes[] = {
437 { "id", GDB_XML_AF_NONE, NULL, NULL },
438 { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL},
123dc839
DJ
439 { NULL, GDB_XML_AF_NONE, NULL, NULL }
440};
441
442static const struct gdb_xml_attribute vector_attributes[] = {
443 { "id", GDB_XML_AF_NONE, NULL, NULL },
444 { "type", GDB_XML_AF_NONE, NULL, NULL },
445 { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
446 { NULL, GDB_XML_AF_NONE, NULL, NULL }
447};
448
449static const struct gdb_xml_attribute feature_attributes[] = {
450 { "name", GDB_XML_AF_NONE, NULL, NULL },
451 { NULL, GDB_XML_AF_NONE, NULL, NULL }
452};
453
454static const struct gdb_xml_element feature_children[] = {
455 { "reg", reg_attributes, NULL,
456 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
457 tdesc_start_reg, NULL },
f5dff777
DJ
458 { "struct", struct_union_attributes, struct_union_children,
459 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
460 tdesc_start_struct, NULL },
461 { "union", struct_union_attributes, struct_union_children,
123dc839 462 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
ad068eab 463 tdesc_start_union, NULL },
f5dff777
DJ
464 { "flags", flags_attributes, struct_union_children,
465 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
466 tdesc_start_flags, NULL },
123dc839
DJ
467 { "vector", vector_attributes, NULL,
468 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
469 tdesc_start_vector, NULL },
470 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
471};
472
1780a0ed
DJ
473static const struct gdb_xml_attribute target_attributes[] = {
474 { "version", GDB_XML_AF_NONE, NULL, NULL },
475 { NULL, GDB_XML_AF_NONE, NULL, NULL }
476};
477
123dc839 478static const struct gdb_xml_element target_children[] = {
23181151
DJ
479 { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
480 NULL, tdesc_end_arch },
08d16641
PA
481 { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
482 NULL, tdesc_end_osabi },
e35359c5
UW
483 { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
484 NULL, tdesc_end_compatible },
123dc839
DJ
485 { "feature", feature_attributes, feature_children,
486 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
487 tdesc_start_feature, NULL },
23181151
DJ
488 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
489};
490
123dc839 491static const struct gdb_xml_element tdesc_elements[] = {
1780a0ed
DJ
492 { "target", target_attributes, target_children, GDB_XML_EF_NONE,
493 tdesc_start_target, NULL },
23181151
DJ
494 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
495};
496
497/* Parse DOCUMENT into a target description and return it. */
498
499static struct target_desc *
108546a0
DJ
500tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
501 void *fetcher_baton)
23181151
DJ
502{
503 struct cleanup *back_to, *result_cleanup;
504 struct gdb_xml_parser *parser;
505 struct tdesc_parsing_data data;
fc6e0168 506 struct tdesc_xml_cache *cache;
108546a0 507 char *expanded_text;
fc6e0168 508 int ix;
23181151 509
108546a0
DJ
510 /* Expand all XInclude directives. */
511 expanded_text = xml_process_xincludes (_("target description"),
512 document, fetcher, fetcher_baton, 0);
513 if (expanded_text == NULL)
514 {
515 warning (_("Could not load XML target description; ignoring"));
516 return NULL;
517 }
23181151 518
fc6e0168
DJ
519 /* Check for an exact match in the list of descriptions we have
520 previously parsed. strcmp is a slightly inefficient way to
521 do this; an SHA-1 checksum would work as well. */
522 for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
523 if (strcmp (cache->xml_document, expanded_text) == 0)
524 {
525 xfree (expanded_text);
526 return cache->tdesc;
527 }
528
529 back_to = make_cleanup (null_cleanup, NULL);
23181151
DJ
530 parser = gdb_xml_create_parser_and_cleanup (_("target description"),
531 tdesc_elements, &data);
108546a0 532 gdb_xml_use_dtd (parser, "gdb-target.dtd");
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
108546a0 539 if (gdb_xml_parse (parser, expanded_text) == 0)
23181151
DJ
540 {
541 /* Parsed successfully. */
fc6e0168
DJ
542 struct tdesc_xml_cache new_cache;
543
544 new_cache.xml_document = expanded_text;
545 new_cache.tdesc = data.tdesc;
546 VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
23181151
DJ
547 discard_cleanups (result_cleanup);
548 do_cleanups (back_to);
549 return data.tdesc;
550 }
551 else
552 {
553 warning (_("Could not load XML target description; ignoring"));
554 do_cleanups (back_to);
555 return NULL;
556 }
557}
23181151
DJ
558#endif /* HAVE_LIBEXPAT */
559\f
560
23181151
DJ
561/* Read an XML target description from FILENAME. Parse it, and return
562 the parsed description. */
563
564const struct target_desc *
565file_read_description_xml (const char *filename)
566{
567 struct target_desc *tdesc;
568 char *tdesc_str;
569 struct cleanup *back_to;
108546a0 570 char *dirname;
23181151 571
a96d9b2e 572 tdesc_str = xml_fetch_content_from_file (filename, NULL);
23181151 573 if (tdesc_str == NULL)
108546a0
DJ
574 {
575 warning (_("Could not open \"%s\""), filename);
576 return NULL;
577 }
23181151
DJ
578
579 back_to = make_cleanup (xfree, tdesc_str);
108546a0 580
e1024ff1
DJ
581 dirname = ldirname (filename);
582 if (dirname != NULL)
583 make_cleanup (xfree, dirname);
108546a0 584
a96d9b2e 585 tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
23181151
DJ
586 do_cleanups (back_to);
587
588 return tdesc;
589}
590
108546a0
DJ
591/* Read a string representation of available features from the target,
592 using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is
593 malloc allocated and NUL-terminated. NAME should be a non-NULL
594 string identifying the XML document we want; the top level document
595 is "target.xml". Other calls may be performed for the DTD or
596 for <xi:include>. */
597
598static char *
599fetch_available_features_from_target (const char *name, void *baton_)
600{
601 struct target_ops *ops = baton_;
602
603 /* Read this object as a string. This ensures that a NUL
604 terminator is added. */
605 return target_read_stralloc (ops,
606 TARGET_OBJECT_AVAILABLE_FEATURES,
607 name);
608}
609\f
610
23181151
DJ
611/* Read an XML target description using OPS. Parse it, and return the
612 parsed description. */
613
614const struct target_desc *
615target_read_description_xml (struct target_ops *ops)
616{
617 struct target_desc *tdesc;
618 char *tdesc_str;
619 struct cleanup *back_to;
620
108546a0 621 tdesc_str = fetch_available_features_from_target ("target.xml", ops);
23181151
DJ
622 if (tdesc_str == NULL)
623 return NULL;
624
625 back_to = make_cleanup (xfree, tdesc_str);
108546a0
DJ
626 tdesc = tdesc_parse_xml (tdesc_str,
627 fetch_available_features_from_target,
628 ops);
23181151
DJ
629 do_cleanups (back_to);
630
631 return tdesc;
632}
This page took 0.530435 seconds and 4 git commands to generate.