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