aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-10-24 11:12:11 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2019-12-01 22:31:30 +0000
commit5bbd8269fa8d138e8ea1dd3c8cdf42412c1dfa41 (patch)
tree424045e6cff4208f62566e5ab727aafe23cfca7c /gdb/dwarf2read.c
parent82e3b5645f9c4edc1d84e57c32665d0e76bbbd77 (diff)
downloadgdb-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.c47
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;