diff options
Diffstat (limited to 'gdb/target-descriptions.c')
-rw-r--r-- | gdb/target-descriptions.c | 302 |
1 files changed, 219 insertions, 83 deletions
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index ac6e3a23483..40f04786b08 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -90,20 +90,17 @@ typedef struct tdesc_type_field { char *name; struct tdesc_type *type; + /* For non-enum-values, either both are -1 (non-bitfield), or both are + not -1 (bitfield). For enum values, start is the value (which could be + -1), end is -1. */ int start, end; } tdesc_type_field; DEF_VEC_O(tdesc_type_field); -typedef struct tdesc_type_flag -{ - char *name; - int start; -} tdesc_type_flag; -DEF_VEC_O(tdesc_type_flag); - enum tdesc_type_kind { /* Predefined types. */ + TDESC_TYPE_BOOL, TDESC_TYPE_INT8, TDESC_TYPE_INT16, TDESC_TYPE_INT32, @@ -125,7 +122,8 @@ enum tdesc_type_kind TDESC_TYPE_VECTOR, TDESC_TYPE_STRUCT, TDESC_TYPE_UNION, - TDESC_TYPE_FLAGS + TDESC_TYPE_FLAGS, + TDESC_TYPE_ENUM }; typedef struct tdesc_type @@ -146,19 +144,12 @@ typedef struct tdesc_type int count; } v; - /* Struct or union type. */ + /* Struct, union, flags, or enum type. */ struct { VEC(tdesc_type_field) *fields; int size; } u; - - /* Flags type. */ - struct - { - VEC(tdesc_type_flag) *flags; - int size; - } f; } u; } *tdesc_type_p; DEF_VEC_P(tdesc_type_p); @@ -527,6 +518,7 @@ tdesc_feature_name (const struct tdesc_feature *feature) /* Predefined types. */ static struct tdesc_type tdesc_predefined_types[] = { + { "bool", TDESC_TYPE_BOOL }, { "int8", TDESC_TYPE_INT8 }, { "int16", TDESC_TYPE_INT16 }, { "int32", TDESC_TYPE_INT32 }, @@ -545,6 +537,21 @@ static struct tdesc_type tdesc_predefined_types[] = { "i387_ext", TDESC_TYPE_I387_EXT } }; +/* Lookup a predefined type. */ + +static struct tdesc_type * +tdesc_predefined_type (enum tdesc_type_kind kind) +{ + int ix; + struct tdesc_type *type; + + for (ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++) + if (tdesc_predefined_types[ix].kind == kind) + return &tdesc_predefined_types[ix]; + + gdb_assert_not_reached ("bad predefined tdesc type"); +} + /* Return the type associated with ID in the context of FEATURE, or NULL if none. */ @@ -602,6 +609,9 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type) switch (tdesc_type->kind) { /* Predefined types. */ + case TDESC_TYPE_BOOL: + return builtin_type (gdbarch)->builtin_bool; + case TDESC_TYPE_INT8: return builtin_type (gdbarch)->builtin_int8; @@ -690,17 +700,18 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type) VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f); ix++) { - if (f->type == NULL) + if (f->start != -1 && f->end != -1) { /* Bitfield. */ struct field *fld; struct type *field_type; int bitsize, total_size; - /* This invariant should be preserved while creating - types. */ + /* This invariant should be preserved while creating types. */ gdb_assert (tdesc_type->u.u.size != 0); - if (tdesc_type->u.u.size > 4) + if (f->type != NULL) + field_type = tdesc_gdb_type (gdbarch, f->type); + else if (tdesc_type->u.u.size > 4) field_type = builtin_type (gdbarch)->builtin_uint64; else field_type = builtin_type (gdbarch)->builtin_uint32; @@ -725,6 +736,7 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type) } else { + gdb_assert (f->start == -1 && f->end == -1); field_type = tdesc_gdb_type (gdbarch, f->type); append_composite_type_field (type, xstrdup (f->name), field_type); @@ -763,19 +775,45 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type) case TDESC_TYPE_FLAGS: { - struct tdesc_type_flag *f; + struct tdesc_type_field *f; int ix; type = arch_flags_type (gdbarch, tdesc_type->name, - tdesc_type->u.f.size); + tdesc_type->u.u.size); + for (ix = 0; + VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f); + ix++) + { + struct type *field_type; + int bitsize = f->end - f->start + 1; + + gdb_assert (f->type != NULL); + field_type = tdesc_gdb_type (gdbarch, f->type); + append_flags_type_field (type, f->start, bitsize, + field_type, f->name); + } + + return type; + } + + case TDESC_TYPE_ENUM: + { + struct tdesc_type_field *f; + int ix; + + type = arch_type (gdbarch, TYPE_CODE_ENUM, + tdesc_type->u.u.size, tdesc_type->name); + TYPE_UNSIGNED (type) = 1; for (ix = 0; - VEC_iterate (tdesc_type_flag, tdesc_type->u.f.flags, ix, f); + VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f); ix++) - /* Note that contrary to the function name, this call will - just set the properties of an already-allocated - field. */ - append_flags_type_flag (type, f->start, - *f->name ? f->name : NULL); + { + struct field *fld + = append_composite_type_field_raw (type, xstrdup (f->name), + NULL); + + SET_FIELD_BITPOS (fld[0], f->start); + } return type; } @@ -1266,6 +1304,11 @@ tdesc_create_reg (struct tdesc_feature *feature, const char *name, VEC_safe_push (tdesc_reg_p, feature->registers, reg); } +/* Subroutine of tdesc_free_feature to simplify it. + Note: We do not want to free any referenced types here (e.g., types of + fields of a struct). All types of a feature are recorded in + feature->types and are freed that way. */ + static void tdesc_free_type (struct tdesc_type *type) { @@ -1273,6 +1316,8 @@ tdesc_free_type (struct tdesc_type *type) { case TDESC_TYPE_STRUCT: case TDESC_TYPE_UNION: + case TDESC_TYPE_FLAGS: + case TDESC_TYPE_ENUM: { struct tdesc_type_field *f; int ix; @@ -1286,20 +1331,6 @@ tdesc_free_type (struct tdesc_type *type) } break; - case TDESC_TYPE_FLAGS: - { - struct tdesc_type_flag *f; - int ix; - - for (ix = 0; - VEC_iterate (tdesc_type_flag, type->u.f.flags, ix, f); - ix++) - xfree (f->name); - - VEC_free (tdesc_type_flag, type->u.f.flags); - } - break; - default: break; } @@ -1369,15 +1400,29 @@ tdesc_create_flags (struct tdesc_feature *feature, const char *name, type->name = xstrdup (name); type->kind = TDESC_TYPE_FLAGS; - type->u.f.size = size; + type->u.u.size = 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). */ +struct tdesc_type * +tdesc_create_enum (struct tdesc_feature *feature, const char *name, + int size) +{ + struct tdesc_type *type = XCNEW (struct tdesc_type); + + gdb_assert (size > 0); + + type->name = xstrdup (name); + type->kind = TDESC_TYPE_ENUM; + type->u.u.size = size; + + VEC_safe_push (tdesc_type_p, feature->types, type); + return type; +} + +/* Add a new field to TYPE. */ void tdesc_add_field (struct tdesc_type *type, const char *field_name, @@ -1390,39 +1435,88 @@ tdesc_add_field (struct tdesc_type *type, const char *field_name, f.name = xstrdup (field_name); f.type = field_type; + /* Initialize these values so we know this is not a bit-field + when we print-c-tdesc. */ + f.start = -1; + f.end = -1; VEC_safe_push (tdesc_type_field, type->u.u.fields, &f); } -/* Add a new bitfield. */ +/* Add a new typed bitfield to TYPE. */ void -tdesc_add_bitfield (struct tdesc_type *type, const char *field_name, - int start, int end) +tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name, + int start, int end, struct tdesc_type *field_type) { struct tdesc_type_field f = { 0 }; - gdb_assert (type->kind == TDESC_TYPE_STRUCT); + gdb_assert (type->kind == TDESC_TYPE_STRUCT + || type->kind == TDESC_TYPE_FLAGS); + gdb_assert (start >= 0 && end >= start); f.name = xstrdup (field_name); f.start = start; f.end = end; + f.type = field_type; VEC_safe_push (tdesc_type_field, type->u.u.fields, &f); } +/* Add a new untyped bitfield to TYPE. + Untyped bitfields become either uint32 or uint64 depending on the size + of the underlying type. */ + +void +tdesc_add_bitfield (struct tdesc_type *type, const char *field_name, + int start, int end) +{ + struct tdesc_type *field_type; + + gdb_assert (start >= 0 && end >= start); + + if (type->u.u.size > 4) + field_type = tdesc_predefined_type (TDESC_TYPE_UINT64); + else + field_type = tdesc_predefined_type (TDESC_TYPE_UINT32); + + tdesc_add_typed_bitfield (type, field_name, start, end, field_type); +} + +/* A flag is just a typed(bool) single-bit bitfield. + This function is kept to minimize changes in generated files. */ + void tdesc_add_flag (struct tdesc_type *type, int start, const char *flag_name) { - struct tdesc_type_flag f = { 0 }; + struct tdesc_type_field f = { 0 }; - gdb_assert (type->kind == TDESC_TYPE_FLAGS); + gdb_assert (type->kind == TDESC_TYPE_FLAGS + || type->kind == TDESC_TYPE_STRUCT); f.name = xstrdup (flag_name); f.start = start; + f.end = start; + f.type = tdesc_predefined_type (TDESC_TYPE_BOOL); - VEC_safe_push (tdesc_type_flag, type->u.f.flags, &f); + VEC_safe_push (tdesc_type_field, type->u.u.fields, &f); +} + +void +tdesc_add_enum_value (struct tdesc_type *type, int value, + const char *name) +{ + struct tdesc_type_field f = { 0 }; + + gdb_assert (type->kind == TDESC_TYPE_ENUM); + + f.name = xstrdup (name); + f.start = value; + f.end = -1; + f.type = tdesc_predefined_type (TDESC_TYPE_INT32); + + VEC_safe_push (tdesc_type_field, type->u.u.fields, &f); } static void @@ -1623,7 +1717,6 @@ maint_print_c_tdesc_cmd (char *args, int from_tty) struct tdesc_reg *reg; struct tdesc_type *type; struct tdesc_type_field *f; - struct tdesc_type_flag *flag; int ix, ix2, ix3; int printed_field_type = 0; @@ -1686,11 +1779,11 @@ maint_print_c_tdesc_cmd (char *args, int from_tty) printed_field_type = 1; } - if (((type->kind == TDESC_TYPE_UNION - || type->kind == TDESC_TYPE_STRUCT) - && VEC_length (tdesc_type_field, type->u.u.fields) > 0) - || (type->kind == TDESC_TYPE_FLAGS - && VEC_length (tdesc_type_flag, type->u.f.flags) > 0)) + if ((type->kind == TDESC_TYPE_UNION + || type->kind == TDESC_TYPE_STRUCT + || type->kind == TDESC_TYPE_FLAGS + || type->kind == TDESC_TYPE_ENUM) + && VEC_length (tdesc_type_field, type->u.u.fields) > 0) { printf_unfiltered (" struct tdesc_type *type;\n"); printed_desc_type = 1; @@ -1761,33 +1854,77 @@ feature = tdesc_create_feature (result, \"%s\");\n", type->name, type->u.v.count); break; case TDESC_TYPE_STRUCT: - printf_unfiltered - (" type = tdesc_create_struct (feature, \"%s\");\n", - type->name); - if (type->u.u.size != 0) - printf_unfiltered - (" tdesc_set_struct_size (type, %s);\n", - plongest (type->u.u.size)); + case TDESC_TYPE_FLAGS: + if (type->kind == TDESC_TYPE_STRUCT) + { + printf_unfiltered + (" type = tdesc_create_struct (feature, \"%s\");\n", + type->name); + if (type->u.u.size != 0) + printf_unfiltered + (" tdesc_set_struct_size (type, %d);\n", + type->u.u.size); + } + else + { + printf_unfiltered + (" type = tdesc_create_flags (feature, \"%s\", %d);\n", + type->name, type->u.u.size); + } for (ix3 = 0; VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); ix3++) { - /* Going first for implicitly sized types, else part handles - bitfields. As reported on xml-tdesc.c implicitly sized types - cannot contain a bitfield. */ - if (f->type != NULL) + const char *type_name; + + gdb_assert (f->type != NULL); + type_name = f->type->name; + + /* To minimize changes to generated files, don't emit type + info for fields that have defaulted types. */ + if (f->start != -1) + { + gdb_assert (f->end != -1); + if (f->type->kind == TDESC_TYPE_BOOL) + { + gdb_assert (f->start == f->end); + printf_unfiltered + (" tdesc_add_flag (type, %d, \"%s\");\n", + f->start, f->name); + } + else if ((type->u.u.size == 4 + && f->type->kind == TDESC_TYPE_UINT32) + || (type->u.u.size == 8 + && f->type->kind == TDESC_TYPE_UINT64)) + { + printf_unfiltered + (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n", + f->name, f->start, f->end); + } + else + { + printf_unfiltered + (" field_type = tdesc_named_type (feature," + " \"%s\");\n", + type_name); + printf_unfiltered + (" tdesc_add_typed_bitfield (type, \"%s\"," + " %d, %d, field_type);\n", + f->name, f->start, f->end); + } + } + else /* Not a bitfield. */ { + gdb_assert (f->end == -1); + gdb_assert (type->kind == TDESC_TYPE_STRUCT); printf_unfiltered - (" field_type = tdesc_named_type (feature, \"%s\");\n", - f->type->name); + (" field_type = tdesc_named_type (feature," + " \"%s\");\n", + type_name); printf_unfiltered (" tdesc_add_field (type, \"%s\", field_type);\n", f->name); } - else - printf_unfiltered - (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n", - f->name, f->start, f->end); } break; case TDESC_TYPE_UNION: @@ -1806,17 +1943,16 @@ feature = tdesc_create_feature (result, \"%s\");\n", f->name); } break; - case TDESC_TYPE_FLAGS: + case TDESC_TYPE_ENUM: printf_unfiltered - (" type = tdesc_create_flags (feature, \"%s\", %d);\n", - type->name, (int) type->u.f.size); + (" type = tdesc_create_enum (feature, \"%s\", %d);\n", + type->name, type->u.u.size); for (ix3 = 0; - VEC_iterate (tdesc_type_flag, type->u.f.flags, ix3, - flag); + VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); ix3++) printf_unfiltered - (" tdesc_add_flag (type, %d, \"%s\");\n", - flag->start, flag->name); + (" tdesc_add_enum_value (type, %d, \"%s\");\n", + f->start, f->name); break; default: error (_("C output is not supported type \"%s\"."), type->name); |