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