From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14451 invoked by alias); 21 Oct 2005 10:14:37 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 14429 invoked by uid 22791); 21 Oct 2005 10:14:34 -0000 Received: from ausmtp01.au.ibm.com (HELO ausmtp01.au.ibm.com) (202.81.18.186) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Fri, 21 Oct 2005 10:14:34 +0000 Received: from sd0112e0.au.ibm.com (d23rh903.au.ibm.com [202.81.18.201]) by ausmtp01.au.ibm.com (8.12.10/8.12.10) with ESMTP id j9LAHVxJ155740 for ; Fri, 21 Oct 2005 20:17:31 +1000 Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.250.237]) by sd0112e0.au.ibm.com (8.12.10/NCO/VERS6.7) with ESMTP id j9LAHCD2129062 for ; Fri, 21 Oct 2005 20:17:17 +1000 Received: from d23av04.au.ibm.com (loopback [127.0.0.1]) by d23av04.au.ibm.com (8.12.11/8.13.3) with ESMTP id j9LADJBV004969 for ; Fri, 21 Oct 2005 20:13:20 +1000 Received: from [9.181.133.252] ([9.181.133.252]) by d23av04.au.ibm.com (8.12.11/8.12.11) with ESMTP id j9LADGso004905; Fri, 21 Oct 2005 20:13:17 +1000 Date: Fri, 21 Oct 2005 10:14:00 -0000 From: Wu Zhou To: drow@false.org, gdb-patches@sources.redhat.com Subject: [RFC/gnu-v3-abi]: Remove the dependence of TYPE_VPTR_FIELDNO to find vptr Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2005-10/txt/msg00175.txt.bz2 Hi Daniel, As we discussed a few days ago, in gnu-v3-abi.c we can skip all the rigamarole with the debuginfo to directly find the VPTR, which is always at offset 0 of the struct. So if the c++ compiler don't depend on DW_AT_containing_type and don't set TYPE_VPTR_FIELDNO, we can use that rule to directly get the address of VPTR. I had thought of removing TYPE_VPTR_FIELDNO completely in gnu-v3-abi.c, but found that gnuv3_rtti_type need to look into TYPE_VPTR_FIELDNO to determine whether we can find the RTTI. So before we can find an alternative way to replace that (do you have any thought on how to do that?), we still need TYPE_VPTR_FIELDNO. So I am now adopting the following method: if TYPE_VPTR_BASETYPE is zero, we skip these code to check and fill TYPE_VPTR_FIELDNO. And I will use the following code to find the VPTR: vtable_address = unpack_long (builtin_type_void_data_ptr, value_contents (value)); I had coded a patch and tested it on x86, ppc32 and ppc64. No regression was found with the c++ testcases. Do you think this method is acceptable? Appended is the patch. Please review and comment. 2005-10-21 Wu Zhou * gnu-v3-abi.c (gnuv3_rtti_type): Before getting the fieldno, check the type is not NULL. The vptr is always at the offset 0 of the struct, use this knowledge to find it. * gnu-v3-abi.c (gnuv3_virtual_fn_field): Ditto. * gnu-v3-abi.c (gnuv3_baseclass_offset): Before getting the fieldno, check the type is not NULL. Index: gnu-v3-abi.c =================================================================== RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v retrieving revision 1.28 diff -c -3 -p -r1.28 gnu-v3-abi.c *** gnu-v3-abi.c 12 May 2005 15:28:31 -0000 1.28 --- gnu-v3-abi.c 21 Oct 2005 09:47:54 -0000 *************** gnuv3_rtti_type (struct value *value, *** 217,230 **** /* Fetch VALUE's virtual table pointer, and tweak it to point at an instance of our imaginary gdb_gnu_v3_abi_vtable structure. */ base_type = check_typedef (TYPE_VPTR_BASETYPE (values_type)); ! if (values_type != base_type) { value = value_cast (base_type, value); if (using_enc_p) *using_enc_p = 1; } ! vtable_address ! = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (values_type))); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset ()); --- 217,231 ---- /* Fetch VALUE's virtual table pointer, and tweak it to point at an instance of our imaginary gdb_gnu_v3_abi_vtable structure. */ base_type = check_typedef (TYPE_VPTR_BASETYPE (values_type)); ! if (base_type && values_type != base_type) { value = value_cast (base_type, value); if (using_enc_p) *using_enc_p = 1; } ! ! vtable_address = unpack_long (builtin_type_void_data_ptr, ! value_contents (value)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset ()); *************** gnuv3_virtual_fn_field (struct value **v *** 305,320 **** /* This type may have been defined before its virtual function table was. If so, fill in the virtual function table entry for the type now. */ ! if (TYPE_VPTR_FIELDNO (vfn_base) < 0) fill_in_vptr_fieldno (vfn_base); ! if (TYPE_VPTR_FIELDNO (vfn_base) < 0) error (_("Could not find virtual table pointer for class \"%s\"."), TYPE_TAG_NAME (vfn_base) ? TYPE_TAG_NAME (vfn_base) : ""); /* Now that we know which base class is defining our virtual function, cast our value to that baseclass. This takes care of any necessary `this' adjustments. */ ! if (vfn_base != values_type) value = value_cast (vfn_base, value); /* Now value is an object of the appropriate base type. Fetch its --- 306,322 ---- /* This type may have been defined before its virtual function table was. If so, fill in the virtual function table entry for the type now. */ ! ! if (vfn_base && TYPE_VPTR_FIELDNO (vfn_base) < 0) fill_in_vptr_fieldno (vfn_base); ! if (vfn_base && TYPE_VPTR_FIELDNO (vfn_base) < 0) error (_("Could not find virtual table pointer for class \"%s\"."), TYPE_TAG_NAME (vfn_base) ? TYPE_TAG_NAME (vfn_base) : ""); /* Now that we know which base class is defining our virtual function, cast our value to that baseclass. This takes care of any necessary `this' adjustments. */ ! if (vfn_base && vfn_base != values_type) value = value_cast (vfn_base, value); /* Now value is an object of the appropriate base type. Fetch its *************** gnuv3_virtual_fn_field (struct value **v *** 323,333 **** Does multiple inheritance affect this? Can this even trigger, or is TYPE_VPTR_BASETYPE idempotent? */ ! if (TYPE_VPTR_BASETYPE (vfn_base) != vfn_base) value = value_cast (TYPE_VPTR_BASETYPE (vfn_base), value); - vtable_address - = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (vfn_base))); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset ()); --- 325,336 ---- Does multiple inheritance affect this? Can this even trigger, or is TYPE_VPTR_BASETYPE idempotent? */ ! if (TYPE_VPTR_BASETYPE (vfn_base) && ! TYPE_VPTR_BASETYPE (vfn_base) != vfn_base) value = value_cast (TYPE_VPTR_BASETYPE (vfn_base), value); + vtable_address = unpack_long (builtin_type_void_data_ptr, + value_contents (value)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset ()); *************** gnuv3_baseclass_offset (struct type *typ *** 398,407 **** we have debugging information for that baseclass. */ vbasetype = TYPE_VPTR_BASETYPE (type); ! if (TYPE_VPTR_FIELDNO (vbasetype) < 0) fill_in_vptr_fieldno (vbasetype); ! if (TYPE_VPTR_FIELDNO (vbasetype) >= 0 && TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0) error (_("Illegal vptr offset in class %s"), TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : ""); --- 401,410 ---- we have debugging information for that baseclass. */ vbasetype = TYPE_VPTR_BASETYPE (type); ! if (vbasetype && TYPE_VPTR_FIELDNO (vbasetype) < 0) fill_in_vptr_fieldno (vbasetype); ! if (vbasetype && TYPE_VPTR_FIELDNO (vbasetype) >= 0 && TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0) error (_("Illegal vptr offset in class %s"), TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : ""); Best Regards - Wu Zhou