This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC, v2] Fix PR symtab/15391


Jan's note about -m32 testing for implptrconst.exp made me revisit this
patch.  The new version fixes some more bugs.


PR symtab/15391 is a failure with the DW_OP_GNU_implicit_pointer
feature.

I tracked it down to a logic error in read_pieced_value.  The code
truncates this_size_bits according to the type size and offset too
early -- it should do it after taking bits_to_skip into account.

This patch fixes the bug.

While testing this, I also tripped across a latent bug because
indirect_pieced_value does not sign-extend where needed.  This patch
fixes this bug as well.

Built and regtested on x86-64 Fedora 18.  New test cases included;
this required a minor addition to the DWARF assembler.  Note that the
DWARF CU made by implptrpiece.exp uses a funny pointer size in order
to show the sign-extension bug on all platforms.

	* dwarf2loc.c (read_pieced_value): Truncate this_size_bits
	after taking bits_to_skip into account.  Sign extend byte_offset.

	* gdb.dwarf2/implptrpiece.exp: New file.
	* gdb.dwarf2/implptrconst.exp (d): New variable.
	Print d.
	* lib/dwarf2.exp (Dwarf::_location): Handle DW_OP_piece.
---
 gdb/dwarf2loc.c                           |  20 ++++-
 gdb/testsuite/gdb.dwarf2/implptrconst.exp |   9 ++
 gdb/testsuite/gdb.dwarf2/implptrpiece.exp | 131 ++++++++++++++++++++++++++++++
 gdb/testsuite/lib/dwarf.exp               |   4 +
 4 files changed, 160 insertions(+), 4 deletions(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/implptrpiece.exp

diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 9e44096..7beb927 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1641,8 +1641,6 @@ read_pieced_value (struct value *v)
 	  bits_to_skip -= this_size_bits;
 	  continue;
 	}
-      if (this_size_bits > type_len - offset)
-	this_size_bits = type_len - offset;
       if (bits_to_skip > 0)
 	{
 	  dest_offset_bits = 0;
@@ -1655,6 +1653,8 @@ read_pieced_value (struct value *v)
 	  dest_offset_bits = offset;
 	  source_offset_bits = 0;
 	}
+      if (this_size_bits > type_len - offset)
+	this_size_bits = type_len - offset;
 
       this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
       source_offset = source_offset_bits / 8;
@@ -2087,8 +2087,20 @@ indirect_pieced_value (struct value *value)
 
   frame = get_selected_frame (_("No frame selected."));
 
-  /* This is an offset requested by GDB, such as value subcripts.  */
+  /* This is an offset requested by GDB, such as value subscripts.
+     However, due to how synthetic pointers are implemented, this is
+     always presented to us as a pointer type.  This means we have to
+     sign-extend it manually as appropriate.  */
   byte_offset = value_as_address (value);
+  if (TYPE_LENGTH (value_type (value)) < sizeof (LONGEST))
+    {
+      LONGEST nbits = 8 * TYPE_LENGTH (value_type (value));
+      LONGEST m1 = -1;
+
+      if (((byte_offset >> (nbits - 1)) & 1) != 0)
+	byte_offset |= m1 << nbits;
+    }
+  byte_offset += piece->v.ptr.offset;
 
   gdb_assert (piece);
   baton
@@ -2099,7 +2111,7 @@ indirect_pieced_value (struct value *value)
   if (baton.data != NULL)
     return dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame,
 					  baton.data, baton.size, baton.per_cu,
-					  piece->v.ptr.offset + byte_offset);
+					  byte_offset);
 
   {
     struct obstack temp_obstack;
diff --git a/gdb/testsuite/gdb.dwarf2/implptrconst.exp b/gdb/testsuite/gdb.dwarf2/implptrconst.exp
index 7eca600..566ac01 100644
--- a/gdb/testsuite/gdb.dwarf2/implptrconst.exp
+++ b/gdb/testsuite/gdb.dwarf2/implptrconst.exp
@@ -73,6 +73,14 @@ Dwarf::assemble $asm_file {
 		    GNU_implicit_pointer $var_label 0
 		} SPECIAL_expr}
 	    }
