summaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2018-01-01 22:47:18 -0500
committerJoel Brobecker <brobecker@adacore.com>2018-01-01 22:50:13 -0500
commita405673cc5b56c260de4e1202cead709d1a4f24c (patch)
treefe2a9bacdacc9697e68844c58b6c769db9a9181d /gdb/dwarf2read.c
parent74a2f8ffb83172de1af0da6751a65c08a722986f (diff)
Add support for dynamic DW_AT_byte_stride.
This patch adds support for DW_AT_byte_stride, using Ada as one example of where this would be useful. However, the implementation is language-agnostic. Consider the following Ada code: procedure Nested (L, U : Integer) is subtype Small_Type is Integer range L .. U; type Record_Type (I : Small_Type := L) is record S : String (1 .. I); end record; type Array_Type is array (Integer range <>) of Record_Type; A1 : Array_Type := (1 => (I => 0, S => <>), 2 => (I => 1, S => "A"), 3 => (I => 2, S => "AB")); procedure Discard (R : Record_Type) is begin null; end Discard; begin Discard (A1 (1)); -- STOP end; It defines an array A1 of Record_Type, which is a variant record type whose maximum size actually depends on the value of the parameters passed when calling Nested. As a result, the stride of the array A1 cannot be known statically, which leads the compiler to generate a dynamic DW_AT_byte_stride attribute for our type. Here is what the debugging info looks like with GNAT: .uleb128 0x10 # (DIE (0x14e) DW_TAG_array_type) .long .LASF17 # DW_AT_name: "foo__nested__T18b" .long 0x141 # DW_AT_byte_stride .long 0xdc # DW_AT_type .uleb128 0x11 # (DIE (0x15f) DW_TAG_subrange_type) .long 0x166 # DW_AT_type .byte 0x3 # DW_AT_upper_bound .byte 0 # end of children of DIE 0x14e There DW_AT_byte_stride is a reference to a local (internal) variable: .uleb128 0x9 # (DIE (0x141) DW_TAG_variable) .long .LASF6 # DW_AT_name: "foo__nested__T18b___PAD___XVZ" This patch enhances GDB to handle this dynamic byte stride attribute by first adding a new dynamic_prop_node_kind (DYN_PROP_BYTE_STRIDE) to store the array dynamic stride info (when dynamic). It then enhances the dynamic type resolver to handle this dynamic property. Before applying this patch, trying to print the value of some of A1's elements after having stopped at the "STOP" comment does not work. For instance: (gdb) p a1(2) Cannot access memory at address 0x80000268dec0 With this patch applied, GDB now prints the value of all 3 elements correctly: (gdb) print A1(1) $1 = (i => 0, s => "") (gdb) print A1(2) $2 = (i => 1, s => "A") (gdb) print A1(3) $3 = (i => 2, s => "AB") gdb/ChangeLog: * gdbtypes.h (enum dynamic_prop_node_kind) <DYN_PROP_BYTE_STRIDE>: New enum value. (create_array_type_with_stride): Add byte_stride_prop parameter. * gdbtypes.c (create_array_type_with_stride) <byte_stride_prop>: New parameter. Update all callers in this file. (array_type_has_dynamic_stride): New function. (is_dynamic_type_internal, resolve_dynamic_array): Add handling of arrays with dynamic byte strides. * dwarf2read.c (read_array_type): Add support for dynamic DW_AT_byte_stride attributes. gdb/testsuite/ChangeLog: * gdb.ada/dyn_stride: New testcase. Tested on x86_64-linux.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4dbd5c35d7..a3028e5c52 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -16312,6 +16312,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *element_type, *range_type, *index_type;
struct attribute *attr;
const char *name;
+ struct dynamic_prop *byte_stride_prop = NULL;
unsigned int bit_stride = 0;
element_type = die_type (die, cu);
@@ -16323,7 +16324,25 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_byte_stride, cu);
if (attr != NULL)
- bit_stride = DW_UNSND (attr) * 8;
+ {
+ int stride_ok;
+
+ byte_stride_prop
+ = (struct dynamic_prop *) alloca (sizeof (struct dynamic_prop));
+ stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop);
+ if (!stride_ok)
+ {
+ complaint (&symfile_complaints,
+ _("unable to read array DW_AT_byte_stride "
+ " - DIE at 0x%x [in module %s]"),
+ to_underlying (die->sect_off),
+ objfile_name (cu->objfile));
+ /* Ignore this attribute. We will likely not be able to print
+ arrays of this type correctly, but there is little we can do
+ to help if we cannot read the attribute's value. */
+ byte_stride_prop = NULL;
+ }
+ }
attr = dwarf2_attr (die, DW_AT_bit_stride, cu);
if (attr != NULL)
@@ -16336,7 +16355,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
index_type = objfile_type (objfile)->builtin_int;
range_type = create_static_range_type (NULL, index_type, 0, -1);
type = create_array_type_with_stride (NULL, element_type, range_type,
- bit_stride);
+ byte_stride_prop, bit_stride);
return set_die_type (die, type, cu);
}
@@ -16369,14 +16388,14 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
while (i < range_types.size ())
type = create_array_type_with_stride (NULL, type, range_types[i++],
- bit_stride);
+ byte_stride_prop, bit_stride);
}
else
{
size_t ndim = range_types.size ();
while (ndim-- > 0)
type = create_array_type_with_stride (NULL, type, range_types[ndim],
- bit_stride);
+ byte_stride_prop, bit_stride);
}
/* Understand Dwarf2 support for vector types (like they occur on