1 /* 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 } 633