mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 17:18:24 +08:00
Handle bit offset and bit size in base types
PR symtab/25470 points out that the Zig programming language allows integers of various bit sizes (including zero), not just sizes that are a multiple of 8. This is supported in DWARF by applying both a byte size and a DW_AT_bit_size. This patch adds support for this feature to integer and boolean types. Other base types are not handled -- for floating-point types, this didn't seem to make sense, and for character types I didn't see much need. (These can be added later if desired.) I've also added support for DW_AT_data_bit_offset at the same time. I don't know whether the Zig compiler requires this, but it was described in the same section in the DWARF standard and was easy to add. A new test case is supplied, using the DWARF assembler. gdb/ChangeLog 2020-09-23 Tom Tromey <tom@tromey.com> PR symtab/25470: * value.c (unpack_long, pack_long, pack_unsigned_long): Handle bit offset and bit size. * printcmd.c (print_scalar_formatted): Handle zero-length integer. (print_scalar_formatted): Use bit_size_differs_p. * gdbtypes.h (enum type_specific_kind) <TYPE_SPECIFIC_INT>: New constant. (union type_specific): <int_stuff>: New member. (struct type) <bit_size_differs_p, bit_size, bit_offset>: New methods. * gdbtypes.c (init_integer_type, init_boolean_type): Initialize TYPE_SPECIFIC_FIELD. (recursive_dump_type, copy_type_recursive): Update. * dwarf2/read.c (read_base_type): Handle DW_AT_bit_size and DW_AT_data_bit_offset. gdb/testsuite/ChangeLog 2020-09-23 Tom Tromey <tom@tromey.com> * gdb.dwarf2/intbits.exp: New file. * gdb.dwarf2/intbits.c: New file.
This commit is contained in:
@ -599,7 +599,8 @@ enum type_specific_kind
|
||||
TYPE_SPECIFIC_FLOATFORMAT,
|
||||
/* Note: This is used by TYPE_CODE_FUNC and TYPE_CODE_METHOD. */
|
||||
TYPE_SPECIFIC_FUNC,
|
||||
TYPE_SPECIFIC_SELF_TYPE
|
||||
TYPE_SPECIFIC_SELF_TYPE,
|
||||
TYPE_SPECIFIC_INT
|
||||
};
|
||||
|
||||
union type_owner
|
||||
@ -764,6 +765,21 @@ union type_specific
|
||||
is a member of. */
|
||||
|
||||
struct type *self_type;
|
||||
|
||||
/* * An integer-like scalar type may be stored in just part of its
|
||||
enclosing storage bytes. This structure describes this
|
||||
situation. */
|
||||
struct
|
||||
{
|
||||
/* * The bit size of the integer. This can be 0. For integers
|
||||
that fill their storage (the ordinary case), this field holds
|
||||
the byte size times 8. */
|
||||
unsigned short bit_size;
|
||||
/* * The bit offset of the integer. This is ordinarily 0, and can
|
||||
only be non-zero if the bit size is less than the storage
|
||||
size. */
|
||||
unsigned short bit_offset;
|
||||
} int_stuff;
|
||||
};
|
||||
|
||||
/* * Main structure representing a type in GDB.
|
||||
@ -1182,6 +1198,31 @@ struct type
|
||||
/* * Remove dynamic property of kind KIND from this type, if it exists. */
|
||||
void remove_dyn_prop (dynamic_prop_node_kind kind);
|
||||
|
||||
/* * Return true if this is an integer type whose logical (bit) size
|
||||
differs from its storage size; false otherwise. Always return
|
||||
false for non-integer (i.e., non-TYPE_SPECIFIC_INT) types. */
|
||||
bool bit_size_differs_p () const
|
||||
{
|
||||
return (main_type->type_specific_field == TYPE_SPECIFIC_INT
|
||||
&& main_type->type_specific.int_stuff.bit_size != 8 * length);
|
||||
}
|
||||
|
||||
/* * Return the logical (bit) size for this integer type. Only
|
||||
valid for integer (TYPE_SPECIFIC_INT) types. */
|
||||
unsigned short bit_size () const
|
||||
{
|
||||
gdb_assert (main_type->type_specific_field == TYPE_SPECIFIC_INT);
|
||||
return main_type->type_specific.int_stuff.bit_size;
|
||||
}
|
||||
|
||||
/* * Return the bit offset for this integer type. Only valid for
|
||||
integer (TYPE_SPECIFIC_INT) types. */
|
||||
unsigned short bit_offset () const
|
||||
{
|
||||
gdb_assert (main_type->type_specific_field == TYPE_SPECIFIC_INT);
|
||||
return main_type->type_specific.int_stuff.bit_offset;
|
||||
}
|
||||
|
||||
/* * Type that is a pointer to this type.
|
||||
NULL if no such pointer-to type is known yet.
|
||||
The debugger may add the address of such a type
|
||||
|
Reference in New Issue
Block a user