+
+	    DW_TAG_variable {
+		{name d}
+		{type :$ptr_label}
+		{location {
+		    GNU_implicit_pointer $var_label 2
+		} SPECIAL_expr}
+	    }
 	}
     }
 }
@@ -103,3 +111,4 @@ if ![runto_main] {
 }
 
 gdb_test "print *c" " = 114 'r'"
+gdb_test "print d\[-2\]" " = 114 'r'"
diff --git a/gdb/testsuite/gdb.dwarf2/implptrpiece.exp b/gdb/testsuite/gdb.dwarf2/implptrpiece.exp
new file mode 100644
index 0000000..a8d4e8e
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/implptrpiece.exp
@@ -0,0 +1,131 @@
+# Copyright 2013 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 dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0  
+}
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile main.c implptrpiece-dw.S
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+
+Dwarf::assemble $asm_file {
+    # Using a funny address size here and in the pointer type lets us
+    # also check for a sign-extension bug in the
+    # DW_OP_GNU_implicit_pointer code.
+    cu 0 2 2 {
+ 	compile_unit {} {
+	    declare_labels struct_label short_type_label
+	    declare_labels char_type_label ptr_label
+	    declare_labels var_label
+
+	    struct_label: structure_type {
+		{name S}
+		{byte_size 4 DW_FORM_sdata}
+	    } {
+		member {
+		    {name a}
+		    {type :$short_type_label}
+		    {data_member_location 0 DW_FORM_sdata}
+		}
+		member {
+		    {name b}
+		    {type :$char_type_label}
+		    {data_member_location 2 DW_FORM_sdata}
+		}
+		member {
+		    {name c}
+		    {type :$char_type_label}
+		    {data_member_location 3 DW_FORM_sdata}
+		}
+	    }
+
+	    short_type_label: base_type {
+		{name "short int"}
+		{encoding @DW_ATE_signed}
+		{byte_size 2 DW_FORM_sdata}
+	    }
+
+	    char_type_label: base_type {
+		{name "signed char"}
+		{encoding @DW_ATE_signed}
+		{byte_size 1 DW_FORM_sdata}
+	    }
+
+	    # See comment above to understand the pointer size.
+	    ptr_label: pointer_type {
+		{byte_size 2 DW_FORM_sdata}
+		{type :$char_type_label}
+	    }
+
+	    var_label: DW_TAG_variable {
+		{name s}
+		{type :$struct_label}
+		{location {
+		    const1u 1
+		    stack_value
+		    piece 2
+		    const1u 2
+		    stack_value
+		    piece 1
+		    const1u 3
+		    stack_value
+		    piece 1
+		} SPECIAL_expr}
+	    }
+
+	    DW_TAG_variable {
+		{name p}
+		{type :$ptr_label}
+		{location {
+		    GNU_implicit_pointer $var_label 2
+		} SPECIAL_expr}
+	    }
+	}
+    }
+}
+
+if  {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
+	  object {nodebug}] != ""} {
+    return -1
+}
+
+if  {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} {
+    return -1
+}
+
+if  {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \
+	  "${binfile}" executable {}] != ""} {
+    return -1
+}
+
+# We need --readnow because otherwise we never read in the CU we
+# created above.
+set saved_gdbflags $GDBFLAGS
+set GDBFLAGS "$GDBFLAGS -readnow"
+clean_restart ${testfile}
+set GDBFLAGS $saved_gdbflags
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test "print/d p\[-1\]" " = 0"
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 2e5a3f7..b73784f 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -646,6 +646,10 @@ namespace eval Dwarf {
 		    _op .sleb128 [lindex $line 1]
 		}
 
+		DW_OP_piece {
+		    _op .uleb128 [lindex $line 1]
+		}
+
 		DW_OP_GNU_implicit_pointer {
 		    if {[llength $line] != 3} {
 			error "usage: DW_OP_GNU_implicit_pointer LABEL OFFSET"
-- 
1.8.1.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]