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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [xml-tdesc.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 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 union we are currently parsing, or last parsed.  */
89
  struct tdesc_type *current_union;
90
};
91
 
92
/* Handle the end of an <architecture> element and its value.  */
93
 
94
static void
95
tdesc_end_arch (struct gdb_xml_parser *parser,
96
                const struct gdb_xml_element *element,
97
                void *user_data, const char *body_text)
98
{
99
  struct tdesc_parsing_data *data = user_data;
100
  const struct bfd_arch_info *arch;
101
 
102
  arch = bfd_scan_arch (body_text);
103
  if (arch == NULL)
104
    gdb_xml_error (parser, _("Target description specified unknown "
105
                             "architecture \"%s\""), body_text);
106
  set_tdesc_architecture (data->tdesc, arch);
107
}
108
 
109
/* Handle the end of an <osabi> element and its value.  */
110
 
111
static void
112
tdesc_end_osabi (struct gdb_xml_parser *parser,
113
                 const struct gdb_xml_element *element,
114
                 void *user_data, const char *body_text)
115
{
116
  struct tdesc_parsing_data *data = user_data;
117
  enum gdb_osabi osabi;
118
 
119
  osabi = osabi_from_tdesc_string (body_text);
120
  if (osabi == GDB_OSABI_UNKNOWN)
121
    warning (_("Target description specified unknown osabi \"%s\""),
122
             body_text);
123
  else
124
    set_tdesc_osabi (data->tdesc, osabi);
125
}
126
 
127
/* Handle the end of a <compatible> element and its value.  */
128
 
129
static void
130
tdesc_end_compatible (struct gdb_xml_parser *parser,
131
                      const struct gdb_xml_element *element,
132
                      void *user_data, const char *body_text)
133
{
134
  struct tdesc_parsing_data *data = user_data;
135
  const struct bfd_arch_info *arch;
136
 
137
  arch = bfd_scan_arch (body_text);
138
  tdesc_add_compatible (data->tdesc, arch);
139
}
140
 
141
/* Handle the start of a <target> element.  */
142
 
143
static void
144
tdesc_start_target (struct gdb_xml_parser *parser,
145
                    const struct gdb_xml_element *element,
146
                    void *user_data, VEC(gdb_xml_value_s) *attributes)
147
{
148
  struct tdesc_parsing_data *data = user_data;
149
  char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;
150
 
151
  if (strcmp (version, "1.0") != 0)
152
    gdb_xml_error (parser,
153
                   _("Target description has unsupported version \"%s\""),
154
                   version);
155
}
156
 
157
/* Handle the start of a <feature> element.  */
158
 
159
static void
160
tdesc_start_feature (struct gdb_xml_parser *parser,
161
                     const struct gdb_xml_element *element,
162
                     void *user_data, VEC(gdb_xml_value_s) *attributes)
163
{
164
  struct tdesc_parsing_data *data = user_data;
165
  char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
166
 
167
  data->current_feature = tdesc_create_feature (data->tdesc, name);
168
}
169
 
170
/* Handle the start of a <reg> element.  Fill in the optional
171
   attributes and attach it to the containing feature.  */
172
 
173
static void
174
tdesc_start_reg (struct gdb_xml_parser *parser,
175
                 const struct gdb_xml_element *element,
176
                 void *user_data, VEC(gdb_xml_value_s) *attributes)
177
{
178
  struct tdesc_parsing_data *data = user_data;
179
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
180
  int ix = 0, length;
181
  char *name, *group, *type;
182
  int bitsize, regnum, save_restore;
183
 
184
  length = VEC_length (gdb_xml_value_s, attributes);
185
 
186
  name = attrs[ix++].value;
187
  bitsize = * (ULONGEST *) attrs[ix++].value;
188
 
189
  if (ix < length && strcmp (attrs[ix].name, "regnum") == 0)
190
    regnum = * (ULONGEST *) attrs[ix++].value;
191
  else
192
    regnum = data->next_regnum;
193
 
194
  if (ix < length && strcmp (attrs[ix].name, "type") == 0)
195
    type = attrs[ix++].value;
196
  else
197
    type = "int";
198
 
199
  if (ix < length && strcmp (attrs[ix].name, "group") == 0)
200
    group = attrs[ix++].value;
201
  else
202
    group = NULL;
203
 
204
  if (ix < length && strcmp (attrs[ix].name, "save-restore") == 0)
205
    save_restore = * (ULONGEST *) attrs[ix++].value;
206
  else
207
    save_restore = 1;
208
 
209
  if (strcmp (type, "int") != 0
210
      && strcmp (type, "float") != 0
211
      && tdesc_named_type (data->current_feature, type) == NULL)
212
    gdb_xml_error (parser, _("Register \"%s\" has unknown type \"%s\""),
213
                   name, type);
214
 
215
  tdesc_create_reg (data->current_feature, name, regnum, save_restore, group,
216
                    bitsize, type);
217
 
218
  data->next_regnum = regnum + 1;
219
}
220
 
