mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-02 04:27:46 +08:00
* gdbtypes.c (append_composite_type_field_raw): New.
(append_composite_type_field_aligned): Use the new function. * gdbtypes.h (append_composite_type_field_raw): Declare. * target-descriptions.c (struct tdesc_type_field): Add start and end. (struct tdesc_type_flag): New type. (struct tdesc_type): Add TDESC_TYPE_STRUCT and TDESC_TYPE_FLAGS to kind. Add size to u.u. Add u.f for flags. (tdesc_gdb_type): Handle TDESC_TYPE_STRUCT and TDESC_TYPE_FLAGS. (tdesc_free_type): Likewise. (tdesc_create_struct, tdesc_set_struct_size, tdesc_create_flags): New. (tdesc_add_field): Handle TDESC_TYPE_STRUCT. (tdesc_add_bitfield, tdesc_add_flag): New. * target-descriptions.h (tdesc_create_struct, tdesc_set_struct_size) (tdesc_create_flags, tdesc_add_bitfield, tdesc_add_flag): Declare. * xml-tdesc.c (struct tdesc_parsing_data): Rename current_union to current_type. Add current_type_size and current_type_is_flags. (tdesc_start_union): Clear the new fields. (tdesc_start_struct, tdesc_start_flags): New. (tdesc_start_field): Handle struct fields, including bitfields. (field_attributes): Make type optional. Add start and end. (union_children): Rename to struct_union_children. (union_attributes): Rename to struct_union_attributes. Add optional size. (flags_attributes): New. (feature_children): Add struct and flags. * features/gdb-target.dtd: Add flags and struct to features. Make field type optional. Add field start and end. doc/ * gdb.texinfo (Types): Describe <struct> and <flags>. testsuite/ * gdb.xml/extra-regs.xml: Add struct1, struct2, and flags types. Add structreg, bitfields, and flags registers. * gdb.xml/tdesc-regs.exp: Test structreg and bitfields registers.
This commit is contained in:
@ -90,9 +90,17 @@ typedef struct tdesc_type_field
|
||||
{
|
||||
char *name;
|
||||
struct tdesc_type *type;
|
||||
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);
|
||||
|
||||
typedef struct tdesc_type
|
||||
{
|
||||
/* The name of this type. */
|
||||
@ -123,7 +131,9 @@ typedef struct tdesc_type
|
||||
|
||||
/* Types defined by a target feature. */
|
||||
TDESC_TYPE_VECTOR,
|
||||
TDESC_TYPE_UNION
|
||||
TDESC_TYPE_STRUCT,
|
||||
TDESC_TYPE_UNION,
|
||||
TDESC_TYPE_FLAGS
|
||||
} kind;
|
||||
|
||||
/* Kind-specific data. */
|
||||
@ -136,11 +146,19 @@ typedef struct tdesc_type
|
||||
int count;
|
||||
} v;
|
||||
|
||||
/* Union type. */
|
||||
/* Struct or union type. */
|
||||
struct
|
||||
{
|
||||
VEC(tdesc_type_field) *fields;
|
||||
LONGEST size;
|
||||
} u;
|
||||
|
||||
/* Flags type. */
|
||||
struct
|
||||
{
|
||||
VEC(tdesc_type_flag) *flags;
|
||||
LONGEST size;
|
||||
} f;
|
||||
} u;
|
||||
} *tdesc_type_p;
|
||||
DEF_VEC_P(tdesc_type_p);
|
||||
@ -652,6 +670,66 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type)
|
||||
return type;
|
||||
}
|
||||
|
||||
case TDESC_TYPE_STRUCT:
|
||||
{
|
||||
struct type *type, *field_type;
|
||||
struct tdesc_type_field *f;
|
||||
int ix;
|
||||
|
||||
type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
|
||||
TYPE_NAME (type) = xstrdup (tdesc_type->name);
|
||||
TYPE_TAG_NAME (type) = TYPE_NAME (type);
|
||||
|
||||
for (ix = 0;
|
||||
VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
|
||||
ix++)
|
||||
{
|
||||
if (f->type == 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 != 0);
|
||||
if (tdesc_type->u.u.size > 4)
|
||||
field_type = builtin_type (gdbarch)->builtin_uint64;
|
||||
else
|
||||
field_type = builtin_type (gdbarch)->builtin_uint32;
|
||||
|
||||
fld = 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 = f->end - f->start + 1;
|
||||
total_size = tdesc_type->u.u.size * TARGET_CHAR_BIT;
|
||||
if (gdbarch_bits_big_endian (gdbarch))
|
||||
FIELD_BITPOS (fld[0]) = total_size - f->start - bitsize;
|
||||
else
|
||||
FIELD_BITPOS (fld[0]) = f->start;
|
||||
FIELD_BITSIZE (fld[0]) = bitsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
field_type = tdesc_gdb_type (gdbarch, f->type);
|
||||
append_composite_type_field (type, xstrdup (f->name),
|
||||
field_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (tdesc_type->u.u.size != 0)
|
||||
TYPE_LENGTH (type) = tdesc_type->u.u.size;
|
||||
return type;
|
||||
}
|
||||
|
||||
case TDESC_TYPE_UNION:
|
||||
{
|
||||
struct type *type, *field_type;
|
||||
@ -668,12 +746,30 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type)
|
||||
field_type = tdesc_gdb_type (gdbarch, f->type);
|
||||
append_composite_type_field (type, xstrdup (f->name), field_type);
|
||||
|
||||
/* If any of the children of this union are vectors, flag the
|
||||
/* If any of the children of a union are vectors, flag the
|
||||
union as a vector also. This allows e.g. a union of two
|
||||
vector types to show up automatically in "info vector". */
|
||||
if (TYPE_VECTOR (field_type))
|
||||
TYPE_VECTOR (type) = 1;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
case TDESC_TYPE_FLAGS:
|
||||
{
|
||||
struct type *type, *field_type;
|
||||
struct tdesc_type_flag *f;
|
||||
int ix;
|
||||
|
||||
type = arch_flags_type (gdbarch, xstrdup (tdesc_type->name),
|
||||
tdesc_type->u.f.size);
|
||||
for (ix = 0;
|
||||
VEC_iterate (tdesc_type_flag, tdesc_type->u.f.flags, 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);
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -1161,6 +1257,7 @@ tdesc_free_type (struct tdesc_type *type)
|
||||
|
||||
switch (type->kind)
|
||||
{
|
||||
case TDESC_TYPE_STRUCT:
|
||||
case TDESC_TYPE_UNION:
|
||||
{
|
||||
struct tdesc_type_field *f;
|
||||
@ -1175,6 +1272,20 @@ 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;
|
||||
}
|
||||
@ -1198,6 +1309,29 @@ tdesc_create_vector (struct tdesc_feature *feature, const char *name,
|
||||
return type;
|
||||
}
|
||||
|
||||
struct tdesc_type *
|
||||
tdesc_create_struct (struct tdesc_feature *feature, const char *name)
|
||||
{
|
||||
struct tdesc_type *type = XZALLOC (struct tdesc_type);
|
||||
|
||||
type->name = xstrdup (name);
|
||||
type->kind = TDESC_TYPE_STRUCT;
|
||||
|
||||
VEC_safe_push (tdesc_type_p, feature->types, type);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Set the total length of TYPE. Structs which contain bitfields may
|
||||
omit the reserved bits, so the end of the last field may not
|
||||
suffice. */
|
||||
|
||||
void
|
||||
tdesc_set_struct_size (struct tdesc_type *type, LONGEST size)
|
||||
{
|
||||
gdb_assert (type->kind == TDESC_TYPE_STRUCT);
|
||||
type->u.u.size = size;
|
||||
}
|
||||
|
||||
struct tdesc_type *
|
||||
tdesc_create_union (struct tdesc_feature *feature, const char *name)
|
||||
{
|
||||
@ -1210,13 +1344,32 @@ tdesc_create_union (struct tdesc_feature *feature, const char *name)
|
||||
return type;
|
||||
}
|
||||
|
||||
struct tdesc_type *
|
||||
tdesc_create_flags (struct tdesc_feature *feature, const char *name,
|
||||
LONGEST size)
|
||||
{
|
||||
struct tdesc_type *type = XZALLOC (struct tdesc_type);
|
||||
|
||||
type->name = xstrdup (name);
|
||||
type->kind = TDESC_TYPE_FLAGS;
|
||||
type->u.f.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). */
|
||||
|
||||
void
|
||||
tdesc_add_field (struct tdesc_type *type, const char *field_name,
|
||||
struct tdesc_type *field_type)
|
||||
{
|
||||
struct tdesc_type_field f = { 0 };
|
||||
|
||||
gdb_assert (type->kind == TDESC_TYPE_UNION);
|
||||
gdb_assert (type->kind == TDESC_TYPE_UNION
|
||||
|| type->kind == TDESC_TYPE_STRUCT);
|
||||
|
||||
f.name = xstrdup (field_name);
|
||||
f.type = field_type;
|
||||
@ -1224,6 +1377,37 @@ tdesc_add_field (struct tdesc_type *type, const char *field_name,
|
||||
VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
|
||||
}
|
||||
|
||||
/* Add a new bitfield. */
|
||||
|
||||
void
|
||||
tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
|
||||
int start, int end)
|
||||
{
|
||||
struct tdesc_type_field f = { 0 };
|
||||
|
||||
gdb_assert (type->kind == TDESC_TYPE_STRUCT);
|
||||
|
||||
f.name = xstrdup (field_name);
|
||||
f.start = start;
|
||||
f.end = end;
|
||||
|
||||
VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
|
||||
}
|
||||
|
||||
void
|
||||
tdesc_add_flag (struct tdesc_type *type, int start,
|
||||
const char *flag_name)
|
||||
{
|
||||
struct tdesc_type_flag f = { 0 };
|
||||
|
||||
gdb_assert (type->kind == TDESC_TYPE_FLAGS);
|
||||
|
||||
f.name = xstrdup (flag_name);
|
||||
f.start = start;
|
||||
|
||||
VEC_safe_push (tdesc_type_flag, type->u.f.flags, &f);
|
||||
}
|
||||
|
||||
static void
|
||||
tdesc_free_feature (struct tdesc_feature *feature)
|
||||
{
|
||||
|
Reference in New Issue
Block a user