OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [xml-tdesc.c] - Blame information for rev 865

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* XML target description support for GDB.
2
 
3
   Copyright (C) 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
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
11
   the Free Software Foundation; either version 3 of the License, or
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
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
#include "defs.h"
23
#include "target.h"
24
#include "target-descriptions.h"
25
#include "xml-support.h"
26
#include "xml-tdesc.h"
27
#include "osabi.h"
28
 
29
#include "filenames.h"
30
 
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
 
38
static struct target_desc *
39
tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
40
                 void *fetcher_baton)
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
 
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
 
64
struct tdesc_xml_cache
65
{
66
  const char *xml_document;
67
  struct target_desc *tdesc;
68
};
69
typedef struct tdesc_xml_cache tdesc_xml_cache_s;
70
DEF_VEC_O(tdesc_xml_cache_s);
71
 
72
static VEC(tdesc_xml_cache_s) *xml_cache;
73
 
74
/* Callback data for target description parsing.  */
75
 
76
struct tdesc_parsing_data
77
{
78
  /* The target description we are building.  */
79
  struct target_desc *tdesc;
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
 
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;
97
};
98
 
99
/* Handle the end of an <architecture> element and its value.  */
100
 
101
static void
102
tdesc_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
 
116
/* Handle the end of an <osabi> element and its value.  */
117
 
118
static void
119
tdesc_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
 
134
/* Handle the end of a <compatible> element and its value.  */
135
 
136
static void
137
tdesc_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
 
148
/* Handle the start of a <target> element.  */
149
 
150
static void
151
tdesc_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
{
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
 
163
/* Handle the start of a <feature> element.  */
164
 
165
static void
166
tdesc_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
 
179
static void
180
tdesc_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
 
230
static void
231
tdesc_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;
237
 
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
 
246
static void
247
tdesc_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
 
265
      tdesc_set_struct_size (type, size);
266
      data->current_type_size = size;
267
    }
268
}
269
 
270
static void
271
tdesc_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;
286
}
287
 
288
/* Handle the start of a <field> element.  Attach the field to the
289
   current struct or union.  */
290
 
291
static void
292
tdesc_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;
297
  int ix = 0, length;
298
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
299
  struct tdesc_type *field_type;
300
  char *field_name, *field_type_id;
301
  int start, end;
302
 
303
  length = VEC_length (gdb_xml_value_s, attributes);
304
 
305
  field_name = attrs[ix++].value;
306
 
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);
375
}
376
 
377
/* Handle the start of a <vector> element.  Initialize the type and
378
   record it with the current feature.  */
379
 
380
static void
381
tdesc_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);
387
  struct tdesc_type *field_type;
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
 
400
  tdesc_create_vector (data->current_feature, id, field_type, count);
401
}
402
 
403
/* The elements and attributes of an XML target description.  */
404
 
405
static const struct gdb_xml_attribute field_attributes[] = {
406
  { "name", GDB_XML_AF_NONE, NULL, NULL },
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 },
410
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
411
};
412
 
413
static const struct gdb_xml_element struct_union_children[] = {
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
 
419
static 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
 
430
static const struct gdb_xml_attribute struct_union_attributes[] = {
431
  { "id", GDB_XML_AF_NONE, NULL, NULL },
432
  { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL},
433
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
434
};
435
 
436
static 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},
439
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
440
};
441
 
442
static 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
 
449
static 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
 
454
static 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 },
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,
462
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
463
    tdesc_start_union, NULL },
464
  { "flags", flags_attributes, struct_union_children,
465
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
466
    tdesc_start_flags, NULL },
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
 
473
static 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
 
478
static const struct gdb_xml_element target_children[] = {
479
  { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
480
    NULL, tdesc_end_arch },
481
  { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
482
    NULL, tdesc_end_osabi },
483
  { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
484
    NULL, tdesc_end_compatible },
485
  { "feature", feature_attributes, feature_children,
486
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
487
    tdesc_start_feature, NULL },
488
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
489
};
490
 
491
static const struct gdb_xml_element tdesc_elements[] = {
492
  { "target", target_attributes, target_children, GDB_XML_EF_NONE,
493
    tdesc_start_target, NULL },
494
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
495
};
496
 
497
/* Parse DOCUMENT into a target description and return it.  */
498
 
499
static struct target_desc *
500
tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
501
                 void *fetcher_baton)
502
{
503
  struct cleanup *back_to, *result_cleanup;
504
  struct gdb_xml_parser *parser;
505
  struct tdesc_parsing_data data;
506
  struct tdesc_xml_cache *cache;
507
  char *expanded_text;
508
  int ix;
509
 
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
    }
518
 
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);
530
  parser = gdb_xml_create_parser_and_cleanup (_("target description"),
531
                                              tdesc_elements, &data);
532
  gdb_xml_use_dtd (parser, "gdb-target.dtd");
533
 
534
  memset (&data, 0, sizeof (struct tdesc_parsing_data));
535
  data.tdesc = allocate_target_description ();
536
  result_cleanup = make_cleanup_free_target_description (data.tdesc);
537
  make_cleanup (xfree, expanded_text);
538
 
539
  if (gdb_xml_parse (parser, expanded_text) == 0)
540
    {
541
      /* Parsed successfully.  */
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);
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
}
558
#endif /* HAVE_LIBEXPAT */
559
 
560
 
561
/* Read an XML target description from FILENAME.  Parse it, and return
562
   the parsed description.  */
563
 
564
const struct target_desc *
565
file_read_description_xml (const char *filename)
566
{
567
  struct target_desc *tdesc;
568
  char *tdesc_str;
569
  struct cleanup *back_to;
570
  char *dirname;
571
 
572
  tdesc_str = xml_fetch_content_from_file (filename, NULL);
573
  if (tdesc_str == NULL)
574
    {
575
      warning (_("Could not open \"%s\""), filename);
576
      return NULL;
577
    }
578
 
579
  back_to = make_cleanup (xfree, tdesc_str);
580
 
581
  dirname = ldirname (filename);
582
  if (dirname != NULL)
583
    make_cleanup (xfree, dirname);
584
 
585
  tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
586
  do_cleanups (back_to);
587
 
588
  return tdesc;
589
}
590
 
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
 
598
static char *
599
fetch_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
 
610
 
611
/* Read an XML target description using OPS.  Parse it, and return the
612
   parsed description.  */
613
 
614
const struct target_desc *
615
target_read_description_xml (struct target_ops *ops)
616
{
617
  struct target_desc *tdesc;
618
  char *tdesc_str;
619
  struct cleanup *back_to;
620
 
621
  tdesc_str = fetch_available_features_from_target ("target.xml", ops);
622
  if (tdesc_str == NULL)
623
    return NULL;
624
 
625
  back_to = make_cleanup (xfree, tdesc_str);
626
  tdesc = tdesc_parse_xml (tdesc_str,
627
                           fetch_available_features_from_target,
628
                           ops);
629
  do_cleanups (back_to);
630
 
631
  return tdesc;
632
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.