221
/* Handle the start of a <union> element.  Initialize the type and
222
   record it with the current feature.  */
223
 
224
static void
225
tdesc_start_union (struct gdb_xml_parser *parser,
226
                   const struct gdb_xml_element *element,
227
                   void *user_data, VEC(gdb_xml_value_s) *attributes)
228
{
229
  struct tdesc_parsing_data *data = user_data;
230
  char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
231
 
232
  data->current_union = tdesc_create_union (data->current_feature, id);
233
}
234
 
235
/* Handle the start of a <field> element.  Attach the field to the
236
   current union.  */
237
 
238
static void
239
tdesc_start_field (struct gdb_xml_parser *parser,
240
                   const struct gdb_xml_element *element,
241
                   void *user_data, VEC(gdb_xml_value_s) *attributes)
242
{
243
  struct tdesc_parsing_data *data = user_data;
244
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
245
  struct tdesc_type *field_type;
246
  char *field_name, *field_type_id;
247
 
248
  field_name = attrs[0].value;
249
  field_type_id = attrs[1].value;
250
 
251
  field_type = tdesc_named_type (data->current_feature, field_type_id);
252
  if (field_type == NULL)
253
    gdb_xml_error (parser, _("Union field \"%s\" references undefined "
254
                             "type \"%s\""),
255
                   field_name, field_type_id);
256
 
257
  tdesc_add_field (data->current_union, field_name, field_type);
258
}
259
 
260
/* Handle the start of a <vector> element.  Initialize the type and
261
   record it with the current feature.  */
262
 
263
static void
264
tdesc_start_vector (struct gdb_xml_parser *parser,
265
                    const struct gdb_xml_element *element,
266
                    void *user_data, VEC(gdb_xml_value_s) *attributes)
267
{
268
  struct tdesc_parsing_data *data = user_data;
269
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
270
  struct tdesc_type *field_type;
271
  char *id, *field_type_id;
272
  int count;
273
 
274
  id = attrs[0].value;
275
  field_type_id = attrs[1].value;
276
  count = * (ULONGEST *) attrs[2].value;
277
 
278
  field_type = tdesc_named_type (data->current_feature, field_type_id);
279
  if (field_type == NULL)
280
    gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
281
                   id, field_type_id);
282
 
283
  tdesc_create_vector (data->current_feature, id, field_type, count);
284
}
285
 
286
/* The elements and attributes of an XML target description.  */
287
 
288
static const struct gdb_xml_attribute field_attributes[] = {
289
  { "name", GDB_XML_AF_NONE, NULL, NULL },
290
  { "type", GDB_XML_AF_NONE, NULL, NULL },
291
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
292
};
293
 
294
static const struct gdb_xml_element union_children[] = {
295
  { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
296
    tdesc_start_field, NULL },
297
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
298
};
299
 
