mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-28 10:00:51 +00:00
Extend flags to support multibit and enum bitfields.
gdb/ChangeLog: Extend flags to support multibit and enum bitfields. NEWS: Document new features. * c-typeprint.c (c_type_print_varspec_prefix): Handle TYPE_CODE_FLAGS. (c_type_print_varspec_suffix, c_type_print_base): Ditto. * gdbtypes.c (arch_flags_type): Don't assume all fields are one bit. (append_flags_type_field): New function. (append_flags_type_flag): Call it. * gdbtypes.h (append_flags_type_field): Declare. * target-descriptions.c (struct tdesc_type_flag): Delete. (enum tdesc_type_kind) <TDESC_TYPE_BOOL>: New enum value. (enum tdesc_type_kind) <TDESC_TYPE_ENUM>: Ditto. (struct tdesc_type) <u.f>: Delete. (tdesc_predefined_types): Add "bool". (tdesc_predefined_type): New function. (tdesc_gdb_type): Handle TDESC_TYPE_BOOL, TDESC_TYPE_ENUM. Update TDESC_TYPE_FLAGS support. (tdesc_free_type): Handle TDESC_TYPE_ENUM. Update TDESC_TYPE_FLAGS. (tdesc_create_flags): Update. (tdesc_create_enum): New function. (tdesc_add_field): Initialize start,end to -1. (tdesc_add_typed_bitfield): New function. (tdesc_add_bitfield): Call it. (tdesc_add_flag): Allow TDESC_TYPE_STRUCT. Update. (tdesc_add_enum_value): New function. (maint_print_c_tdesc_cmd): Fold TDESC_TYPE_FLAGS support into TDESC_TYPE_STRUCT. Handle TDESC_TYPE_ENUM. * target-descriptions.h (tdesc_create_enum): Declare. (tdesc_add_typed_bitfield, tdesc_add_enum_value): Declare. * valprint.c (generic_val_print_enum_1): New function. (generic_val_print_enum): Call it. (val_print_type_code_flags): Make static. Handle multibit bitfields and enum bitfields. * valprint.h (val_print_type_code_flags): Delete. * xml-tdesc.c (struct tdesc_parsing_data) <current_type_is_flags>: Delete. All uses removed. (tdesc_start_enum): New function. (tdesc_start_field): Handle multibit and enum bitfields. (tdesc_start_enum_value): New function. (enum_value_attributes, enum_children, enum_attributes): New static globals. (feature_children): Add "enum". * features/gdb-target.dtd (enum, evalue): New elements. gdb/doc/ChangeLog: * gdb.texinfo (Target Descriptions): New menu item "Enum Target Types". (Target Description Format): Mention enum types. Update docs on flags types. (Predefined Target Types): Add "bool". (Enum Target Types): New node. gdb/testsuite/ChangeLog: * gdb.xml/extra-regs.xml: Add enum, mixed_flags values. * gdb.xml/tdesc-regs.exp (load_description): New arg xml_file. All callers updated. Add tests for enums, mixed flags register.
This commit is contained in:
@@ -98,6 +98,10 @@ static void set_output_radix (char *, int, struct cmd_list_element *);
|
||||
|
||||
static void set_output_radix_1 (int, unsigned);
|
||||
|
||||
static void val_print_type_code_flags (struct type *type,
|
||||
const gdb_byte *valaddr,
|
||||
struct ui_file *stream);
|
||||
|
||||
void _initialize_valprint (void);
|
||||
|
||||
#define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */
|
||||
@@ -526,28 +530,17 @@ generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
|
||||
}
|
||||
}
|
||||
|
||||
/* generic_val_print helper for TYPE_CODE_ENUM. */
|
||||
/* Helper function for generic_val_print_enum.
|
||||
This is also used to print enums in TYPE_CODE_FLAGS values. */
|
||||
|
||||
static void
|
||||
generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
|
||||
int embedded_offset, struct ui_file *stream,
|
||||
const struct value *original_value,
|
||||
const struct value_print_options *options)
|
||||
generic_val_print_enum_1 (struct type *type, LONGEST val,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int len;
|
||||
LONGEST val;
|
||||
struct gdbarch *gdbarch = get_type_arch (type);
|
||||
int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
|
||||
|
||||
if (options->format)
|
||||
{
|
||||
val_print_scalar_formatted (type, valaddr, embedded_offset,
|
||||
original_value, options, 0, stream);
|
||||
return;
|
||||
}
|
||||
len = TYPE_NFIELDS (type);
|
||||
val = unpack_long (type, valaddr + embedded_offset * unit_size);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
QUIT;
|
||||
@@ -597,6 +590,29 @@ generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
|
||||
print_longest (stream, 'd', 0, val);
|
||||
}
|
||||
|
||||
/* generic_val_print helper for TYPE_CODE_ENUM. */
|
||||
|
||||
static void
|
||||
generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
|
||||
int embedded_offset, struct ui_file *stream,
|
||||
const struct value *original_value,
|
||||
const struct value_print_options *options)
|
||||
{
|
||||
LONGEST val;
|
||||
struct gdbarch *gdbarch = get_type_arch (type);
|
||||
int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
|
||||
|
||||
if (options->format)
|
||||
{
|
||||
val_print_scalar_formatted (type, valaddr, embedded_offset,
|
||||
original_value, options, 0, stream);
|
||||
return;
|
||||
}
|
||||
val = unpack_long (type, valaddr + embedded_offset * unit_size);
|
||||
|
||||
generic_val_print_enum_1 (type, val, stream);
|
||||
}
|
||||
|
||||
/* generic_val_print helper for TYPE_CODE_FLAGS. */
|
||||
|
||||
static void
|
||||
@@ -1162,26 +1178,51 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
ULONGEST val = unpack_long (type, valaddr);
|
||||
int bitpos, nfields = TYPE_NFIELDS (type);
|
||||
int field, nfields = TYPE_NFIELDS (type);
|
||||
struct gdbarch *gdbarch = get_type_arch (type);
|
||||
struct type *bool_type = builtin_type (gdbarch)->builtin_bool;
|
||||
|
||||
fputs_filtered ("[ ", stream);
|
||||
for (bitpos = 0; bitpos < nfields; bitpos++)
|
||||
fputs_filtered ("[", stream);
|
||||
for (field = 0; field < nfields; field++)
|
||||
{
|
||||
if (TYPE_FIELD_BITPOS (type, bitpos) != -1
|
||||
&& (val & ((ULONGEST)1 << bitpos)))
|
||||
if (TYPE_FIELD_NAME (type, field)[0] != '\0')
|
||||
{
|
||||
if (TYPE_FIELD_NAME (type, bitpos))
|
||||
fprintf_filtered (stream, "%s ", TYPE_FIELD_NAME (type, bitpos));
|
||||
struct type *field_type = TYPE_FIELD_TYPE (type, field);
|
||||
|
||||
if (field_type == bool_type
|
||||
/* We require boolean types here to be one bit wide. This is a
|
||||
problematic place to notify the user of an internal error
|
||||
though. Instead just fall through and print the field as an
|
||||
int. */
|
||||
&& TYPE_FIELD_BITSIZE (type, field) == 1)
|
||||
{
|
||||
if (val & ((ULONGEST)1 << TYPE_FIELD_BITPOS (type, field)))
|
||||
fprintf_filtered (stream, " %s",
|
||||
TYPE_FIELD_NAME (type, field));
|
||||
}
|
||||
else
|
||||
fprintf_filtered (stream, "#%d ", bitpos);
|
||||
{
|
||||
unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
|
||||
ULONGEST field_val
|
||||
= val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1);
|
||||
|
||||
if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT)
|
||||
field_val &= ((ULONGEST) 1 << field_len) - 1;
|
||||
fprintf_filtered (stream, " %s=",
|
||||
TYPE_FIELD_NAME (type, field));
|
||||
if (TYPE_CODE (field_type) == TYPE_CODE_ENUM)
|
||||
generic_val_print_enum_1 (field_type, field_val, stream);
|
||||
else
|
||||
print_longest (stream, 'd', 0, field_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
fputs_filtered ("]", stream);
|
||||
fputs_filtered (" ]", stream);
|
||||
}
|
||||
|
||||
/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
|
||||
|
||||
Reference in New Issue
Block a user