diff options
author | Joel Brobecker <brobecker@adacore.com> | 2018-01-01 22:47:18 -0500 |
---|---|---|
committer | Joel Brobecker <brobecker@adacore.com> | 2018-01-01 22:50:13 -0500 |
commit | a405673cc5b56c260de4e1202cead709d1a4f24c (patch) | |
tree | fe2a9bacdacc9697e68844c58b6c769db9a9181d /gdb/testsuite/gdb.ada | |
parent | 74a2f8ffb83172de1af0da6751a65c08a722986f (diff) | |
download | binutils-gdb-a405673cc5b56c260de4e1202cead709d1a4f24c.tar.gz |
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/testsuite/gdb.ada')
-rw-r--r-- | gdb/testsuite/gdb.ada/dyn_stride.exp | 38 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/dyn_stride/foo.adb | 42 |
2 files changed, 80 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.ada/dyn_stride.exp b/gdb/testsuite/gdb.ada/dyn_stride.exp new file mode 100644 index 00000000000..33723d46c19 --- /dev/null +++ b/gdb/testsuite/gdb.ada/dyn_stride.exp @@ -0,0 +1,38 @@ +# Copyright 2015-2018 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 "ada.exp" + +standard_ada_testfile foo + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb] +if ![runto "foo.adb:$bp_location" ] then { + return -1 +} + +gdb_test "print A1(1)" \ + "\\(i => 0, s => \"\"\\)" + +gdb_test "print A1(2)" \ + "\\(i => 1, s => \"A\"\\)" + +gdb_test "print A1(3)" \ + "\\(i => 2, s => \"AB\"\\)" diff --git a/gdb/testsuite/gdb.ada/dyn_stride/foo.adb b/gdb/testsuite/gdb.ada/dyn_stride/foo.adb new file mode 100644 index 00000000000..12ab8cedca9 --- /dev/null +++ b/gdb/testsuite/gdb.ada/dyn_stride/foo.adb @@ -0,0 +1,42 @@ +-- Copyright 2015-2018 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/>. + +procedure Foo is + + 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; + +begin + Nested (0, 10); + Nested (-10, 10); +end Foo; |