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]

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


Hi,

GDB can now segfault on a GCC-4.5-HEAD output due to the simplification:
	http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40659
 <2><3b>: Abbrev Number: 2 (DW_TAG_inheritance)
    <3c>   DW_AT_type        : <0x27>	
    <40>   DW_AT_data_member_location: 2 byte block: 23 0      (DW_OP_plus_uconst: 0)
->
    <40>   DW_AT_data_member_location: 0
    DW_AT_data_member_location DW_FORM_data1


Important part is the dwarf2_add_field change of /* C++ base class field.  */,
other changes are only a cleanup.

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


Thanks,
Jan


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

	Support constant DW_AT_data_member_location by GCC PR debug/40659.
	* dwarf2read.c (dwarf2_get_attr_constant_value): Prototype now uses
	CORE_ADDR.
	(dwarf2_add_field, dwarf2_add_member_fn, read_common_block): Use
	dwarf2_get_attr_constant_value.
	(read_subrange_type, read_subrange_type): Add new parameter to the
	dwarf2_get_attr_constant_value call.
	(dwarf2_get_ref_die_offset): Fix the return value comment.  Change the
	function data type INT to CORE_ADDR.  Support also attr_form_is_block.

gdb/testsuite/
2009-08-11  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
@@ -1078,7 +1078,8 @@ static int is_ref_attr (struct attribute *);
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
 
-static int dwarf2_get_attr_constant_value (struct attribute *, int);
+static CORE_ADDR dwarf2_get_attr_constant_value (struct attribute *, CORE_ADDR,
+					   struct dwarf2_cu *);
 
 static struct die_info *follow_die_ref_or_sig (struct die_info *,
 					       struct attribute *,
@@ -4384,21 +4385,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
       /* Get bit offset of field.  */
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
-	{
-          int byte_offset;
-
-          if (attr_form_is_section_offset (attr))
-            {
-              dwarf2_complex_location_expr_complaint ();
-              byte_offset = 0;
-            }
-          else if (attr_form_is_constant (attr))
-            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else
-            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-
-          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
-	}
+	SET_FIELD_BITPOS (*fp, dwarf2_get_attr_constant_value (attr, 0, cu)
+			       * bits_per_byte);
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
 	{
@@ -4490,7 +4478,7 @@ 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)
+	SET_FIELD_BITPOS (*fp, dwarf2_get_attr_constant_value (attr, 0, cu)
 			       * bits_per_byte);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
@@ -4709,22 +4697,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* Get index in virtual function table if it is a virtual member function.  */
   attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
   if (attr)
-    {
-      /* Support the .debug_loc offsets */
-      if (attr_form_is_block (attr))
-        {
-          fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
-        }
-      else if (attr_form_is_section_offset (attr))
-        {
-	  dwarf2_complex_location_expr_complaint ();
-        }
-      else
-        {
-	  dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location",
-						 fieldname);
-        }
-   }
+    fnp->voffset = dwarf2_get_attr_constant_value (attr, -2, cu) + 2;
 }
 
 /* Create the vector of member function fields, and attach it to the type.  */
@@ -5413,22 +5386,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (attr)
-    {
-      /* Support the .debug_loc offsets */
-      if (attr_form_is_block (attr))
-        {
-          base = decode_locdesc (DW_BLOCK (attr), cu);
-        }
-      else if (attr_form_is_section_offset (attr))
-        {
-	  dwarf2_complex_location_expr_complaint ();
-        }
-      else
-        {
-	  dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
-						 "common block member");
-        }
-    }
+    base = dwarf2_get_attr_constant_value (attr, 0, cu);
   if (die->child != NULL)
     {
       child_die = die->child;
@@ -5439,7 +5397,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 	  if (attr)
 	    {
 	      SYMBOL_VALUE_ADDRESS (sym) =
-		base + decode_locdesc (DW_BLOCK (attr), cu);
+		base + dwarf2_get_attr_constant_value (attr, 0, cu);
 	      add_symbol_to_list (sym, &global_symbols);
 	    }
 	  child_die = sibling_die (child_die);
@@ -5955,7 +5913,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
      but we don't know how to handle it.  */
   attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
   if (attr)
-    low = dwarf2_get_attr_constant_value (attr, 0);
+    low = dwarf2_get_attr_constant_value (attr, 0, cu);
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
   if (attr)
@@ -5976,7 +5934,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
           high = low - 1;
         }
       else
-        high = dwarf2_get_attr_constant_value (attr, 1);
+        high = dwarf2_get_attr_constant_value (attr, 1, cu);
     }
 
   range_type = create_range_type (NULL, base_type, low, high);
@@ -10181,11 +10139,12 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
   return 0;
 }
 
-/* Return the constant value held by the given attribute.  Return -1
+/* Return the constant value held by the given attribute.  Return DEFAULT_VALUE
    if the value held by the attribute is not constant.  */
 
-static int
-dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+static CORE_ADDR
+dwarf2_get_attr_constant_value (struct attribute *attr, CORE_ADDR default_value,
+				struct dwarf2_cu *cu)
 {
   if (attr->form == DW_FORM_sdata)
     return DW_SND (attr);
@@ -10195,6 +10154,8 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
            || attr->form == DW_FORM_data4
            || attr->form == DW_FORM_data8)
     return DW_UNSND (attr);
+  else if (attr_form_is_block (attr))
+    return decode_locdesc (DW_BLOCK (attr), cu);
   else
     {
       complaint (&symfile_complaints, _("Attribute value is not a constant (%s)"),
--- /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]