diff options
Diffstat (limited to 'gdb/xml-tdesc.c')
-rw-r--r-- | gdb/xml-tdesc.c | 182 |
1 files changed, 134 insertions, 48 deletions
diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c index adfe9fd..a0fd08a 100644 --- a/gdb/xml-tdesc.c +++ b/gdb/xml-tdesc.c @@ -91,12 +91,9 @@ struct tdesc_parsing_data /* The struct or union we are currently parsing, or last parsed. */ struct tdesc_type *current_type; - /* The byte size of the current struct type, if specified. Zero - if not specified. */ + /* The byte size of the current struct/flags type, if specified. Zero + if not specified. Flags values must specify a size. */ int current_type_size; - - /* Whether the current type is a flags type. */ - int current_type_is_flags; }; /* Handle the end of an <architecture> element and its value. */ @@ -240,7 +237,6 @@ tdesc_start_union (struct gdb_xml_parser *parser, data->current_type = tdesc_create_union (data->current_feature, id); data->current_type_size = 0; - data->current_type_is_flags = 0; } /* Handle the start of a <struct> element. Initialize the type and @@ -259,7 +255,6 @@ tdesc_start_struct (struct gdb_xml_parser *parser, type = tdesc_create_struct (data->current_feature, id); data->current_type = type; data->current_type_size = 0; - data->current_type_is_flags = 0; attr = xml_find_attribute (attributes, "size"); if (attr != NULL) @@ -297,12 +292,34 @@ tdesc_start_flags (struct gdb_xml_parser *parser, type = tdesc_create_flags (data->current_feature, id, size); data->current_type = type; + data->current_type_size = size; +} + +static void +tdesc_start_enum (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, VEC(gdb_xml_value_s) *attributes) +{ + struct tdesc_parsing_data *data = user_data; + char *id = xml_find_attribute (attributes, "id")->value; + int size = * (ULONGEST *) + xml_find_attribute (attributes, "size")->value; + struct tdesc_type *type; + + if (size > MAX_FIELD_SIZE) + { + gdb_xml_error (parser, + _("Enum size %s is larger than maximum (%d)"), + pulongest (size), MAX_FIELD_SIZE); + } + type = tdesc_create_enum (data->current_feature, id, size); + + data->current_type = type; data->current_type_size = 0; - data->current_type_is_flags = 1; } /* Handle the start of a <field> element. Attach the field to the - current struct or union. */ + current struct, union or flags. */ static void tdesc_start_field (struct gdb_xml_parser *parser, @@ -319,9 +336,15 @@ tdesc_start_field (struct gdb_xml_parser *parser, attr = xml_find_attribute (attributes, "type"); if (attr != NULL) - field_type_id = (char *) attr->value; + { + field_type_id = (char *) attr->value; + field_type = tdesc_named_type (data->current_feature, field_type_id); + } else - field_type_id = NULL; + { + field_type_id = NULL; + field_type = NULL; + } attr = xml_find_attribute (attributes, "start"); if (attr != NULL) @@ -355,65 +378,107 @@ tdesc_start_field (struct gdb_xml_parser *parser, else end = -1; - if (field_type_id != NULL) - { - if (data->current_type_is_flags) - gdb_xml_error (parser, _("Cannot add typed field \"%s\" to flags"), - field_name); - if (data->current_type_size != 0) - gdb_xml_error (parser, - _("Explicitly sized type can not " - "contain non-bitfield \"%s\""), - field_name); - - field_type = tdesc_named_type (data->current_feature, field_type_id); - if (field_type == NULL) - gdb_xml_error (parser, _("Field \"%s\" references undefined " - "type \"%s\""), - field_name, field_type_id); - - tdesc_add_field (data->current_type, field_name, field_type); - } - else if (start != -1 && end != -1) + if (start != -1) { struct tdesc_type *t = data->current_type; - if (data->current_type_is_flags) - tdesc_add_flag (t, start, field_name); - else + if (data->current_type_size == 0) + gdb_xml_error (parser, + _("Bitfields must live in explicitly sized types")); + + if (field_type_id != NULL + && strcmp (field_type_id, "bool") == 0 + && !(start == end || end == -1)) { - if (data->current_type_size == 0) - gdb_xml_error (parser, - _("Implicitly sized type can " - "not contain bitfield \"%s\""), - field_name); + gdb_xml_error (parser, + _("Boolean fields must be one bit in size")); + } - if (end >= 64) - gdb_xml_error (parser, - _("Bitfield \"%s\" goes past " - "64 bits (unsupported)"), - field_name); + if (end >= 64) + gdb_xml_error (parser, + _("Bitfield \"%s\" goes past " + "64 bits (unsupported)"), + field_name); + if (end != -1) + { /* Assume that the bit numbering in XML is "lsb-zero". Most - architectures other than PowerPC use this ordering. In - the future, we can add an XML tag to indicate "msb-zero" + architectures other than PowerPC use this ordering. In the + future, we can add an XML tag to indicate "msb-zero" numbering. */ if (start > end) gdb_xml_error (parser, _("Bitfield \"%s\" has start after end"), field_name); - if (end >= data->current_type_size * TARGET_CHAR_BIT) gdb_xml_error (parser, _("Bitfield \"%s\" does not fit in struct")); + } - tdesc_add_bitfield (t, field_name, start, end); + if (end == -1) + { + if (field_type != NULL) + tdesc_add_typed_bitfield (t, field_name, start, start, field_type); + else + tdesc_add_flag (t, start, field_name); } + else if (field_type != NULL) + tdesc_add_typed_bitfield (t, field_name, start, end, field_type); + else + tdesc_add_bitfield (t, field_name, start, end); + } + else if (start == -1 && end != -1) + gdb_xml_error (parser, _("End specified but not start")); + else if (field_type_id != NULL) + { + /* TDESC_TYPE_FLAGS values are explicitly sized, so the following test + catches adding non-bitfield types to flags as well. */ + if (data->current_type_size != 0) + gdb_xml_error (parser, + _("Explicitly sized type cannot " + "contain non-bitfield \"%s\""), + field_name); + + if (field_type == NULL) + gdb_xml_error (parser, _("Field \"%s\" references undefined " + "type \"%s\""), + field_name, field_type_id); + + tdesc_add_field (data->current_type, field_name, field_type); } else gdb_xml_error (parser, _("Field \"%s\" has neither type nor bit position"), field_name); } +/* Handle the start of an <evalue> element. Attach the value to the + current enum. */ + +static void +tdesc_start_enum_value (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, VEC(gdb_xml_value_s) *attributes) +{ + struct tdesc_parsing_data *data = (struct tdesc_parsing_data *) user_data; + struct gdb_xml_value *attr; + char *field_name; + ULONGEST ul_value; + int value; + + field_name = (char *) xml_find_attribute (attributes, "name")->value; + + attr = xml_find_attribute (attributes, "value"); + ul_value = * (ULONGEST *) attr->value; + if (ul_value > INT_MAX) + { + gdb_xml_error (parser, + _("Enum value %s is larger than maximum (%d)"), + pulongest (ul_value), INT_MAX); + } + value = ul_value; + + tdesc_add_enum_value (data->current_type, value, field_name); +} + /* Handle the start of a <vector> element. Initialize the type and record it with the current feature. */ @@ -457,12 +522,24 @@ static const struct gdb_xml_attribute field_attributes[] = { { NULL, GDB_XML_AF_NONE, NULL, NULL } }; +static const struct gdb_xml_attribute enum_value_attributes[] = { + { "name", GDB_XML_AF_NONE, NULL, NULL }, + { "value", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + static const struct gdb_xml_element struct_union_children[] = { { "field", field_attributes, NULL, GDB_XML_EF_REPEATABLE, tdesc_start_field, NULL }, { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; +static const struct gdb_xml_element enum_children[] = { + { "evalue", enum_value_attributes, NULL, GDB_XML_EF_REPEATABLE, + tdesc_start_enum_value, NULL }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + static const struct gdb_xml_attribute reg_attributes[] = { { "name", GDB_XML_AF_NONE, NULL, NULL }, { "bitsize", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, @@ -486,6 +563,12 @@ static const struct gdb_xml_attribute flags_attributes[] = { { NULL, GDB_XML_AF_NONE, NULL, NULL } }; +static const struct gdb_xml_attribute enum_attributes[] = { + { "id", GDB_XML_AF_NONE, NULL, NULL }, + { "size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL}, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + static const struct gdb_xml_attribute vector_attributes[] = { { "id", GDB_XML_AF_NONE, NULL, NULL }, { "type", GDB_XML_AF_NONE, NULL, NULL }, @@ -511,6 +594,9 @@ static const struct gdb_xml_element feature_children[] = { { "flags", flags_attributes, struct_union_children, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, tdesc_start_flags, NULL }, + { "enum", enum_attributes, enum_children, + GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, + tdesc_start_enum, NULL }, { "vector", vector_attributes, NULL, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, tdesc_start_vector, NULL }, |