* win32-low.c (create_process): New.
[deliverable/binutils-gdb.git] / gdb / xml-tdesc.c
CommitLineData
23181151
DJ
1/* XML target description support for GDB.
2
3 Copyright (C) 2006
4 Free Software Foundation, Inc.
5
6 Contributed by CodeSourcery.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
23181151
DJ
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23181151
DJ
22
23#include "defs.h"
123dc839 24#include "gdbtypes.h"
23181151
DJ
25#include "target.h"
26#include "target-descriptions.h"
27#include "xml-support.h"
28#include "xml-tdesc.h"
29
108546a0
DJ
30#include "filenames.h"
31
23181151
DJ
32#include "gdb_assert.h"
33
34#if !defined(HAVE_LIBEXPAT)
35
36/* Parse DOCUMENT into a target description. Or don't, since we don't have
37 an XML parser. */
38
39static struct target_desc *
108546a0
DJ
40tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
41 void *fetcher_baton)
23181151
DJ
42{
43 static int have_warned;
44
45 if (!have_warned)
46 {
47 have_warned = 1;
48 warning (_("Can not parse XML target description; XML support was "
49 "disabled at compile time"));
50 }
51
52 return NULL;
53}
54
55#else /* HAVE_LIBEXPAT */
56
fc6e0168
DJ
57/* A record of every XML description we have parsed. We never discard
58 old descriptions, because we never discard gdbarches. As long as we
59 have a gdbarch referencing this description, we want to have a copy
60 of it here, so that if we parse the same XML document again we can
61 return the same "struct target_desc *"; if they are not singletons,
62 then we will create unnecessary duplicate gdbarches. See
63 gdbarch_list_lookup_by_info. */
64
65struct tdesc_xml_cache
66{
67 const char *xml_document;
68 struct target_desc *tdesc;
69};
70typedef struct tdesc_xml_cache tdesc_xml_cache_s;
71DEF_VEC_O(tdesc_xml_cache_s);
72
73static VEC(tdesc_xml_cache_s) *xml_cache;
74
23181151
DJ
75/* Callback data for target description parsing. */
76
77struct tdesc_parsing_data
78{
79 /* The target description we are building. */
80 struct target_desc *tdesc;
123dc839
DJ
81
82 /* The target feature we are currently parsing, or last parsed. */
83 struct tdesc_feature *current_feature;
84
85 /* The register number to use for the next register we see, if
86 it does not have its own. This starts at zero. */
87 int next_regnum;
88
89 /* The union we are currently parsing, or last parsed. */
90 struct type *current_union;
23181151
DJ
91};
92
93/* Handle the end of an <architecture> element and its value. */
94
95static void
96tdesc_end_arch (struct gdb_xml_parser *parser,
97 const struct gdb_xml_element *element,
98 void *user_data, const char *body_text)
99{
100 struct tdesc_parsing_data *data = user_data;
101 const struct bfd_arch_info *arch;
102
103 arch = bfd_scan_arch (body_text);
104 if (arch == NULL)
105 gdb_xml_error (parser, _("Target description specified unknown "
106 "architecture \"%s\""), body_text);
107 set_tdesc_architecture (data->tdesc, arch);
108}
109
1780a0ed
DJ
110/* Handle the start of a <target> element. */
111
112static void
113tdesc_start_target (struct gdb_xml_parser *parser,
114 const struct gdb_xml_element *element,
115 void *user_data, VEC(gdb_xml_value_s) *attributes)
116{
117 struct tdesc_parsing_data *data = user_data;
118 char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;
119
120 if (strcmp (version, "1.0") != 0)
121 gdb_xml_error (parser,
122 _("Target description has unsupported version \"%s\""),
123 version);
124}
125
123dc839
DJ
126/* Handle the start of a <feature> element. */
127
128static void
129tdesc_start_feature (struct gdb_xml_parser *parser,
130 const struct gdb_xml_element *element,
131 void *user_data, VEC(gdb_xml_value_s) *attributes)
132{
133 struct tdesc_parsing_data *data = user_data;
134 char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
135
136 data->current_feature = tdesc_create_feature (data->tdesc, name);
137}
138
139/* Handle the start of a <reg> element. Fill in the optional
140 attributes and attach it to the containing feature. */
141
142static void
143tdesc_start_reg (struct gdb_xml_parser *parser,
144 const struct gdb_xml_element *element,
145 void *user_data, VEC(gdb_xml_value_s) *attributes)
146{
147 struct tdesc_parsing_data *data = user_data;
148 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
149 int ix = 0, length;
150 char *name, *group, *type;
151 int bitsize, regnum, save_restore;
152
153 length = VEC_length (gdb_xml_value_s, attributes);
154
155 name = attrs[ix++].value;
156 bitsize = * (ULONGEST *) attrs[ix++].value;
157
158 if (ix < length && strcmp (attrs[ix].name, "regnum") == 0)
159 regnum = * (ULONGEST *) attrs[ix++].value;
160 else
161 regnum = data->next_regnum;
162
163 if (ix < length && strcmp (attrs[ix].name, "type") == 0)
164 type = attrs[ix++].value;
165 else
166 type = "int";
167
168 if (ix < length && strcmp (attrs[ix].name, "group") == 0)
169 group = attrs[ix++].value;
170 else
171 group = NULL;
172
173 if (ix < length && strcmp (attrs[ix].name, "save-restore") == 0)
174 save_restore = * (ULONGEST *) attrs[ix++].value;
175 else
176 save_restore = 1;
177
178 if (strcmp (type, "int") != 0
179 && strcmp (type, "float") != 0
d9cc5895
DJ
180 && strcmp (type, "code_ptr") != 0
181 && strcmp (type, "data_ptr") != 0
123dc839
DJ
182 && tdesc_named_type (data->current_feature, type) == NULL)
183 gdb_xml_error (parser, _("Register \"%s\" has unknown type \"%s\""),
184 name, type);
185
186 tdesc_create_reg (data->current_feature, name, regnum, save_restore, group,
187 bitsize, type);
188
189 data->next_regnum = regnum + 1;
190}
191
192/* Handle the start of a <union> element. Initialize the type and
193 record it with the current feature. */
194
195static void
196tdesc_start_union (struct gdb_xml_parser *parser,
197 const struct gdb_xml_element *element,
198 void *user_data, VEC(gdb_xml_value_s) *attributes)
199{
200 struct tdesc_parsing_data *data = user_data;
201 char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
202 struct type *type;
203
204 type = init_composite_type (NULL, TYPE_CODE_UNION);
205 TYPE_NAME (type) = xstrdup (id);
206 tdesc_record_type (data->current_feature, type);
207 data->current_union = type;
208}
209
210/* Handle the end of a <union> element. */
211
212static void
213tdesc_end_union (struct gdb_xml_parser *parser,
214 const struct gdb_xml_element *element,
215 void *user_data, const char *body_text)
216{
217 struct tdesc_parsing_data *data = user_data;
218 int i;
219
220 /* If any of the children of this union are vectors, flag the union
221 as a vector also. This allows e.g. a union of two vector types
222 to show up automatically in "info vector". */
223 for (i = 0; i < TYPE_NFIELDS (data->current_union); i++)
224 if (TYPE_VECTOR (TYPE_FIELD_TYPE (data->current_union, i)))
225 {
226 TYPE_FLAGS (data->current_union) |= TYPE_FLAG_VECTOR;
227 break;
228 }
229}
230
231/* Handle the start of a <field> element. Attach the field to the
232 current union. */
233
234static void
235tdesc_start_field (struct gdb_xml_parser *parser,
236 const struct gdb_xml_element *element,
237 void *user_data, VEC(gdb_xml_value_s) *attributes)
238{
239 struct tdesc_parsing_data *data = user_data;
240 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
241 struct type *type, *field_type;
242 char *field_name, *field_type_id;
243
244 field_name = attrs[0].value;
245 field_type_id = attrs[1].value;
246
247 field_type = tdesc_named_type (data->current_feature, field_type_id);
248 if (field_type == NULL)
249 gdb_xml_error (parser, _("Union field \"%s\" references undefined "
250 "type \"%s\""),
251 field_name, field_type_id);
252
253 append_composite_type_field (data->current_union, xstrdup (field_name),
254 field_type);
255}
256
257/* Handle the start of a <vector> element. Initialize the type and
258 record it with the current feature. */
259
260static void
261tdesc_start_vector (struct gdb_xml_parser *parser,
262 const struct gdb_xml_element *element,
263 void *user_data, VEC(gdb_xml_value_s) *attributes)
264{
265 struct tdesc_parsing_data *data = user_data;
266 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
267 struct type *type, *field_type, *range_type;
268 char *id, *field_type_id;
269 int count;
270
271 id = attrs[0].value;
272 field_type_id = attrs[1].value;
273 count = * (ULONGEST *) attrs[2].value;
274
275 field_type = tdesc_named_type (data->current_feature, field_type_id);
276 if (field_type == NULL)
277 gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
278 id, field_type_id);
279
280 /* A vector is just an array plus a special flag. */
281 range_type = create_range_type (NULL, builtin_type_int, 0, count - 1);
282 type = create_array_type (NULL, field_type, range_type);
283 TYPE_NAME (type) = xstrdup (id);
284
285 TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
286
287 tdesc_record_type (data->current_feature, type);
288}
289
23181151
DJ
290/* The elements and attributes of an XML target description. */
291
123dc839
DJ
292static const struct gdb_xml_attribute field_attributes[] = {
293 { "name", GDB_XML_AF_NONE, NULL, NULL },
294 { "type", GDB_XML_AF_NONE, NULL, NULL },
295 { NULL, GDB_XML_AF_NONE, NULL, NULL }
296};
297
298static const struct gdb_xml_element union_children[] = {
299 { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
300 tdesc_start_field, NULL },
301 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
302};
303
304static const struct gdb_xml_attribute reg_attributes[] = {
305 { "name", GDB_XML_AF_NONE, NULL, NULL },
306 { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
307 { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
308 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
309 { "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
310 { "save-restore", GDB_XML_AF_OPTIONAL,
311 gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
312 { NULL, GDB_XML_AF_NONE, NULL, NULL }
313};
314
315static const struct gdb_xml_attribute union_attributes[] = {
316 { "id", GDB_XML_AF_NONE, NULL, NULL },
317 { NULL, GDB_XML_AF_NONE, NULL, NULL }
318};
319
320static const struct gdb_xml_attribute vector_attributes[] = {
321 { "id", GDB_XML_AF_NONE, NULL, NULL },
322 { "type", GDB_XML_AF_NONE, NULL, NULL },
323 { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
324 { NULL, GDB_XML_AF_NONE, NULL, NULL }
325};
326
327static const struct gdb_xml_attribute feature_attributes[] = {
328 { "name", GDB_XML_AF_NONE, NULL, NULL },
329 { NULL, GDB_XML_AF_NONE, NULL, NULL }
330};
331
332static const struct gdb_xml_element feature_children[] = {
333 { "reg", reg_attributes, NULL,
334 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
335 tdesc_start_reg, NULL },
336 { "union", union_attributes, union_children,
337 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
338 tdesc_start_union, tdesc_end_union },
339 { "vector", vector_attributes, NULL,
340 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
341 tdesc_start_vector, NULL },
342 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
343};
344
1780a0ed
DJ
345static const struct gdb_xml_attribute target_attributes[] = {
346 { "version", GDB_XML_AF_NONE, NULL, NULL },
347 { NULL, GDB_XML_AF_NONE, NULL, NULL }
348};
349
123dc839 350static const struct gdb_xml_element target_children[] = {
23181151
DJ
351 { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
352 NULL, tdesc_end_arch },
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
429/* Close FILE. */
430
431static void
432do_cleanup_fclose (void *file)
433{
434 fclose (file);
435}
436
437/* Open FILENAME, read all its text into memory, close it, and return
438 the text. If something goes wrong, return NULL and warn. */
439
440static char *
108546a0 441fetch_xml_from_file (const char *filename, void *baton)
23181151 442{
108546a0 443 const char *dirname = baton;
23181151
DJ
444 FILE *file;
445 struct cleanup *back_to;
446 char *text;
447 size_t len, offset;
448
108546a0 449 if (dirname && *dirname)
23181151 450 {
108546a0
DJ
451 char *fullname = concat (dirname, "/", filename, NULL);
452 if (fullname == NULL)
453 nomem (0);
454 file = fopen (fullname, FOPEN_RT);
455 xfree (fullname);
23181151 456 }
108546a0
DJ
457 else
458 file = fopen (filename, FOPEN_RT);
459
460 if (file == NULL)
461 return NULL;
462
23181151
DJ
463 back_to = make_cleanup (do_cleanup_fclose, file);
464
465 /* Read in the whole file, one chunk at a time. */
466 len = 4096;
467 offset = 0;
468 text = xmalloc (len);
469 make_cleanup (free_current_contents, &text);
470 while (1)
471 {
472 size_t bytes_read;
473
474 /* Continue reading where the last read left off. Leave at least
475 one byte so that we can NUL-terminate the result. */
476 bytes_read = fread (text + offset, 1, len - offset - 1, file);
477 if (ferror (file))
478 {
479 warning (_("Read error from \"%s\""), filename);
480 do_cleanups (back_to);
481 return NULL;
482 }
483
484 offset += bytes_read;
485
486 if (feof (file))
487 break;
488
489 len = len * 2;
490 text = xrealloc (text, len);
491 }
492
493 fclose (file);
494 discard_cleanups (back_to);
495
496 text[offset] = '\0';
497 return text;
498}
499
500/* Read an XML target description from FILENAME. Parse it, and return
501 the parsed description. */
502
503const struct target_desc *
504file_read_description_xml (const char *filename)
505{
506 struct target_desc *tdesc;
507 char *tdesc_str;
508 struct cleanup *back_to;
108546a0 509 char *dirname;
23181151 510
108546a0 511 tdesc_str = fetch_xml_from_file (filename, NULL);
23181151 512 if (tdesc_str == NULL)
108546a0
DJ
513 {
514 warning (_("Could not open \"%s\""), filename);
515 return NULL;
516 }
23181151
DJ
517
518 back_to = make_cleanup (xfree, tdesc_str);
108546a0 519
e1024ff1
DJ
520 dirname = ldirname (filename);
521 if (dirname != NULL)
522 make_cleanup (xfree, dirname);
108546a0
DJ
523
524 tdesc = tdesc_parse_xml (tdesc_str, fetch_xml_from_file, dirname);
23181151
DJ
525 do_cleanups (back_to);
526
527 return tdesc;
528}
529
108546a0
DJ
530/* Read a string representation of available features from the target,
531 using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is
532 malloc allocated and NUL-terminated. NAME should be a non-NULL
533 string identifying the XML document we want; the top level document
534 is "target.xml". Other calls may be performed for the DTD or
535 for <xi:include>. */
536
537static char *
538fetch_available_features_from_target (const char *name, void *baton_)
539{
540 struct target_ops *ops = baton_;
541
542 /* Read this object as a string. This ensures that a NUL
543 terminator is added. */
544 return target_read_stralloc (ops,
545 TARGET_OBJECT_AVAILABLE_FEATURES,
546 name);
547}
548\f
549
23181151
DJ
550/* Read an XML target description using OPS. Parse it, and return the
551 parsed description. */
552
553const struct target_desc *
554target_read_description_xml (struct target_ops *ops)
555{
556 struct target_desc *tdesc;
557 char *tdesc_str;
558 struct cleanup *back_to;
559
108546a0 560 tdesc_str = fetch_available_features_from_target ("target.xml", ops);
23181151
DJ
561 if (tdesc_str == NULL)
562 return NULL;
563
564 back_to = make_cleanup (xfree, tdesc_str);
108546a0
DJ
565 tdesc = tdesc_parse_xml (tdesc_str,
566 fetch_available_features_from_target,
567 ops);
23181151
DJ
568 do_cleanups (back_to);
569
570 return tdesc;
571}
This page took 0.147577 seconds and 4 git commands to generate.