Fix build failure in inf-ptrace.c.
[deliverable/binutils-gdb.git] / gdb / xml-tdesc.c
CommitLineData
23181151
DJ
1/* XML target description support for GDB.
2
0fb0cc75 3 Copyright (C) 2006, 2008, 2009 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
88 /* The union we are currently parsing, or last parsed. */
ad068eab 89 struct tdesc_type *current_union;
23181151
DJ
90};
91
92/* Handle the end of an <architecture> element and its value. */
93
94static void
95tdesc_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
08d16641
PA
109/* Handle the end of an <osabi> element and its value. */
110
111static void
112tdesc_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
e35359c5
UW
127/* Handle the end of a <compatible> element and its value. */
128
129static void
130tdesc_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
1780a0ed
DJ
141/* Handle the start of a <target> element. */
142
143static void
144tdesc_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
123dc839
DJ
157/* Handle the start of a <feature> element. */
158
159static void
160tdesc_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
173static void
174tdesc_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
224static void
225tdesc_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;
123dc839 231
ad068eab 232 data->current_union = tdesc_create_union (data->current_feature, id);
123dc839
DJ
233}
234
235/* Handle the start of a <field> element. Attach the field to the
236 current union. */
237
238static void
239tdesc_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);
ad068eab 245 struct tdesc_type *field_type;
123dc839
DJ
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
ad068eab 257 tdesc_add_field (data->current_union, field_name, field_type);
123dc839
DJ
258}
259
260/* Handle the start of a <vector> element. Initialize the type and
261 record it with the current feature. */
262
263static void
264tdesc_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);
ad068eab 270 struct tdesc_type *field_type;
123dc839
DJ
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
ad068eab 283 tdesc_create_vector (data->current_feature, id, field_type, count);
123dc839
DJ
284}
285
23181151
DJ
286/* The elements and attributes of an XML target description. */
287
123dc839
DJ
288static 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
294static 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
300static 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
311static 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
316static 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
323static 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
328static 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,
ad068eab 334 tdesc_start_union, NULL },
123dc839
DJ
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
1780a0ed
DJ
341static 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
123dc839 346static const struct gdb_xml_element target_children[] = {
23181151
DJ
347 { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
348 NULL, tdesc_end_arch },
08d16641
PA
349 { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL,
350 NULL, tdesc_end_osabi },
e35359c5
UW
351 { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
352 NULL, tdesc_end_compatible },
123dc839
DJ
353 { "feature", feature_attributes, feature_children,
354 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
355 tdesc_start_feature, NULL },
23181151
DJ
356 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
357};
358
123dc839 359static const struct gdb_xml_element tdesc_elements[] = {
1780a0ed
DJ
360 { "target", target_attributes, target_children, GDB_XML_EF_NONE,
361 tdesc_start_target, NULL },
23181151
DJ
362 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
363};
364
365/* Parse DOCUMENT into a target description and return it. */
366
367static struct target_desc *
108546a0
DJ
368tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
369 void *fetcher_baton)
23181151
DJ
370{
371 struct cleanup *back_to, *result_cleanup;
372 struct gdb_xml_parser *parser;
373 struct tdesc_parsing_data data;
fc6e0168 374 struct tdesc_xml_cache *cache;
108546a0 375 char *expanded_text;
fc6e0168 376 int ix;
23181151 377
108546a0
DJ
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 }
23181151 386
fc6e0168
DJ
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);
23181151
DJ
398 parser = gdb_xml_create_parser_and_cleanup (_("target description"),
399 tdesc_elements, &data);
108546a0 400 gdb_xml_use_dtd (parser, "gdb-target.dtd");
23181151 401
108546a0 402 memset (&data, 0, sizeof (struct tdesc_parsing_data));
23181151
DJ
403 data.tdesc = allocate_target_description ();
404 result_cleanup = make_cleanup_free_target_description (data.tdesc);
fc6e0168 405 make_cleanup (xfree, expanded_text);
23181151 406
108546a0 407 if (gdb_xml_parse (parser, expanded_text) == 0)
23181151
DJ
408 {
409 /* Parsed successfully. */
fc6e0168
DJ
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);
23181151
DJ
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}
23181151
DJ
426#endif /* HAVE_LIBEXPAT */
427\f
428
23181151
DJ
429/* Read an XML target description from FILENAME. Parse it, and return
430 the parsed description. */
431
432const struct target_desc *
433file_read_description_xml (const char *filename)
434{
435 struct target_desc *tdesc;
436 char *tdesc_str;
437 struct cleanup *back_to;
108546a0 438 char *dirname;
23181151 439
a96d9b2e 440 tdesc_str = xml_fetch_content_from_file (filename, NULL);
23181151 441 if (tdesc_str == NULL)
108546a0
DJ
442 {
443 warning (_("Could not open \"%s\""), filename);
444 return NULL;
445 }
23181151
DJ
446
447 back_to = make_cleanup (xfree, tdesc_str);
108546a0 448
e1024ff1
DJ
449 dirname = ldirname (filename);
450 if (dirname != NULL)
451 make_cleanup (xfree, dirname);
108546a0 452
a96d9b2e 453 tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname);
23181151
DJ
454 do_cleanups (back_to);
455
456 return tdesc;
457}
458
108546a0
DJ
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
466static char *
467fetch_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\f
478
23181151
DJ
479/* Read an XML target description using OPS. Parse it, and return the
480 parsed description. */
481
482const struct target_desc *
483target_read_description_xml (struct target_ops *ops)
484{
485 struct target_desc *tdesc;
486 char *tdesc_str;
487 struct cleanup *back_to;
488
108546a0 489 tdesc_str = fetch_available_features_from_target ("target.xml", ops);
23181151
DJ
490 if (tdesc_str == NULL)
491 return NULL;
492
493 back_to = make_cleanup (xfree, tdesc_str);
108546a0
DJ
494 tdesc = tdesc_parse_xml (tdesc_str,
495 fetch_available_features_from_target,
496 ops);
23181151
DJ
497 do_cleanups (back_to);
498
499 return tdesc;
500}
This page took 0.354627 seconds and 4 git commands to generate.