From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12933 invoked by alias); 3 Jun 2011 11:06:00 -0000 Received: (qmail 12924 invoked by uid 22791); 3 Jun 2011 11:05:57 -0000 X-SWARE-Spam-Status: No, hits=-0.2 required=5.0 tests=AWL,BAYES_20,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,T_FILL_THIS_FORM_SHORT,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-vx0-f169.google.com (HELO mail-vx0-f169.google.com) (209.85.220.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 03 Jun 2011 11:05:41 +0000 Received: by vxk20 with SMTP id 20so1678244vxk.0 for ; Fri, 03 Jun 2011 04:05:40 -0700 (PDT) MIME-Version: 1.0 Received: by 10.52.174.176 with SMTP id bt16mr440150vdc.282.1307099139765; Fri, 03 Jun 2011 04:05:39 -0700 (PDT) Received: by 10.52.181.194 with HTTP; Fri, 3 Jun 2011 04:05:39 -0700 (PDT) Date: Fri, 03 Jun 2011 11:06:00 -0000 Message-ID: Subject: [target-description] enum and typed fields in struct From: Wei-cheng Wang To: gdb-patches@sourceware.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-06/txt/msg00049.txt.bz2 Would it be nice if =E2=80=98print $cpsr=E2=80=99 shows `$1 =3D {[ #4 T C Z ], M =3D User, IT_cond =3D 0, GE =3D 0, DNM =3D 0}' instead of `$1 =3D 1610612784' ? Current target-description does not support enum type, and typed bit-fields are not allowed. However, non-GPRRs usually consist of flags and bit-fields, and it is likely bit-fields are not just magic numbers but symbolic constants. In this patch, I implement enum for target-description, typed bit-fields and c-tdesc for struct and enum. So we can use the following tdesc XML to describe, for example, ARM cprs registers. Any idea? Wei-cheng # modified: gdb/features/gdb-target.dtd # modified: gdb/gdbtypes.c # modified: gdb/gdbtypes.h # modified: gdb/target-descriptions.c # modified: gdb/target-descriptions.h # modified: gdb/xml-tdesc.c diff --git a/gdb/features/gdb-target.dtd b/gdb/features/gdb-target.dtd index fd7dac3..ea4f7ce 100644 --- a/gdb/features/gdb-target.dtd +++ b/gdb/features/gdb-target.dtd @@ -45,6 +45,11 @@ id CDATA #REQUIRED size CDATA #REQUIRED> + + + u.u.fields, ix, f); ix++) { + struct field *fld; + struct type *field_type; + int bitsize, total_size; + + /* This code should backward compatible with old tdesc. + For non-sized struct with typed-fields, + the size of struct should be the sum of size of all fields. + append_composite_type_field() */ if (f->type =3D=3D NULL) { - /* Bitfield. */ - struct field *fld; - struct type *field_type; - int bitsize, total_size; - /* This invariant should be preserved while creating types. */ gdb_assert (tdesc_type->u.u.size !=3D 0); @@ -647,28 +651,42 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type) fld =3D append_composite_type_field_raw (type, xstrdup (f->name), field_type); - - /* For little-endian, BITPOS counts from the LSB of - the structure and marks the LSB of the field. For - big-endian, BITPOS counts from the MSB of the - structure and marks the MSB of the field. Either - way, it is the number of bits to the "left" of the - field. To calculate this in big-endian, we need - the total size of the structure. */ - bitsize =3D f->end - f->start + 1; - total_size =3D tdesc_type->u.u.size * TARGET_CHAR_BIT; - if (gdbarch_bits_big_endian (gdbarch)) - FIELD_BITPOS (fld[0]) =3D total_size - f->start - bitsize; - else - FIELD_BITPOS (fld[0]) =3D f->start; - FIELD_BITSIZE (fld[0]) =3D bitsize; } else { field_type =3D tdesc_gdb_type (gdbarch, f->type); - append_composite_type_field (type, xstrdup (f->name), + fld =3D append_composite_type_field (type, xstrdup (f->name), field_type); } + + /* This will turn all fields into bitfileds */ + if (f->start =3D=3D -1) + { + if (TYPE_NFIELDS (type) > 1) + f->start =3D (FIELD_BITPOS (fld[-1]) + FIELD_BITSIZE (fld[-1])); + else + f->start =3D 0; + } + if (f->end =3D=3D -1) + { + f->end =3D f->start - 1 + TYPE_LENGTH (field_type) + * TARGET_CHAR_BIT; + } + + /* For little-endian, BITPOS counts from the LSB of + the structure and marks the LSB of the field. For + big-endian, BITPOS counts from the MSB of the + structure and marks the MSB of the field. Either + way, it is the number of bits to the "left" of the + field. To calculate this in big-endian, we need + the total size of the structure. */ + bitsize =3D f->end - f->start + 1; + total_size =3D tdesc_type->u.u.size * TARGET_CHAR_BIT; + if (gdbarch_bits_big_endian (gdbarch)) + FIELD_BITPOS (fld[0]) =3D total_size - f->start - bitsize; + else + FIELD_BITPOS (fld[0]) =3D f->start; + FIELD_BITSIZE (fld[0]) =3D bitsize; } if (tdesc_type->u.u.size !=3D 0) @@ -719,6 +737,27 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type) return type; } + + case TDESC_TYPE_ENUM: + { + struct tdesc_type_flag *f; + int ix; + + type =3D arch_type (gdbarch, TYPE_CODE_ENUM, + tdesc_type->u.f.size, tdesc_type->name); + TYPE_UNSIGNED (type) =3D 1; + for (ix =3D 0; + VEC_iterate (tdesc_type_flag, tdesc_type->u.f.flags, ix, f); + ix++) + { + struct field *fld; + fld =3D append_composite_type_field_raw (type, + xstrdup (f->name), NULL); + FIELD_BITPOS (fld[0]) =3D f->start; + } + + return type; + } } internal_error (__FILE__, __LINE__, @@ -1220,6 +1259,7 @@ tdesc_free_type (struct tdesc_type *type) } break; + case TDESC_TYPE_ENUM: case TDESC_TYPE_FLAGS: { struct tdesc_type_flag *f; @@ -1306,6 +1346,20 @@ tdesc_create_flags (struct tdesc_feature *feature, const char *name, return type; } +struct tdesc_type * +tdesc_create_enum (struct tdesc_feature *feature, const char *name, + LONGEST size) +{ + struct tdesc_type *type =3D XZALLOC (struct tdesc_type); + + type->name =3D xstrdup (name); + type->kind =3D TDESC_TYPE_ENUM; + type->u.f.size =3D size; + + VEC_safe_push (tdesc_type_p, feature->types, type); + return type; +} + /* Add a new field. Return a temporary pointer to the field, which is only valid until the next call to tdesc_add_field (the vector might be reallocated). */ @@ -1321,6 +1375,8 @@ tdesc_add_field (struct tdesc_type *type, const char *field_name, f.name =3D xstrdup (field_name); f.type =3D field_type; + f.start =3D -1; + f.end =3D -1; VEC_safe_push (tdesc_type_field, type->u.u.fields, &f); } @@ -1329,7 +1385,7 @@ tdesc_add_field (struct tdesc_type *type, const char *field_name, void tdesc_add_bitfield (struct tdesc_type *type, const char *field_name, - int start, int end) + int start, int end, struct tdesc_type *field_type) { struct tdesc_type_field f =3D { 0 }; @@ -1338,6 +1394,7 @@ tdesc_add_bitfield (struct tdesc_type *type, const char *field_name, f.name =3D xstrdup (field_name); f.start =3D start; f.end =3D end; + f.type =3D field_type; VEC_safe_push (tdesc_type_field, type->u.u.fields, &f); } @@ -1348,7 +1405,8 @@ tdesc_add_flag (struct tdesc_type *type, int start, { struct tdesc_type_flag f =3D { 0 }; - gdb_assert (type->kind =3D=3D TDESC_TYPE_FLAGS); + gdb_assert (type->kind =3D=3D TDESC_TYPE_FLAGS + || type->kind =3D=3D TDESC_TYPE_ENUM); f.name =3D xstrdup (flag_name); f.start =3D start; @@ -1664,6 +1722,27 @@ feature =3D tdesc_create_feature (result, \"%s\");\n= ", f->name); } break; + case TDESC_TYPE_STRUCT: + printf_unfiltered + (" type =3D tdesc_create_struct (feature, \"%s\");\n", + type->name); + for (ix3 =3D 0; + VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); + ix3++) + { + printf_unfiltered + (" field_type =3D tdesc_named_type (feature, \"%s\");\n", + f->type->name); + if (f->start =3D=3D -1 || f->end =3D=3D -1) + printf_unfiltered + (" tdesc_add_field (type, \"%s\", field_type);\n", + f->name); + else + printf_unfiltered + (" tdesc_add_bitfield (type, \"%s\", %d, %d, field_type);\n", + f->name, f->start, f->end); + } + break; case TDESC_TYPE_FLAGS: printf_unfiltered (" field_type =3D tdesc_create_flags (feature, \"%s\", %d);\n", @@ -1676,6 +1755,18 @@ feature =3D tdesc_create_feature (result, \"%s\");\n= ", (" tdesc_add_flag (field_type, %d, \"%s\");\n", flag->start, flag->name); break; + case TDESC_TYPE_ENUM: + printf_unfiltered + (" field_type =3D tdesc_create_enum (feature, \"%s\", %d);\n", + type->name, (int) type->u.f.size); + for (ix3 =3D 0; + VEC_iterate (tdesc_type_flag, type->u.f.flags, ix3, + flag); + ix3++) + printf_unfiltered + (" tdesc_add_flag (field_type, %d, \"%s\");\n", + flag->start, flag->name); + break; default: error (_("C output is not supported type \"%s\"."), type->name); } diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h index 5f0b7d5..810d88b 100644 --- a/gdb/target-descriptions.h +++ b/gdb/target-descriptions.h @@ -214,10 +214,13 @@ struct tdesc_type *tdesc_create_union (struct tdesc_feature *feature, struct tdesc_type *tdesc_create_flags (struct tdesc_feature *feature, const char *name, LONGEST size); +struct tdesc_type *tdesc_create_enum (struct tdesc_feature *feature, + const char *name, + LONGEST size); void tdesc_add_field (struct tdesc_type *type, const char *field_name, struct tdesc_type *field_type); void tdesc_add_bitfield (struct tdesc_type *type, const char *field_name, - int start, int end); + int start, int end, struct tdesc_type *field_type); void tdesc_add_flag (struct tdesc_type *type, int start, const char *flag_name); void tdesc_create_reg (struct tdesc_feature *feature, const char *name, diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c index 5073e7b..318554d 100644 --- a/gdb/xml-tdesc.c +++ b/gdb/xml-tdesc.c @@ -286,6 +286,24 @@ tdesc_start_flags (struct gdb_xml_parser *parser, data->current_type_is_flags =3D 1; } +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 =3D user_data; + char *id =3D xml_find_attribute (attributes, "id")->value; + int length =3D (int) * (ULONGEST *) + xml_find_attribute (attributes, "size")->value; + struct tdesc_type *type; + + type =3D tdesc_create_enum (data->current_feature, id, length); + + data->current_type =3D type; + data->current_type_size =3D 0; + data->current_type_is_flags =3D 1; +} + /* Handle the start of a element. Attach the field to the current struct or union. */ @@ -304,9 +322,15 @@ tdesc_start_field (struct gdb_xml_parser *parser, attr =3D xml_find_attribute (attributes, "type"); if (attr !=3D NULL) - field_type_id =3D attr->value; + { + field_type_id =3D attr->value; + field_type =3D tdesc_named_type (data->current_feature, field_type_i= d); + } else - field_type_id =3D NULL; + { + field_type_id =3D NULL; + field_type =3D NULL; + } attr =3D xml_find_attribute (attributes, "start"); if (attr !=3D NULL) @@ -320,26 +344,7 @@ tdesc_start_field (struct gdb_xml_parser *parser, else end =3D -1; - if (field_type_id !=3D 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 !=3D 0) - gdb_xml_error (parser, - _("Explicitly sized type can not " - "contain non-bitfield \"%s\""), - field_name); - - field_type =3D tdesc_named_type (data->current_feature, field_type_i= d); - if (field_type =3D=3D 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 !=3D -1 && end !=3D -1) + if (start !=3D -1 && end !=3D -1) { struct tdesc_type *t =3D data->current_type; @@ -371,9 +376,22 @@ tdesc_start_field (struct gdb_xml_parser *parser, gdb_xml_error (parser, _("Bitfield \"%s\" does not fit in struct")); - tdesc_add_bitfield (t, field_name, start, end); + tdesc_add_bitfield (t, field_name, start, end, field_type); } } + else if (field_type_id !=3D NULL) + { + if (data->current_type_is_flags) + gdb_xml_error (parser, _("Cannot add typed field \"%s\" to flags"), + field_name); + + if (field_type =3D=3D 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 positi= on"), field_name); @@ -444,6 +462,12 @@ static const struct gdb_xml_attribute flags_attributes[] =3D { { NULL, GDB_XML_AF_NONE, NULL, NULL } }; +static const struct gdb_xml_attribute enum_attributes[] =3D { + { "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[] =3D { { "id", GDB_XML_AF_NONE, NULL, NULL }, { "type", GDB_XML_AF_NONE, NULL, NULL }, @@ -469,6 +493,9 @@ static const struct gdb_xml_element feature_children[] = =3D { { "flags", flags_attributes, struct_union_children, GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, tdesc_start_flags, NULL }, + { "enum", enum_attributes, struct_union_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 },