2011-01-05 Michael Snyder <msnyder@vmware.com>
[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;
508 struct gdb_xml_parser *parser;
509 struct tdesc_parsing_data data;
fc6e0168 510 struct tdesc_xml_cache *cache;
108546a0 511 char *expanded_text;
fc6e0168 512 int ix;
23181151 513
108546a0
DJ
514 /* Expand all XInclude directives. */
515 expanded_text = xml_process_xincludes (_("target description"),
516 document, fetcher, fetcher_baton, 0);
517 if (expanded_text == NULL)
518 {
519 warning (_("Could not load XML target description; ignoring"));
520 return NULL;
521 }
23181151 522
fc6e0168
DJ
523 /* Check for an exact match in the list of descriptions we have
524 previously parsed. strcmp is a slightly inefficient way to
525 do this; an SHA-1 checksum would work as well. */
526 for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
527 if (strcmp (cache->xml_document, expanded_text) == 0)
528 {
529 xfree (expanded_text);
530 return cache->tdesc;
531 }
532
533 back_to = make_cleanup (null_cleanup, NULL);
23181151
DJ
534 parser = gdb_xml_create_parser_and_cleanup (_("target description"),
535 tdesc_elements, &data);
108546a0 536 gdb_xml_use_dtd (parser, "gdb-target.dtd");
23181151 537
108546a0 538 memset (&data, 0, sizeof (struct tdesc_parsing_data));
23181151
DJ
539 data.tdesc = allocate_target_description ();
540 result_cleanup = make_cleanup_free_target_description (data.tdesc);
fc6e0168 541 make_cleanup (xfree, expanded_text);
23181151 542
108546a0 543 if (gdb_xml_parse (parser, expanded_text) == 0)
23181151
DJ
544 {
545 /* Parsed successfully. */
fc6e0168
DJ
546 struct tdesc_xml_cache new_cache;
547
548 new_cache.xml_document = expanded_text;
549 new_cache.tdesc = data.tdesc;
550 VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
23181151
DJ
551 discard_cleanups (result_cleanup);
552 do_cleanups (back_to);
553 return data.tdesc;
554 }
555 else
556 {
557 warning (_("Could not load XML target description; ignoring"));
558 do_cleanups (back_to);
559 return NULL;
560 }
561}
23181151
DJ
562#endif /* HAVE_LIBEXPAT */
563\f
564
23181151
DJ
565/* Read an XML target description from FILENAME. Parse it, and return
566 the parsed description. */
567
568const struct target_desc *
569file_read_description_xml (const char *filename)
570{
571 struct target_desc *tdesc;
572 char *tdesc_str;
573 struct cleanup *back_to;
108546a0 574 char *dirname;
23181151 575
a96d9b2e 576 tdesc_str = xml_fetch_content_from_file (filename, NULL);
23181151 577 if (tdesc_str == NULL)
108546a0
DJ
578 {
579 warning (_("Could not open \"%s\""), filename);
580 return NULL;
581 }
23181151
DJ
582
583 back_to = make_cleanup (xfree, tdesc_str);
108546a0 584
e1024ff1
DJ
585 dirname = ldirname (filename);
586 if (dirname != NULL)
587 make_cleanup (xfree, dirname);
108546a0 588
a96d9b2e 589 tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
23181151
DJ
590 do_cleanups (back_to);
591
592 return tdesc;
593}
594
108546a0
DJ
595/* Read a string representation of available features from the target,
596 using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is
597 malloc allocated and NUL-terminated. NAME should be a non-NULL
598 string identifying the XML document we want; the top level document
599 is "target.xml". Other calls may be performed for the DTD or
600 for <xi:include>. */
601
602static char *
603fetch_available_features_from_target (const char *name, void *baton_)
604{
605 struct target_ops *ops = baton_;
606
607 /* Read this object as a string. This ensures that a NUL
608 terminator is added. */
609 return target_read_stralloc (ops,
610 TARGET_OBJECT_AVAILABLE_FEATURES,
611 name);
612}
613\f
614
23181151
DJ
615/* Read an XML target description using OPS. Parse it, and return the
616 parsed description. */
617
618const struct target_desc *
619target_read_description_xml (struct target_ops *ops)
620{
621 struct target_desc *tdesc;
622 char *tdesc_str;
623 struct cleanup *back_to;
624
108546a0 625 tdesc_str = fetch_available_features_from_target ("target.xml", ops);
23181151
DJ
626 if (tdesc_str == NULL)
627 return NULL;
628
629 back_to = make_cleanup (xfree, tdesc_str);
108546a0
DJ
630 tdesc = tdesc_parse_xml (tdesc_str,
631 fetch_available_features_from_target,
632 ops);
23181151
DJ
633 do_cleanups (back_to);
634
635 return tdesc;
636}
This page took 0.529502 seconds and 4 git commands to generate.