[RFC/gnu-v3-abi]: Remove the dependence of TYPE_VPTR_FIELDNO to find vptr
Wu Zhou
woodzltc@cn.ibm.com
Fri Oct 21 10:14:00 GMT 2005
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
More information about the Gdb-patches
mailing list