diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-10-24 11:12:11 +0100 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-12-01 22:31:30 +0000 |
commit | 5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41 (patch) | |
tree | 424045e6cff4208f62566e5ab727aafe23cfca7c /gdb/dwarf2read.c | |
parent | 82e3b5645f9c4edc1d84e57c32665d0e76bbbd77 (diff) | |
download | gdb-5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41.zip gdb-5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41.tar.gz gdb-5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41.tar.bz2 |
gdb/fortran: array stride support
Currently GDB supports a byte or bit stride on arrays, in DWARF this
would be DW_AT_bit_stride or DW_AT_byte_stride on DW_TAG_array_type.
However, DWARF can also support DW_AT_byte_stride or DW_AT_bit_stride
on DW_TAG_subrange_type, the tag used to describe each dimension of an
array.
Strides on subranges are used by gFortran to represent Fortran arrays,
and this commit adds support for this to GDB.
I've extended the range_bounds struct to include the stride
information. The name is possibly a little inaccurate now, but this
still sort of makes sense, the structure represents information about
the bounds of the range, and also how to move from the lower to the
upper bound (the stride).
I've added initial support for bit strides, but I've never actually
seen an example of this being generated. Further, I don't really see
right now how GDB would currently handle a bit stride that was not a
multiple of the byte size as the code in, for example,
valarith.c:value_subscripted_rvalue seems geared around byte
addressing. As a consequence if we see a bit stride that is not a
multiple of 8 then GDB will give an error.
gdb/ChangeLog:
* dwarf2read.c (read_subrange_type): Read bit and byte stride and
create a range with stride where appropriate.
* f-valprint.c: Include 'gdbarch.h'.
(f77_print_array_1): Take the stride into account when walking the
array. Also convert the stride into addressable units.
* gdbtypes.c (create_range_type): Initialise the stride to
constant zero.
(create_range_type_with_stride): New function, initialise the
range as normal, and then setup the stride.
(has_static_range): Include the stride here. Also change the
return type to bool.
(create_array_type_with_stride): Consider the range stride if the
array isn't given its own stride.
(resolve_dynamic_range): Resolve the stride if needed.
* gdbtypes.h (struct range_bounds) <stride>: New member variable.
(struct range_bounds) <flag_is_byte_stride>: New member variable.
(TYPE_BIT_STRIDE): Define.
(TYPE_ARRAY_BIT_STRIDE): Define.
(create_range_type_with_stride): Declare.
* valarith.c (value_subscripted_rvalue): Take range stride into
account when walking the array.
gdb/testsuite/ChangeLog:
* gdb.fortran/derived-type-striding.exp: New file.
* gdb.fortran/derived-type-striding.f90: New file.
* gdb.fortran/array-slices.exp: New file.
* gdb.fortran/array-slices.f90: New file.
Change-Id: I9af2bcd1f2d4c56f76f5f3f9f89d8f06bef10d9a
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index fd7d21c..12a9773 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -18065,7 +18065,52 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) && !TYPE_UNSIGNED (base_type) && (high.data.const_val & negative_mask)) high.data.const_val |= negative_mask; - range_type = create_range_type (NULL, orig_base_type, &low, &high, bias); + /* Check for bit and byte strides. */ + struct dynamic_prop byte_stride_prop; + attribute *attr_byte_stride = dwarf2_attr (die, DW_AT_byte_stride, cu); + if (attr_byte_stride != nullptr) + { + struct type *prop_type + = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false); + attr_to_dynamic_prop (attr_byte_stride, die, cu, &byte_stride_prop, + prop_type); + } + + struct dynamic_prop bit_stride_prop; + attribute *attr_bit_stride = dwarf2_attr (die, DW_AT_bit_stride, cu); + if (attr_bit_stride != nullptr) + { + /* It only makes sense to have either a bit or byte stride. */ + if (attr_byte_stride != nullptr) + { + complaint (_("Found DW_AT_bit_stride and DW_AT_byte_stride " + "- DIE at %s [in module %s]"), + sect_offset_str (die->sect_off), + objfile_name (cu->per_cu->dwarf2_per_objfile->objfile)); + attr_bit_stride = nullptr; + } + else + { + struct type *prop_type + = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false); + attr_to_dynamic_prop (attr_bit_stride, die, cu, &bit_stride_prop, + prop_type); + } + } + + if (attr_byte_stride != nullptr + || attr_bit_stride != nullptr) + { + bool byte_stride_p = (attr_byte_stride != nullptr); + struct dynamic_prop *stride + = byte_stride_p ? &byte_stride_prop : &bit_stride_prop; + + range_type + = create_range_type_with_stride (NULL, orig_base_type, &low, + &high, bias, stride, byte_stride_p); + } + else + range_type = create_range_type (NULL, orig_base_type, &low, &high, bias); if (high_bound_is_count) TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1; |