300
static const struct gdb_xml_attribute reg_attributes[] = {
301
  { "name", GDB_XML_AF_NONE, NULL, NULL },
302
  { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
303
  { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
304
  { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
305
  { "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
306
  { "save-restore", GDB_XML_AF_OPTIONAL,
307
    gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
308
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
309
};
310
 
311
static const struct gdb_xml_attribute union_attributes[] = {
312
  { "id", GDB_XML_AF_NONE, NULL, NULL },
313
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
314
};
315
 
316
static const struct gdb_xml_attribute vector_attributes[] = {
317
  { "id", GDB_XML_AF_NONE, NULL, NULL },
318
  { "type", GDB_XML_AF_NONE, NULL, NULL },
319
  { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
320
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
321
};
322
 
323
static const struct gdb_xml_attribute feature_attributes[] = {
324
  { "name", GDB_XML_AF_NONE, NULL, NULL },
325
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
326
};
327
 
328
static const struct gdb_xml_element feature_children[] = {
329
  { "reg", reg_attributes, NULL,
330
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
331
    tdesc_start_reg, NULL },
332
  { "union", union_attributes, union_children,
333
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
334
    tdesc_start_union, NULL },
335
  { "vector", vector_attributes, NULL,
336
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
337
    tdesc_start_vector, NULL },
338
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
339
};
340
 
341
static const struct gdb_xml_attribute target_attributes[] = {
342
  { "version", GDB_XML_AF_NONE, NULL, NULL },
343
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
344
};
345
 
346
static const struct gdb_xml_element target_children[] = {
347
  { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
348
    NULL, tdesc_end_arch },
349
  { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
350
    NULL, tdesc_end_osabi },
351
  { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
352
    NULL, tdesc_end_compatible },
353
  { "feature", feature_attributes, feature_children,
354
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
355
    tdesc_start_feature, NULL },
356
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
357
};
358
 
359
static const struct gdb_xml_element tdesc_elements[] = {
360
  { "target", target_attributes, target_children, GDB_XML_EF_NONE,
361
    tdesc_start_target, NULL },
362
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
363
};
364
 
365
/* Parse DOCUMENT into a target description and return it.  */
366
 
367
static struct target_desc *
368
tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
369
                 void *fetcher_baton)
370
{
371
  struct cleanup *back_to, *result_cleanup;
372
  struct gdb_xml_parser *parser;
373
  struct tdesc_parsing_data data;
374
  struct tdesc_xml_cache *cache;
375
  char *expanded_text;
376
  int ix;
377
 
378
  /* Expand all XInclude directives.  */
379
  expanded_text = xml_process_xincludes (_("target description"),
380
                                         document, fetcher, fetcher_baton, 0);
381
  if (expanded_text == NULL)
382
    {
383
      warning (_("Could not load XML target description; ignoring"));
384
      return NULL;
385
    }
386
 
387
  /* Check for an exact match in the list of descriptions we have
388
     previously parsed.  strcmp is a slightly inefficient way to
389
     do this; an SHA-1 checksum would work as well.  */
390
  for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
391
    if (strcmp (cache->xml_document, expanded_text) == 0)
392
      {
393
       xfree (expanded_text);
394
       return cache->tdesc;
395
      }
396
 
397
  back_to = make_cleanup (null_cleanup, NULL);
398
  parser = gdb_xml_create_parser_and_cleanup (_("target description"),
399
                                              tdesc_elements, &data);
400
  gdb_xml_use_dtd (parser, "gdb-target.dtd");
401
 
402
  memset (&data, 0, sizeof (struct tdesc_parsing_data));
403
  data.tdesc = allocate_target_description ();
404
  result_cleanup = make_cleanup_free_target_description (data.tdesc);
405
  make_cleanup (xfree, expanded_text);
406
 
407
  if (gdb_xml_parse (parser, expanded_text) == 0)
408
    {
409
      /* Parsed successfully.  */
410
      struct tdesc_xml_cache new_cache;
411
 
412
      new_cache.xml_document = expanded_text;
413
      new_cache.tdesc = data.tdesc;
414
      VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
415
      discard_cleanups (result_cleanup);
416
      do_cleanups (back_to);
417
      return data.tdesc;
418
    }
419
  else
420
    {
421
      warning (_("Could not load XML target description; ignoring"));
422
      do_cleanups (back_to);
423
      return NULL;
424
    }
425
}
426
#endif /* HAVE_LIBEXPAT */
427
 
428
 
429
/* Read an XML target description from FILENAME.  Parse it, and return
430
   the parsed description.  */
431
 
432
const struct target_desc *
433
file_read_description_xml (const char *filename)
434
{
435
  struct target_desc *tdesc;
436
  char *tdesc_str;
437
  struct cleanup *back_to;
438
  char *dirname;
439
 
440
  tdesc_str = xml_fetch_content_from_file (filename, NULL);
441
  if (tdesc_str == NULL)
442
    {
443
      warning (_("Could not open \"%s\""), filename);
444
      return NULL;
445
    }
446
 
447
  back_to = make_cleanup (xfree, tdesc_str);
448
 
449
  dirname = ldirname (filename);
450
  if (dirname != NULL)
451
    make_cleanup (xfree, dirname);
452
 
453
  tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
454
  do_cleanups (back_to);
455
 
456
  return tdesc;
457
}
458
 
459
/* Read a string representation of available features from the target,
460
   using TARGET_OBJECT_AVAILABLE_FEATURES.  The returned string is
461
   malloc allocated and NUL-terminated.  NAME should be a non-NULL
462
   string identifying the XML document we want; the top level document
463
   is "target.xml".  Other calls may be performed for the DTD or
464
   for <xi:include>.  */
465
 
466
static char *
467
fetch_available_features_from_target (const char *name, void *baton_)
468
{
469
  struct target_ops *ops = baton_;
470
 
471
  /* Read this object as a string.  This ensures that a NUL
472
     terminator is added.  */
473
  return target_read_stralloc (ops,
474
                               TARGET_OBJECT_AVAILABLE_FEATURES,
475
                               name);
476
}
477
 
478
 
479
/* Read an XML target description using OPS.  Parse it, and return the
480
   parsed description.  */
481
 
482
const struct target_desc *
483
target_read_description_xml (struct target_ops *ops)
484
{
485
  struct target_desc *tdesc;
486
  char *tdesc_str;
487
  struct cleanup *back_to;
488
 
489
  tdesc_str = fetch_available_features_from_target ("target.xml", ops);
490
  if (tdesc_str == NULL)
491
    return NULL;
492
 
493
  back_to = make_cleanup (xfree, tdesc_str);
494
  tdesc = tdesc_parse_xml (tdesc_str,
495
                           fetch_available_features_from_target,
496
                           ops);
497
  do_cleanups (back_to);
498
 
499
  return tdesc;
500
}

powered by: WebSVN 2.1.0

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