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