fix gdbtui build errors when pipe() is not available (e.g. mingw targets)
[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"
27
108546a0
DJ
28#include "filenames.h"
29
23181151
DJ
30#include "gdb_assert.h"
31
32#if !defined(HAVE_LIBEXPAT)
33
34/* Parse DOCUMENT into a target description. Or don't, since we don't have
35 an XML parser. */
36
37static struct target_desc *
108546a0
DJ
38tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
39 void *fetcher_baton)
23181151
DJ
40{
41 static int have_warned;
42
43 if (!have_warned)
44 {
45 have_warned = 1;
46 warning (_("Can not parse XML target description; XML support was "
47 "disabled at compile time"));
48 }
49
50 return NULL;
51}
52
53#else /* HAVE_LIBEXPAT */
54
fc6e0168
DJ
55/* A record of every XML description we have parsed. We never discard
56 old descriptions, because we never discard gdbarches. As long as we
57 have a gdbarch referencing this description, we want to have a copy
58 of it here, so that if we parse the same XML document again we can
59 return the same "struct target_desc *"; if they are not singletons,
60 then we will create unnecessary duplicate gdbarches. See
61 gdbarch_list_lookup_by_info. */
62
63struct tdesc_xml_cache
64{
65 const char *xml_document;
66 struct target_desc *tdesc;
67};
68typedef struct tdesc_xml_cache tdesc_xml_cache_s;
69DEF_VEC_O(tdesc_xml_cache_s);
70
71static VEC(tdesc_xml_cache_s) *xml_cache;
72
23181151
DJ
73/* Callback data for target description parsing. */
74
75struct tdesc_parsing_data
76{
77 /* The target description we are building. */
78 struct target_desc *tdesc;
123dc839
DJ
79
80 /* The target feature we are currently parsing, or last parsed. */
81 struct tdesc_feature *current_feature;
82
83 /* The register number to use for the next register we see, if
84 it does not have its own. This starts at zero. */
85 int next_regnum;
86
87 /* The union we are currently parsing, or last parsed. */
ad068eab 88 struct tdesc_type *current_union;
23181151
DJ
89};
90
91/* Handle the end of an <architecture> element and its value. */
92
93static void
94tdesc_end_arch (struct gdb_xml_parser *parser,
95 const struct gdb_xml_element *element,
96 void *user_data, const char *body_text)
97{
98 struct tdesc_parsing_data *data = user_data;
99 const struct bfd_arch_info *arch;
100
101 arch = bfd_scan_arch (body_text);
102 if (arch == NULL)
103 gdb_xml_error (parser, _("Target description specified unknown "
104 "architecture \"%s\""), body_text);
105 set_tdesc_architecture (data->tdesc, arch);
106}
107
1780a0ed
DJ
108/* Handle the start of a <target> element. */
109
110static void
111tdesc_start_target (struct gdb_xml_parser *parser,
112 const struct gdb_xml_element *element,
113 void *user_data, VEC(gdb_xml_value_s) *attributes)
114{
115 struct tdesc_parsing_data *data = user_data;
116 char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;
117
118 if (strcmp (version, "1.0") != 0)
119 gdb_xml_error (parser,
120 _("Target description has unsupported version \"%s\""),
121 version);
122}
123
123dc839
DJ
124/* Handle the start of a <feature> element. */
125
126static void
127tdesc_start_feature (struct gdb_xml_parser *parser,
128 const struct gdb_xml_element *element,
129 void *user_data, VEC(gdb_xml_value_s) *attributes)
130{
131 struct tdesc_parsing_data *data = user_data;
132 char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
133
134 data->current_feature = tdesc_create_feature (data->tdesc, name);
135}
136
137/* Handle the start of a <reg> element. Fill in the optional
138 attributes and attach it to the containing feature. */
139
140static void
141tdesc_start_reg (struct gdb_xml_parser *parser,
142 const struct gdb_xml_element *element,
143 void *user_data, VEC(gdb_xml_value_s) *attributes)
144{
145 struct tdesc_parsing_data *data = user_data;
146 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
147 int ix = 0, length;
148 char *name, *group, *type;
149 int bitsize, regnum, save_restore;
150
151 length = VEC_length (gdb_xml_value_s, attributes);
152
153 name = attrs[ix++].value;
154 bitsize = * (ULONGEST *) attrs[ix++].value;
155
156 if (ix < length && strcmp (attrs[ix].name, "regnum") == 0)
157 regnum = * (ULONGEST *) attrs[ix++].value;
158 else
159 regnum = data->next_regnum;
160
161 if (ix < length && strcmp (attrs[ix].name, "type") == 0)
162 type = attrs[ix++].value;
163 else
164 type = "int";
165
166 if (ix < length && strcmp (attrs[ix].name, "group") == 0)
167 group = attrs[ix++].value;
168 else
169 group = NULL;
170
171 if (ix < length && strcmp (attrs[ix].name, "save-restore") == 0)
172 save_restore = * (ULONGEST *) attrs[ix++].value;
173 else
174 save_restore = 1;
175
176 if (strcmp (type, "int") != 0
177 && strcmp (type, "float") != 0
178 && tdesc_named_type (data->current_feature, type) == NULL)
179 gdb_xml_error (parser, _("Register \"%s\" has unknown type \"%s\""),
180 name, type);
181
182 tdesc_create_reg (data->current_feature, name, regnum, save_restore, group,
183 bitsize, type);
184
185 data->next_regnum = regnum + 1;
186}
187
188/* Handle the start of a <union> element. Initialize the type and
189 record it with the current feature. */
190
191static void
192tdesc_start_union (struct gdb_xml_parser *parser,
193 const struct gdb_xml_element *element,
194 void *user_data, VEC(gdb_xml_value_s) *attributes)
195{
196 struct tdesc_parsing_data *data = user_data;
197 char *id = VEC_index (gdb_xml_value_s, attributes, 0)->value;
123dc839 198
ad068eab 199 data->current_union = tdesc_create_union (data->current_feature, id);
123dc839
DJ
200}
201
202/* Handle the start of a <field> element. Attach the field to the
203 current union. */
204
205static void
206tdesc_start_field (struct gdb_xml_parser *parser,
207 const struct gdb_xml_element *element,
208 void *user_data, VEC(gdb_xml_value_s) *attributes)
209{
210 struct tdesc_parsing_data *data = user_data;
211 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
ad068eab 212 struct tdesc_type *field_type;
123dc839
DJ
213 char *field_name, *field_type_id;
214
215 field_name = attrs[0].value;
216 field_type_id = attrs[1].value;
217
218 field_type = tdesc_named_type (data->current_feature, field_type_id);
219 if (field_type == NULL)
220 gdb_xml_error (parser, _("Union field \"%s\" references undefined "
221 "type \"%s\""),
222 field_name, field_type_id);
223
ad068eab 224 tdesc_add_field (data->current_union, field_name, field_type);
123dc839
DJ
225}
226
227/* Handle the start of a <vector> element. Initialize the type and
228 record it with the current feature. */
229
230static void
231tdesc_start_vector (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 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
ad068eab 237 struct tdesc_type *field_type;
123dc839
DJ
238 char *id, *field_type_id;
239 int count;
240
241 id = attrs[0].value;
242 field_type_id = attrs[1].value;
243 count = * (ULONGEST *) attrs[2].value;
244
245 field_type = tdesc_named_type (data->current_feature, field_type_id);
246 if (field_type == NULL)
247 gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""),
248 id, field_type_id);
249
ad068eab 250 tdesc_create_vector (data->current_feature, id, field_type, count);
123dc839
DJ
251}
252
23181151
DJ
253/* The elements and attributes of an XML target description. */
254
123dc839
DJ
255static const struct gdb_xml_attribute field_attributes[] = {
256 { "name", GDB_XML_AF_NONE, NULL, NULL },
257 { "type", GDB_XML_AF_NONE, NULL, NULL },
258 { NULL, GDB_XML_AF_NONE, NULL, NULL }
259};
260
261static const struct gdb_xml_element union_children[] = {
262 { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE,
263 tdesc_start_field, NULL },
264 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
265};
266
267static const struct gdb_xml_attribute reg_attributes[] = {
268 { "name", GDB_XML_AF_NONE, NULL, NULL },
269 { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
270 { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
271 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL },
272 { "group", GDB_XML_AF_OPTIONAL, NULL, NULL },
273 { "save-restore", GDB_XML_AF_OPTIONAL,
274 gdb_xml_parse_attr_enum, gdb_xml_enums_boolean },
275 { NULL, GDB_XML_AF_NONE, NULL, NULL }
276};
277
278static const struct gdb_xml_attribute union_attributes[] = {
279 { "id", GDB_XML_AF_NONE, NULL, NULL },
280 { NULL, GDB_XML_AF_NONE, NULL, NULL }
281};
282
283static const struct gdb_xml_attribute vector_attributes[] = {
284 { "id", GDB_XML_AF_NONE, NULL, NULL },
285 { "type", GDB_XML_AF_NONE, NULL, NULL },
286 { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
287 { NULL, GDB_XML_AF_NONE, NULL, NULL }
288};
289
290static const struct gdb_xml_attribute feature_attributes[] = {
291 { "name", GDB_XML_AF_NONE, NULL, NULL },
292 { NULL, GDB_XML_AF_NONE, NULL, NULL }
293};
294
295static const struct gdb_xml_element feature_children[] = {
296 { "reg", reg_attributes, NULL,
297 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
298 tdesc_start_reg, NULL },
299 { "union", union_attributes, union_children,
300 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
ad068eab 301 tdesc_start_union, NULL },
123dc839
DJ
302 { "vector", vector_attributes, NULL,
303 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
304 tdesc_start_vector, NULL },
305 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
306};
307
1780a0ed
DJ
308static const struct gdb_xml_attribute target_attributes[] = {
309 { "version", GDB_XML_AF_NONE, NULL, NULL },
310 { NULL, GDB_XML_AF_NONE, NULL, NULL }
311};
312
123dc839 313static const struct gdb_xml_element target_children[] = {
23181151
DJ
314 { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
315 NULL, tdesc_end_arch },
123dc839
DJ
316 { "feature", feature_attributes, feature_children,
317 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
318 tdesc_start_feature, NULL },
23181151
DJ
319 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
320};
321
123dc839 322static const struct gdb_xml_element tdesc_elements[] = {
1780a0ed
DJ
323 { "target", target_attributes, target_children, GDB_XML_EF_NONE,
324 tdesc_start_target, NULL },
23181151
DJ
325 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
326};
327
328/* Parse DOCUMENT into a target description and return it. */
329
330static struct target_desc *
108546a0
DJ
331tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
332 void *fetcher_baton)
23181151
DJ
333{
334 struct cleanup *back_to, *result_cleanup;
335 struct gdb_xml_parser *parser;
336 struct tdesc_parsing_data data;
fc6e0168 337 struct tdesc_xml_cache *cache;
108546a0 338 char *expanded_text;
fc6e0168 339 int ix;
23181151 340
108546a0
DJ
341 /* Expand all XInclude directives. */
342 expanded_text = xml_process_xincludes (_("target description"),
343 document, fetcher, fetcher_baton, 0);
344 if (expanded_text == NULL)
345 {
346 warning (_("Could not load XML target description; ignoring"));
347 return NULL;
348 }
23181151 349
fc6e0168
DJ
350 /* Check for an exact match in the list of descriptions we have
351 previously parsed. strcmp is a slightly inefficient way to
352 do this; an SHA-1 checksum would work as well. */
353 for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
354 if (strcmp (cache->xml_document, expanded_text) == 0)
355 {
356 xfree (expanded_text);
357 return cache->tdesc;
358 }
359
360 back_to = make_cleanup (null_cleanup, NULL);
23181151
DJ
361 parser = gdb_xml_create_parser_and_cleanup (_("target description"),
362 tdesc_elements, &data);
108546a0 363 gdb_xml_use_dtd (parser, "gdb-target.dtd");
23181151 364
108546a0 365 memset (&data, 0, sizeof (struct tdesc_parsing_data));
23181151
DJ
366 data.tdesc = allocate_target_description ();
367 result_cleanup = make_cleanup_free_target_description (data.tdesc);
fc6e0168 368 make_cleanup (xfree, expanded_text);
23181151 369
108546a0 370 if (gdb_xml_parse (parser, expanded_text) == 0)
23181151
DJ
371 {
372 /* Parsed successfully. */
fc6e0168
DJ
373 struct tdesc_xml_cache new_cache;
374
375 new_cache.xml_document = expanded_text;
376 new_cache.tdesc = data.tdesc;
377 VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
23181151
DJ
378 discard_cleanups (result_cleanup);
379 do_cleanups (back_to);
380 return data.tdesc;
381 }
382 else
383 {
384 warning (_("Could not load XML target description; ignoring"));
385 do_cleanups (back_to);
386 return NULL;
387 }
388}
23181151
DJ
389#endif /* HAVE_LIBEXPAT */
390\f
391
23181151
DJ
392/* Open FILENAME, read all its text into memory, close it, and return
393 the text. If something goes wrong, return NULL and warn. */
394
395static char *
108546a0 396fetch_xml_from_file (const char *filename, void *baton)
23181151 397{
108546a0 398 const char *dirname = baton;
23181151
DJ
399 FILE *file;
400 struct cleanup *back_to;
401 char *text;
402 size_t len, offset;
403
108546a0 404 if (dirname && *dirname)
23181151 405 {
6eb7ee03 406 char *fullname = concat (dirname, "/", filename, (char *) NULL);
108546a0
DJ
407 if (fullname == NULL)
408 nomem (0);
409 file = fopen (fullname, FOPEN_RT);
410 xfree (fullname);
23181151 411 }
108546a0
DJ
412 else
413 file = fopen (filename, FOPEN_RT);
414
415 if (file == NULL)
416 return NULL;
417
7c8a8b04 418 back_to = make_cleanup_fclose (file);
23181151
DJ
419
420 /* Read in the whole file, one chunk at a time. */
421 len = 4096;
422 offset = 0;
423 text = xmalloc (len);
424 make_cleanup (free_current_contents, &text);
425 while (1)
426 {
427 size_t bytes_read;
428
429 /* Continue reading where the last read left off. Leave at least
430 one byte so that we can NUL-terminate the result. */
431 bytes_read = fread (text + offset, 1, len - offset - 1, file);
432 if (ferror (file))
433 {
434 warning (_("Read error from \"%s\""), filename);
435 do_cleanups (back_to);
436 return NULL;
437 }
438
439 offset += bytes_read;
440
441 if (feof (file))
442 break;
443
444 len = len * 2;
445 text = xrealloc (text, len);
446 }
447
448 fclose (file);
449 discard_cleanups (back_to);
450
451 text[offset] = '\0';
452 return text;
453}
454
455/* Read an XML target description from FILENAME. Parse it, and return
456 the parsed description. */
457
458const struct target_desc *
459file_read_description_xml (const char *filename)
460{
461 struct target_desc *tdesc;
462 char *tdesc_str;
463 struct cleanup *back_to;
108546a0 464 char *dirname;
23181151 465
108546a0 466 tdesc_str = fetch_xml_from_file (filename, NULL);
23181151 467 if (tdesc_str == NULL)
108546a0
DJ
468 {
469 warning (_("Could not open \"%s\""), filename);
470 return NULL;
471 }
23181151
DJ
472
473 back_to = make_cleanup (xfree, tdesc_str);
108546a0 474
e1024ff1
DJ
475 dirname = ldirname (filename);
476 if (dirname != NULL)
477 make_cleanup (xfree, dirname);
108546a0
DJ
478
479 tdesc = tdesc_parse_xml (tdesc_str, fetch_xml_from_file, dirname);
23181151
DJ
480 do_cleanups (back_to);
481
482 return tdesc;
483}
484
108546a0
DJ
485/* Read a string representation of available features from the target,
486 using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is
487 malloc allocated and NUL-terminated. NAME should be a non-NULL
488 string identifying the XML document we want; the top level document
489 is "target.xml". Other calls may be performed for the DTD or
490 for <xi:include>. */
491
492static char *
493fetch_available_features_from_target (const char *name, void *baton_)
494{
495 struct target_ops *ops = baton_;
496
497 /* Read this object as a string. This ensures that a NUL
498 terminator is added. */
499 return target_read_stralloc (ops,
500 TARGET_OBJECT_AVAILABLE_FEATURES,
501 name);
502}
503\f
504
23181151
DJ
505/* Read an XML target description using OPS. Parse it, and return the
506 parsed description. */
507
508const struct target_desc *
509target_read_description_xml (struct target_ops *ops)
510{
511 struct target_desc *tdesc;
512 char *tdesc_str;
513 struct cleanup *back_to;
514
108546a0 515 tdesc_str = fetch_available_features_from_target ("target.xml", ops);
23181151
DJ
516 if (tdesc_str == NULL)
517 return NULL;
518
519 back_to = make_cleanup (xfree, tdesc_str);
108546a0
DJ
520 tdesc = tdesc_parse_xml (tdesc_str,
521 fetch_available_features_from_target,
522 ops);
23181151
DJ
523 do_cleanups (back_to);
524
525 return tdesc;
526}
This page took 0.355516 seconds and 4 git commands to generate.