This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFA/DWARF] Add array DW_AT_bit_stride and DW_AT_byte_stride support
- From: Joel Brobecker <brobecker at adacore dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 17 Feb 2014 21:20:29 +0100
- Subject: Re: [RFA/DWARF] Add array DW_AT_bit_stride and DW_AT_byte_stride support
- Authentication-results: sourceware.org; auth=none
- References: <1391005830-16158-1-git-send-email-brobecker at adacore dot com>
Ping?
Thank you :)
On Wed, Jan 29, 2014 at 06:30:30PM +0400, Joel Brobecker wrote:
> Hello,
>
> 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).
> ---
> gdb/dwarf2read.c | 18 +++++-
> gdb/gdbtypes.c | 27 +++++++-
> gdb/gdbtypes.h | 4 ++
> gdb/testsuite/gdb.dwarf2/arr-stride.c | 20 ++++++
> gdb/testsuite/gdb.dwarf2/arr-stride.exp | 108 ++++++++++++++++++++++++++++++++
> 5 files changed, 171 insertions(+), 6 deletions(-)
> create mode 100644 gdb/testsuite/gdb.dwarf2/arr-stride.c
> create mode 100644 gdb/testsuite/gdb.dwarf2/arr-stride.exp
>
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index 54c538a..1c9c188 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -13254,6 +13254,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
> int ndim = 0;
> struct cleanup *back_to;
> const char *name;
> + unsigned int bit_stride = 0;
>
> element_type = die_type (die, cu);
>
> @@ -13262,13 +13263,22 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
> if (type)
> return type;
>
> + attr = dwarf2_attr (die, DW_AT_byte_stride, cu);
> + if (attr != NULL)
> + bit_stride = DW_UNSND (attr) * 8;
> +
> + attr = dwarf2_attr (die, DW_AT_bit_stride, cu);
> + if (attr != NULL)
> + bit_stride = DW_UNSND (attr);
> +
> /* Irix 6.2 native cc creates array types without children for
> arrays with unspecified length. */
> if (die->child == NULL)
> {
> index_type = objfile_type (objfile)->builtin_int;
> range_type = create_range_type (NULL, index_type, 0, -1);
> - type = create_array_type (NULL, element_type, range_type);
> + type = create_array_type_with_stride (NULL, element_type, range_type,
> + bit_stride);
> return set_die_type (die, type, cu);
> }
>
> @@ -13308,12 +13318,14 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
> int i = 0;
>
> while (i < ndim)
> - type = create_array_type (NULL, type, range_types[i++]);
> + type = create_array_type_with_stride (NULL, type, range_types[i++],
> + bit_stride);
> }
> else
> {
> while (ndim-- > 0)
> - type = create_array_type (NULL, type, range_types[ndim]);
> + type = create_array_type_with_stride (NULL, type, range_types[ndim],
> + bit_stride);
> }
>
> /* Understand Dwarf2 support for vector types (like they occur on
> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index 042c17d..03d7ba9 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -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 non-null, 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 = -1), 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)
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index 61ddeff..a1d9921 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -1529,8 +1529,12 @@ extern struct type *lookup_function_type_with_arguments (struct type *,
> extern struct type *create_range_type (struct type *, struct type *, LONGEST,
> LONGEST);
>
> +extern struct type *create_array_type_with_stride
> + (struct type *, struct type *, struct type *, unsigned int);
> +
> extern struct type *create_array_type (struct type *, struct type *,
> struct type *);
> +
> extern struct type *lookup_array_range_type (struct type *, LONGEST, LONGEST);
>
> extern struct type *create_string_type (struct type *, struct type *,
> diff --git a/gdb/testsuite/gdb.dwarf2/arr-stride.c b/gdb/testsuite/gdb.dwarf2/arr-stride.c
> new file mode 100644
> index 0000000..978ef8d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/arr-stride.c
> @@ -0,0 +1,20 @@
> +/* Copyright 2014 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +int
> +main (void)
> +{
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.dwarf2/arr-stride.exp b/gdb/testsuite/gdb.dwarf2/arr-stride.exp
> new file mode 100644
> index 0000000..f2a1f39
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/arr-stride.exp
> @@ -0,0 +1,108 @@
> +# Copyright 2014 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +load_lib dwarf.exp
> +
> +# This test can only be run on targets which support DWARF-2 and use gas.
> +if {![dwarf2_support]} {
> + return 0
> +}
> +
> +standard_testfile arr-stride.c arr-stride-dw.S
> +
> +# Make some DWARF for the test.
> +set asm_file [standard_output_file $srcfile2]
> +Dwarf::assemble $asm_file {
> + cu {} {
> + DW_TAG_compile_unit {
> + {DW_AT_language @DW_LANG_Ada95}
> + {DW_AT_name foo.adb}
> + {DW_AT_comp_dir /tmp}
> + } {
> + declare_labels integer_label array_elt_label array_label \
> + big_array_label
> +
> + integer_label: DW_TAG_base_type {
> + {DW_AT_byte_size 4 DW_FORM_sdata}
> + {DW_AT_encoding @DW_ATE_signed}
> + {DW_AT_name integer}
> + }
> +
> + array_elt_label: DW_TAG_subrange_type {
> + {DW_AT_lower_bound 0xe0 DW_FORM_data1}
> + {DW_AT_upper_bound 0x1f DW_FORM_data1}
> + {DW_AT_name pck__item}
> + {DW_AT_type :$integer_label}
> + }
> +
> + DW_TAG_typedef {
> + {DW_AT_name pck__table}
> + {DW_AT_type :$array_label}
> + }
> +
> + array_label: DW_TAG_array_type {
> + {DW_AT_name pck__table}
> + {DW_AT_bit_stride 6 DW_FORM_data1}
> + {DW_AT_type :$array_elt_label}
> + } {
> + DW_TAG_subrange_type {
> + {DW_AT_type :$integer_label}
> + {DW_AT_lower_bound 0 DW_FORM_data1}
> + {DW_AT_upper_bound 4 DW_FORM_data1}
> + }
> + }
> +
> + DW_TAG_typedef {
> + {DW_AT_name pck__big_table}
> + {DW_AT_type :$big_array_label}
> + }
> +
> + big_array_label: DW_TAG_array_type {
> + {DW_AT_name pck__big_table}
> + {DW_AT_byte_stride 1 DW_FORM_data1}
> + {DW_AT_type :$array_elt_label}
> + } {
> + DW_TAG_subrange_type {
> + {DW_AT_type :$integer_label}
> + {DW_AT_lower_bound 0 DW_FORM_data1}
> + {DW_AT_upper_bound 4 DW_FORM_data1}
> + }
> + }
> + }
> + }
> +}
> +
> +if {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
> + object {nodebug}] != ""} {
> + return -1
> +}
> +
> +if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} {
> + return -1
> +}
> +
> +if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \
> + "${binfile}" executable {}] != ""} {
> + return -1
> +}
> +
> +clean_restart ${testfile}
> +
> +gdb_test_no_output "set language ada"
> +
> +gdb_test "ptype pck.table" \
> + "type = array \\(0 \\.\\. 4\\) of pck\\.item <packed: 6-bit elements>"
> +
> +gdb_test "ptype pck.big_table" \
> + "type = array \\(0 \\.\\. 4\\) of pck\\.item <packed: 8-bit elements>"
> --
> 1.8.3.2
--
Joel