1 /* XML target description support for GDB. 2 3 Copyright (C) 2006, 2008-2012 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 = xml_find_attribute (attributes, "version")->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 = xml_find_attribute (attributes, "name")->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 = xml_find_attribute (attributes, "id")->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 = xml_find_attribute (attributes, "id")->value; 253 struct tdesc_type *type; 254 struct gdb_xml_value *attr; 255 256 type = tdesc_create_struct (data->current_feature, id); 257 data->current_type = type; 258 data->current_type_size = 0; 259 data->current_type_is_flags = 0; 260 261 attr = xml_find_attribute (attributes, "size"); 262 if (attr != NULL) 263 { 264 int size = (int) * (ULONGEST *) attr->value; 265 266 tdesc_set_struct_size (type, size); 267 data->current_type_size = size; 268 } 269 } 270 271 static void 272 tdesc_start_flags (struct gdb_xml_parser *parser, 273 const struct gdb_xml_element *element, 274 void *user_data, VEC(gdb_xml_value_s) *attributes) 275 { 276 struct tdesc_parsing_data *data = user_data; 277 char *id = xml_find_attribute (attributes, "id")->value; 278 int length = (int) * (ULONGEST *) 279 xml_find_attribute (attributes, "size")->value; 280 struct tdesc_type *type; 281 282 type = tdesc_create_flags (data->current_feature, id, length); 283 284 data->current_type = type; 285 data->current_type_size = 0; 286 data->current_type_is_flags = 1; 287 } 288 289 /* Handle the start of a <field> element. Attach the field to the 290 current struct or union. */ 291 292 static void 293 tdesc_start_field (struct gdb_xml_parser *parser, 294 const struct gdb_xml_element *element, 295 void *user_data, VEC(gdb_xml_value_s) *attributes) 296 { 297 struct tdesc_parsing_data *data = user_data; 298 struct gdb_xml_value *attr; 299 struct tdesc_type *field_type; 300 char *field_name, *field_type_id; 301 int start, end; 302 303 field_name = xml_find_attribute (attributes, "name")->value; 304 305 attr = xml_find_attribute (attributes, "type"); 306 if (attr != NULL) 307 field_type_id = attr->value; 308 else 309 field_type_id = NULL; 310 311 attr = xml_find_attribute (attributes, "start"); 312 if (attr != NULL) 313 start = * (ULONGEST *) attr->value; 314 else 315 start = -1; 316 317 attr = xml_find_attribute (attributes, "end"); 318 if (attr != NULL) 319 end = * (ULONGEST *) attr->value; 320 else 321 end = -1; 322 323 if (field_type_id != NULL) 324 { 325 if (data->current_type_is_flags) 326 gdb_xml_error (parser, _("Cannot add typed field \"%s\" to flags"), 327 field_name); 328 if (data->current_type_size != 0) 329 gdb_xml_error (parser, 330 _("Explicitly sized type can not " 331 "contain non-bitfield \"%s\""), 332 field_name); 333 334 field_type = tdesc_named_type (data->current_feature, field_type_id); 335 if (field_type == NULL) 336 gdb_xml_error (parser, _("Field \"%s\" references undefined " 337 "type \"%s\""), 338 field_name, field_type_id); 339 340 tdesc_add_field (data->current_type, field_name, field_type); 341 } 342 else if (start != -1 && end != -1) 343 { 344 struct tdesc_type *t = data->current_type; 345 346 if (data->current_type_is_flags) 347 tdesc_add_flag (t, start, field_name); 348 else 349 { 350 if (data->current_type_size == 0) 351 gdb_xml_error (parser, 352 _("Implicitly sized type can " 353 "not contain bitfield \"%s\""), 354 field_name); 355 356 if (end >= 64) 357 gdb_xml_error (parser, 358 _("Bitfield \"%s\" goes past " 359 "64 bits (unsupported)"), 360 field_name); 361 362 /* Assume that the bit numbering in XML is "lsb-zero". Most 363 architectures other than PowerPC use this ordering. In 364 the future, we can add an XML tag to indicate "msb-zero" 365 numbering. */ 366 if (start > end) 367 gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"), 368 field_name); 369 370 if (end >= data->current_type_size * TARGET_CHAR_BIT) 371 gdb_xml_error (parser, 372 _("Bitfield \"%s\" does not fit in struct")); 373 374 tdesc_add_bitfield (t, field_name, start, end); 375 } 376 } 377 else 378 gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"), 379 field_name); 380 } 381 382 /* Handle the start of a <vector> element. Initialize the type and 383 record it with the current feature. */ 384 385 static void 386 tdesc_start_vector (struct gdb_xml_parser *parser, 387 const struct gdb_xml_element *element, 388 void *user_data, VEC(gdb_xml_value_s) *attributes) 389 { 390 struct tdesc_parsing_data *data = user_data; 391 struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes); 392 struct tdesc_type *field_type; 393 char *id, *field_type_id; 394 int count; 395 396 id = attrs[0].value; 397 field_type_id = attrs[1].value; 398 count = * (ULONGEST *) attrs[2].value; 399 400 field_type = tdesc_named_type (data->current_feature, field_type_id); 401 if (field_type == NULL) 402 gdb_xml_error (parser, _("Vector \"%s\" references undefined type \"%s\""), 403 id, field_type_id); 404 405 tdesc_create_vector (data->current_feature, id, field_type, count); 406 } 407 408 /* The elements and attributes of an XML target description. */ 409 410 static const struct gdb_xml_attribute field_attributes[] = { 411 { "name", GDB_XML_AF_NONE, NULL, NULL }, 412 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL }, 413 { "start", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, 414 { "end", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, 415 { NULL, GDB_XML_AF_NONE, NULL, NULL } 416 }; 417 418 static const struct gdb_xml_element struct_union_children[] = { 419 { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE, 420 tdesc_start_field, NULL }, 421 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 422 }; 423 424 static const struct gdb_xml_attribute reg_attributes[] = { 425 { "name", GDB_XML_AF_NONE, NULL, NULL }, 426 { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 427 { "regnum", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, 428 { "type", GDB_XML_AF_OPTIONAL, NULL, NULL }, 429 { "group", GDB_XML_AF_OPTIONAL, NULL, NULL }, 430 { "save-restore", GDB_XML_AF_OPTIONAL, 431 gdb_xml_parse_attr_enum, gdb_xml_enums_boolean }, 432 { NULL, GDB_XML_AF_NONE, NULL, NULL } 433 }; 434 435 static const struct gdb_xml_attribute struct_union_attributes[] = { 436 { "id", GDB_XML_AF_NONE, NULL, NULL }, 437 { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL}, 438 { NULL, GDB_XML_AF_NONE, NULL, NULL } 439 }; 440 441 static const struct gdb_xml_attribute flags_attributes[] = { 442 { "id", GDB_XML_AF_NONE, NULL, NULL }, 443 { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL}, 444 { NULL, GDB_XML_AF_NONE, NULL, NULL } 445 }; 446 447 static const struct gdb_xml_attribute vector_attributes[] = { 448 { "id", GDB_XML_AF_NONE, NULL, NULL }, 449 { "type", GDB_XML_AF_NONE, NULL, NULL }, 450 { "count", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 451 { NULL, GDB_XML_AF_NONE, NULL, NULL } 452 }; 453 454 static const struct gdb_xml_attribute feature_attributes[] = { 455 { "name", GDB_XML_AF_NONE, NULL, NULL }, 456 { NULL, GDB_XML_AF_NONE, NULL, NULL } 457 }; 458 459 static const struct gdb_xml_element feature_children[] = { 460 { "reg", reg_attributes, NULL, 461 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 462 tdesc_start_reg, NULL }, 463 { "struct", struct_union_attributes, struct_union_children, 464 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 465 tdesc_start_struct, NULL }, 466 { "union", struct_union_attributes, struct_union_children, 467 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 468 tdesc_start_union, NULL }, 469 { "flags", flags_attributes, struct_union_children, 470 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 471 tdesc_start_flags, NULL }, 472 { "vector", vector_attributes, NULL, 473 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 474 tdesc_start_vector, NULL }, 475 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 476 }; 477 478 static const struct gdb_xml_attribute target_attributes[] = { 479 { "version", GDB_XML_AF_NONE, NULL, NULL }, 480 { NULL, GDB_XML_AF_NONE, NULL, NULL } 481 }; 482 483 static const struct gdb_xml_element target_children[] = { 484 { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL, 485 NULL, tdesc_end_arch }, 486 { "osabi", NULL, NULL, GDB_XML_EF_OPTIONAL, 487 NULL, tdesc_end_osabi }, 488 { "compatible", NULL, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 489 NULL, tdesc_end_compatible }, 490 { "feature", feature_attributes, feature_children, 491 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, 492 tdesc_start_feature, NULL }, 493 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 494 }; 495 496 static const struct gdb_xml_element tdesc_elements[] = { 497 { "target", target_attributes, target_children, GDB_XML_EF_NONE, 498 tdesc_start_target, NULL }, 499 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 500 }; 501 502 /* Parse DOCUMENT into a target description and return it. */ 503 504 static struct target_desc * 505 tdesc_parse_xml (const char *document, xml_fetch_another fetcher, 506 void *fetcher_baton) 507 { 508 struct cleanup *back_to, *result_cleanup; 509 struct tdesc_parsing_data data; 510 struct tdesc_xml_cache *cache; 511 char *expanded_text; 512 int ix; 513 514 /* Expand all XInclude directives. */ 515 expanded_text = xml_process_xincludes (_("target description"), 516 document, fetcher, fetcher_baton, 0); 517 if (expanded_text == NULL) 518 { 519 warning (_("Could not load XML target description; ignoring")); 520 return NULL; 521 } 522 523 /* Check for an exact match in the list of descriptions we have 524 previously parsed. strcmp is a slightly inefficient way to 525 do this; an SHA-1 checksum would work as well. */ 526 for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++) 527 if (strcmp (cache->xml_document, expanded_text) == 0) 528 { 529 xfree (expanded_text); 530 return cache->tdesc; 531 } 532 533 back_to = make_cleanup (null_cleanup, NULL); 534 535 memset (&data, 0, sizeof (struct tdesc_parsing_data)); 536 data.tdesc = allocate_target_description (); 537 result_cleanup = make_cleanup_free_target_description (data.tdesc); 538 make_cleanup (xfree, expanded_text); 539 540 if (gdb_xml_parse_quick (_("target description"), "gdb-target.dtd", 541 tdesc_elements, expanded_text, &data) == 0) 542 { 543 /* Parsed successfully. */ 544 struct tdesc_xml_cache new_cache; 545 546 new_cache.xml_document = expanded_text; 547 new_cache.tdesc = data.tdesc; 548 VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache); 549 discard_cleanups (result_cleanup); 550 do_cleanups (back_to); 551 return data.tdesc; 552 } 553 else 554 { 555 warning (_("Could not load XML target description; ignoring")); 556 do_cleanups (back_to); 557 return NULL; 558 } 559 } 560 #endif /* HAVE_LIBEXPAT */ 561 562 563 /* Read an XML target description from FILENAME. Parse it, and return 564 the parsed description. */ 565 566 const struct target_desc * 567 file_read_description_xml (const char *filename) 568 { 569 struct target_desc *tdesc; 570 char *tdesc_str; 571 struct cleanup *back_to; 572 char *dirname; 573 574 tdesc_str = xml_fetch_content_from_file (filename, NULL); 575 if (tdesc_str == NULL) 576 { 577 warning (_("Could not open \"%s\""), filename); 578 return NULL; 579 } 580 581 back_to = make_cleanup (xfree, tdesc_str); 582 583 dirname = ldirname (filename); 584 if (dirname != NULL) 585 make_cleanup (xfree, dirname); 586 587 tdesc = tdesc_parse_xml (tdesc_str, xml_fetch_content_from_file, dirname); 588 do_cleanups (back_to); 589 590 return tdesc; 591 } 592 593 /* Read a string representation of available features from the target, 594 using TARGET_OBJECT_AVAILABLE_FEATURES. The returned string is 595 malloc allocated and NUL-terminated. NAME should be a non-NULL 596 string identifying the XML document we want; the top level document 597 is "target.xml". Other calls may be performed for the DTD or 598 for <xi:include>. */ 599 600 static char * 601 fetch_available_features_from_target (const char *name, void *baton_) 602 { 603 struct target_ops *ops = baton_; 604 605 /* Read this object as a string. This ensures that a NUL 606 terminator is added. */ 607 return target_read_stralloc (ops, 608 TARGET_OBJECT_AVAILABLE_FEATURES, 609 name); 610 } 611 612 613 /* Read an XML target description using OPS. Parse it, and return the 614 parsed description. */ 615 616 const struct target_desc * 617 target_read_description_xml (struct target_ops *ops) 618 { 619 struct target_desc *tdesc; 620 char *tdesc_str; 621 struct cleanup *back_to; 622 623 tdesc_str = fetch_available_features_from_target ("target.xml", ops); 624 if (tdesc_str == NULL) 625 return NULL; 626 627 back_to = make_cleanup (xfree, tdesc_str); 628 tdesc = tdesc_parse_xml (tdesc_str, 629 fetch_available_features_from_target, 630 ops); 631 do_cleanups (back_to); 632 633 return tdesc; 634 } 635