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]

Re: [patch] Support constant DW_AT_data_member_location by GCC PR debug/40659


On Fri, 14 Aug 2009 22:58:52 +0200, Tom Tromey wrote:
> >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> Jan> -          if (attr_form_is_section_offset (attr))
> Jan> -            {
> Jan> -              dwarf2_complex_location_expr_complaint ();
> Jan> -              byte_offset = 0;
> 
> IIUC the patch still will issue a complaint for this construct, but now
> it just issues a more generic one from dwarf2_get_attr_constant_value.
> 
> What about putting the more specific checks into that function instead?
> Would it cause some problem?

Thanks for the review, I found out now DWARF3 is very particular which classes
(constant, block, loclistptr, reference etc.) are permitted for which
attribute names (DW_AT_*) - Figure 20, page 138 (150/267).

My patch was extending a bit the classes permitted for some attributes which
is probably wrong.

Moreover DWARF4 draft makes some changes for it:
http://www.dwarfstd.org/doc/DWARF4-draft4-090815.pdf
# In DWARF V3 the forms DW_FORM_data4 and DW_FORM_data8 were members of either
# class constant or one of the classes lineptr, loclistptr, macptr or
# rangelistptr, depending on context. In DWARF V4 DW_FORM_data4 and
# DW_FORM_data8 are members of class constant in all cases. The new
# DW_FORM_sec_offset replaces their usage for the other classes.

Therefore rewritten the patch in a very conservative way fully following the
current GDB style.

The patch only follows DWARF3, it does not try to implement anything from
DWARF4.

Regression tested on {x86_64,i686}-fedora11-linux-gnu.


Thanks,
Jan


gdb/
2009-08-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Support constant DW_AT_data_member_location by GCC PR debug/40659.
	* dwarf2read.c
	(dwarf2_add_field <DW_TAG_member> <DW_AT_data_member_location>):
	Initialize BYTE_OFFSET to 0 by default.  Explicitly check if
	attr_form_is_block.
	(dwarf2_add_field <DW_TAG_inheritance> <DW_AT_data_member_location>)
	(read_common_block <DW_AT_data_member_location>): New variable
	byte_offset.  Fix crash on non-DW_BLOCK ATTR values.

gdb/testsuite/
2009-08-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Support constant DW_AT_data_member_location by GCC PR debug/40659.
	* gdb.dwarf2/dw2-inheritance.exp, gdb.dwarf2/dw2-inheritance.S: New.

--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4385,17 +4385,16 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
 	{
-          int byte_offset;
+          int byte_offset = 0;
 
           if (attr_form_is_section_offset (attr))
-            {
-              dwarf2_complex_location_expr_complaint ();
-              byte_offset = 0;
-            }
+	    dwarf2_complex_location_expr_complaint ();
           else if (attr_form_is_constant (attr))
             byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else
+          else if (attr_form_is_block (attr))
             byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+	  else
+	    dwarf2_complex_location_expr_complaint ();
 
           SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
 	}
@@ -4490,8 +4489,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       /* C++ base class field.  */
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
-	SET_FIELD_BITPOS (*fp, decode_locdesc (DW_BLOCK (attr), cu)
-			       * bits_per_byte);
+	{
+          int byte_offset = 0;
+
+          if (attr_form_is_section_offset (attr))
+	    dwarf2_complex_location_expr_complaint ();
+          else if (attr_form_is_constant (attr))
+            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+          else if (attr_form_is_block (attr))
+            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+	  else
+	    dwarf2_complex_location_expr_complaint ();
+
+          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
+	}
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = type_name_no_tag (fp->type);
@@ -5438,8 +5449,18 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 	  attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
 	  if (attr)
 	    {
-	      SYMBOL_VALUE_ADDRESS (sym) =
-		base + decode_locdesc (DW_BLOCK (attr), cu);
+	      CORE_ADDR byte_offset = 0;
+
+	      if (attr_form_is_section_offset (attr))
+		dwarf2_complex_location_expr_complaint ();
+	      else if (attr_form_is_constant (attr))
+		byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+	      else if (attr_form_is_block (attr))
+		byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+	      else
+		dwarf2_complex_location_expr_complaint ();
+
+	      SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
 	      add_symbol_to_list (sym, &global_symbols);
 	    }
 	  child_die = sibling_die (child_die);
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S
@@ -0,0 +1,98 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2009 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/>.  */
+
+/* Test DW_TAG_inheritance using constant DW_AT_data_member_location
+   introduced by GCC PR debug/40659.  */
+
+/* Debug information */
+
+	.section .debug_info
+.Lcu1_begin:
+	/* CU header */
+	.4byte	.Lcu1_end - .Lcu1_start		/* Length of Compilation Unit */
+.Lcu1_start:
+	.2byte	2				/* DWARF Version */
+	.4byte	.Labbrev1_begin			/* Offset into abbrev section */
+	.byte	4				/* Pointer size */
+
+	/* CU die */
+	.uleb128 1				/* Abbrev: DW_TAG_compile_unit */
+	.4byte	.Lline1_begin			/* DW_AT_stmt_list */
+	.ascii	"file1.txt\0"			/* DW_AT_name */
+	.ascii	"GNU C 3.3.3\0"			/* DW_AT_producer */
+	.byte	4				/* DW_LANG_C_plus_plus (C++) */
+
+.Lbase:
+	.uleb128	3			/* Abbrev: DW_TAG_class_type */
+	.ascii		"base\0"		/* DW_AT_name */
+	.byte		4			/* DW_AT_byte_size */
+
+	.byte		0			/* End of children of "base" */
+
+	.uleb128	3			/* Abbrev: DW_TAG_class_type */
+	.ascii		"inherited\0"		/* DW_AT_name */
+	.byte		8			/* DW_AT_byte_size */
+
+	.uleb128	2			/* Abbrev: DW_TAG_inheritance */
+	.4byte		.Lbase-.Lcu1_begin	/* DW_AT_type */
+	.byte		0			/* DW_AT_data_member_location */
+
+	.byte		0			/* End of children of "inherited" */
+
+	.byte		0			/* End of children of CU */
+
+.Lcu1_end:
+
+/* Abbrev table */
+	.section .debug_abbrev
+.Labbrev1_begin:
+	.uleb128	1			/* Abbrev code */
+	.uleb128	0x11			/* DW_TAG_compile_unit */
+	.byte		1			/* has_children */
+	.uleb128	0x10			/* DW_AT_stmt_list */
+	.uleb128	0x6			/* DW_FORM_data4 */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x25			/* DW_AT_producer */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x13			/* DW_AT_language */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	2			/* Abbrev code */
+	.uleb128	0x1c			/* DW_TAG_inheritance */
+	.byte		0			/* has_children */
+	.uleb128	0x49			/* DW_AT_type */
+	.uleb128	0x13			/* DW_FORM_ref4 */
+	.uleb128	0x38			/* DW_AT_data_member_location */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	3			/* Abbrev code */
+	.uleb128	0x02			/* DW_TAG_class_type */
+	.byte		1			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0xb			/* DW_AT_byte_size */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.exp
@@ -0,0 +1,40 @@
+# Copyright 2009 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/>.
+
+# Test DW_TAG_inheritance using constant DW_AT_data_member_location
+# introduced by GCC PR debug/40659.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    return 0  
+}
+
+set testfile "dw2-inheritance"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable}" object {nodebug}] != "" } {
+    return -1
+}
+
+clean_restart $executable
+
+gdb_test "ptype inherited" "type = class inherited .*"


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