From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24661 invoked by alias); 11 Aug 2009 19:53:21 -0000 Received: (qmail 24646 invoked by uid 22791); 11 Aug 2009 19:53:17 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 11 Aug 2009 19:53:07 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n7BJr55W027808 for ; Tue, 11 Aug 2009 15:53:05 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n7BJr4ph008050 for ; Tue, 11 Aug 2009 15:53:05 -0400 Received: from host0.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n7BJr2wY022145 for ; Tue, 11 Aug 2009 15:53:04 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.3/8.14.3) with ESMTP id n7BJr1iW014282 for ; Tue, 11 Aug 2009 21:53:01 +0200 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.3/8.14.3/Submit) id n7BJr00l014274 for gdb-patches@sourceware.org; Tue, 11 Aug 2009 21:53:00 +0200 Date: Tue, 11 Aug 2009 20:03:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Support constant DW_AT_data_member_location by GCC PR debug/40659 Message-ID: <20090811195300.GA12898@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.19 (2009-01-05) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-08/txt/msg00163.txt.bz2 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 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 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 . */ + +/* 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 . + +# 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 .*"