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]

[RFC/gnu-v3-abi]: Remove the dependence of TYPE_VPTR_FIELDNO to findvptr


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]