This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PatchPing]: Remove the dependence of TYPE_VPTR_FIELDNO to find vptr
- From: Wu Zhou <woodzltc at cn dot ibm dot com>
- To: drow at false dot org, gdb-patches at sources dot redhat dot com
- Date: Tue, 22 Nov 2005 14:09:39 +0800 (CST)
- Subject: [PatchPing]: Remove the dependence of TYPE_VPTR_FIELDNO to find vptr
- References: <Pine.LNX.4.63.0510211754001.20690@linux.site>
Hi Daniel,
Do you think that this patch still make sense provided that Elena had
checked in my patch to add XL compiler specific code to set
TYPE_VPTR_FIELDNO and TYPE_VPTR_BASETYPE?
Maybe we can at lease keep virtual base type non-zero checking before
accessing its members (such as TYPE_VPTR_FIELDNO)?
Sincerely looking forward to your reply.
Regards
- Wu Zhou
On Fri, 21 Oct 2005, Wu Zhou wrote:
> 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 <woodzltc@cn.ibm.com>
>
> * 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) : "<unknown>");
>
> /* 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) : "<unknown>");
>
> /* 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) : "<unknown>");
> --- 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) : "<unknown>");
>
>
> Best Regards
> - Wu Zhou
>