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:
parent
12ab52e977
commit
dc53a7adb5
|
@ -1,3 +1,14 @@
|
|||
2014-02-26 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2014-02-26 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* breakpoint.c (bpstat_check_breakpoint_conditions): Handle
|
||||
|
|
|
@ -13281,6 +13281,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);
|
||||
|
||||
|
@ -13289,13 +13290,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);
|
||||
}
|
||||
|
||||
|
@ -13335,12 +13345,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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2014-02-26 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.dwarf2/arr-stride.c: New file.
|
||||
* gdb.dwarf2/arr-stride.exp: New file.
|
||||
|
||||
2014-02-26 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* gdb.ada/tasks.exp: Set a task-specific breakpoint at break_me
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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>"
|
Loading…
Reference in New Issue