DWARF: Add array DW_AT_bit_stride and DW_AT_byte_stride support

Consider the following declarations in Ada...

   type Item is range -32 .. 31;
   for Item'Size use 6;

   type Table is array (Natural range 0 .. 4) of Item;
   pragma Pack (Table);

... which declare a packed array whose elements are 6 bits long.
The debugger currently does not notice that the array is packed,
and thus prints values of this type incorrectly. This can be seen
in the "ptype" output:

    (gdb) ptype table
    type = array (0 .. 4) of foo.item

Normally, the debugger should print:

    (gdb) ptype table
    type = array (0 .. 4) of foo.item <packed: 6-bit elements>

The debugging information for this array looks like this:

        .uleb128 0xf    # (DIE (0x15c) DW_TAG_array_type)
        .long   .LASF9  # DW_AT_name: "pck__table"
        .byte   0x6     # DW_AT_bit_stride
        .long   0x1a9   # DW_AT_type
        .uleb128 0x10   # (DIE (0x16a) DW_TAG_subrange_type)
        .long   0x3b    # DW_AT_type
        .byte   0       # DW_AT_lower_bound
        .byte   0x4     # DW_AT_upper_bound
        .byte   0       # end of children of DIE 0x15c

The interesting part is the DW_AT_bit_stride attribute, which tells
the size of the array elements is 6 bits, rather than the normal
element type's size.

This patch adds support for this attribute by first creating
gdbtypes.c::create_array_type_with_stride, which is an enhanced
version of create_array_type taking an extra parameter as the stride.
The old create_array_type can then be re-implemented very simply
by calling the new create_array_type_with_stride.

We can then use this new function from dwarf2read, to create
arrays with or without stride.

gdb/ChangeLog:

        * gdbtypes.h (create_array_type_with_stride): Add declaration.
        * gdbtypes.c (create_array_type_with_stride): New function,
        renaming create_array_type, but with an added parameter
        called "bit_stride".
        (create_array_type): Re-implement using
        create_array_type_with_stride.
        * dwarf2read.c (read_array_type): Add support for DW_AT_byte_stride
        and DW_AT_bit_stride attributes.

gdb/testsuite/ChangeLog:

        * gdb.dwarf2/arr-stride.c: New file.
        * gdb.dwarf2/arr-stride.exp: New file.

The test, relying purely on generating an assembly file, only
verifies the type description of our array. But I was also
able to verify manually that the debugger print values of these
types correctly as well (which was not the case prior to this
patch).
This commit is contained in:
Joel Brobecker
2014-01-29 17:39:56 +04:00
parent 12ab52e977
commit dc53a7adb5
7 changed files with 187 additions and 6 deletions

View File

@ -951,14 +951,18 @@ get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
Elements will be of type ELEMENT_TYPE, the indices will be of type
RANGE_TYPE.
If BIT_STRIDE is not zero, build a packed array type whose element
size is BIT_STRIDE. Otherwise, ignore this parameter.
FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
sure it is TYPE_CODE_UNDEF before we bash it into an array
type? */
struct type *
create_array_type (struct type *result_type,
struct type *element_type,
struct type *range_type)
create_array_type_with_stride (struct type *result_type,
struct type *element_type,
struct type *range_type,
unsigned int bit_stride)
{
LONGEST low_bound, high_bound;
@ -975,6 +979,9 @@ create_array_type (struct type *result_type,
In such cases, the array length should be zero. */
if (high_bound < low_bound)
TYPE_LENGTH (result_type) = 0;
else if (bit_stride > 0)
TYPE_LENGTH (result_type) =
(bit_stride * (high_bound - low_bound + 1) + 7) / 8;
else
TYPE_LENGTH (result_type) =
TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
@ -983,6 +990,8 @@ create_array_type (struct type *result_type,
(struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
TYPE_INDEX_TYPE (result_type) = range_type;
TYPE_VPTR_FIELDNO (result_type) = -1;
if (bit_stride > 0)
TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride;
/* TYPE_FLAG_TARGET_STUB will take care of zero length arrays. */
if (TYPE_LENGTH (result_type) == 0)
@ -991,6 +1000,18 @@ create_array_type (struct type *result_type,
return result_type;
}
/* Same as create_array_type_with_stride but with no bit_stride
(BIT_STRIDE = 0), thus building an unpacked array. */
struct type *
create_array_type (struct type *result_type,
struct type *element_type,
struct type *range_type)
{
return create_array_type_with_stride (result_type, element_type,
range_type, 0);
}
struct type *
lookup_array_range_type (struct type *element_type,
LONGEST low_bound, LONGEST high_bound)