diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/ada-lang.c | 17 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/set_pckd_arr_elt.exp | 47 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/set_pckd_arr_elt/foo.adb | 22 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.adb | 21 | ||||
-rw-r--r-- | gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.ads | 22 | ||||
-rw-r--r-- | gdb/value.c | 13 | ||||
-rw-r--r-- | gdb/value.h | 1 |
9 files changed, 149 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b813695..706788c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2012-03-16 Joel Brobecker <brobecker@adacore.com> + + * value.h (set_value_parent): Add declaration. + * value.c (set_value_parent): New function. + (value_address): If VALUE->PARENT is not NULL, then use it as + the base address instead of VALUE->LOCATION.address. + * ada-lang.c (ada_value_primitive_packed_val): Keep V's address + the same as OBJ's address. Adjust V's offset accordingly. + Set V's parent. + 2012-03-16 Gary Benson <gbenson@redhat.com> PR breakpoints/10738 diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 040d606..78a0261 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2297,10 +2297,9 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, } else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj)) { - v = value_at (type, - value_address (obj) + offset); + v = value_at (type, value_address (obj)); bytes = (unsigned char *) alloca (len); - read_memory (value_address (v), bytes, len); + read_memory (value_address (v) + offset, bytes, len); } else { @@ -2310,18 +2309,22 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, if (obj != NULL) { - CORE_ADDR new_addr; + long new_offset = offset; set_value_component_location (v, obj); - new_addr = value_address (obj) + offset; set_value_bitpos (v, bit_offset + value_bitpos (obj)); set_value_bitsize (v, bit_size); if (value_bitpos (v) >= HOST_CHAR_BIT) { - ++new_addr; + ++new_offset; set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT); } - set_value_address (v, new_addr); + set_value_offset (v, new_offset); + + /* Also set the parent value. This is needed when trying to + assign a new value (in inferior memory). */ + set_value_parent (v, obj); + value_incref (obj); } else set_value_bitsize (v, bit_size); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ee59720..f4a75dd 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-03-16 Joel Brobecker <brobecker@adacore.com> + + * gdb.ada/set_pckd_arr_elt: New testcase. + 2012-03-16 Gary Benson <gbenson@redhat.com> PR breakpoints/10738 diff --git a/gdb/testsuite/gdb.ada/set_pckd_arr_elt.exp b/gdb/testsuite/gdb.ada/set_pckd_arr_elt.exp new file mode 100644 index 0000000..7f6f1d3 --- /dev/null +++ b/gdb/testsuite/gdb.ada/set_pckd_arr_elt.exp @@ -0,0 +1,47 @@ +# Copyright 2012 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" + +if { [skip_ada_tests] } { return -1 } + +set testdir "set_pckd_arr_elt" +set testfile "${testdir}/foo" +set srcfile ${srcdir}/${subdir}/${testfile}.adb +set binfile ${objdir}/${subdir}/${testfile} + +file mkdir ${objdir}/${subdir}/${testdir} +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb] +runto "foo.adb:$bp_location" + +gdb_test "print sa(3) := 9" " = 9" + +# To verify that the assignment was made correctly, we use the fact +# that the program passes this very same element as an argument to +# one of the functions. So we insert a breakpoint on that function, +# and verify that the argument value is correct. + +gdb_breakpoint "update_small" + +gdb_test "continue" \ + "Breakpoint .*, pck\\.update_small \\(s=9\\) at .*pck.adb:.*" \ + "continue to update_small" + diff --git a/gdb/testsuite/gdb.ada/set_pckd_arr_elt/foo.adb b/gdb/testsuite/gdb.ada/set_pckd_arr_elt/foo.adb new file mode 100644 index 0000000..7f4f45d --- /dev/null +++ b/gdb/testsuite/gdb.ada/set_pckd_arr_elt/foo.adb @@ -0,0 +1,22 @@ +-- Copyright 2012 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/>. + +with Pck; use Pck; + +procedure Foo is + SA : Simple_Array := (1, 2, 3, 4); +begin + Update_Small (SA (3)); -- STOP +end Foo; diff --git a/gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.adb b/gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.adb new file mode 100644 index 0000000..a2bec81 --- /dev/null +++ b/gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.adb @@ -0,0 +1,21 @@ +-- Copyright 2012 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/>. + +package body Pck is + procedure Update_Small (S : in out Small) is + begin + null; + end Update_Small; +end Pck; diff --git a/gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.ads b/gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.ads new file mode 100644 index 0000000..6be95e2 --- /dev/null +++ b/gdb/testsuite/gdb.ada/set_pckd_arr_elt/pck.ads @@ -0,0 +1,22 @@ +-- Copyright 2012 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/>. + +package Pck is + type Small is new Integer range 0 .. 2 ** 6 - 1; + type Simple_Array is array (1 .. 4) of Small; + pragma Pack (Simple_Array); + + procedure Update_Small (S : in out Small); +end Pck; diff --git a/gdb/value.c b/gdb/value.c index e8eb33f..c23803a 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -806,6 +806,14 @@ value_parent (struct value *value) return value->parent; } +/* See value.h. */ + +void +set_value_parent (struct value *value, struct value *parent) +{ + value->parent = parent; +} + gdb_byte * value_contents_raw (struct value *value) { @@ -1101,7 +1109,10 @@ value_address (const struct value *value) if (value->lval == lval_internalvar || value->lval == lval_internalvar_component) return 0; - return value->location.address + value->offset; + if (value->parent != NULL) + return value_address (value->parent) + value->offset; + else + return value->location.address + value->offset; } CORE_ADDR diff --git a/gdb/value.h b/gdb/value.h index 3ce0f88..d501b52 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -74,6 +74,7 @@ extern void set_value_bitpos (struct value *, int bit); bitfields. */ struct value *value_parent (struct value *); +extern void set_value_parent (struct value *value, struct value *parent); /* Describes offset of a value within lval of a structure in bytes. If lval == lval_memory, this is an offset to the address. If lval |