From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24829 invoked by alias); 31 Aug 2008 17:52:38 -0000 Received: (qmail 23502 invoked by uid 22791); 31 Aug 2008 17:52:23 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate8.de.ibm.com (HELO mtagate8.de.ibm.com) (195.212.29.157) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 31 Aug 2008 17:51:38 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate8.de.ibm.com (8.13.8/8.13.8) with ESMTP id m7VHpZO9245790 for ; Sun, 31 Aug 2008 17:51:35 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v9.0) with ESMTP id m7VHpZl83100764 for ; Sun, 31 Aug 2008 19:51:35 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m7VHpZa6020233 for ; Sun, 31 Aug 2008 19:51:35 +0200 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m7VHpZMQ020230 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 31 Aug 2008 19:51:35 +0200 Received: from tuxmaker.boeblingen.de.ibm.com (localhost.localdomain [127.0.0.1]) by tuxmaker.boeblingen.de.ibm.com (8.13.8/8.13.8) with ESMTP id m7VHpZHX002997 for ; Sun, 31 Aug 2008 19:51:35 +0200 Received: (from uweigand@localhost) by tuxmaker.boeblingen.de.ibm.com (8.13.8/8.13.8/Submit) id m7VHpYCd002996 for gdb-patches@sourceware.org; Sun, 31 Aug 2008 19:51:34 +0200 Message-Id: <20080831175134.792724000@de.ibm.com> References: <20080831175045.128504000@de.ibm.com> User-Agent: quilt/0.46-1 Date: Sun, 31 Aug 2008 17:53:00 -0000 From: uweigand@de.ibm.com To: gdb-patches@sourceware.org Subject: [rfc][27/37] Eliminate builtin_type_ macros: Update C++ ABI handling Content-Disposition: inline; filename=diff-type-cpgnu 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: 2008-08/txt/msg00700.txt.bz2 Hello, gnu-v3-abi.c uses current_gdbarch and builtin_type_ macros to determine ABI properties of the C++ class implementation. The following patch removes the dependency on the current_gdbarch variable by using the architecture associated with the objfile where the class type is defined. Note that this assumes every C++ class type GDB handles is in fact defined in an objfile, i.e. there are no GDB internal class types. This is in fact the case (except for some Java "class" definitions, which are not handled by gnu-v3-abi.c anyway). Nearly all functions in gnu-v3-abi.c already operate on a class type. The only exceptions are the cplus_method_ptr_size and cplus_make_method_ptr callbacks; to handle those, I've updated their callers to pass in the appropriate method (or method pointer) type. As another C++-related change, I've removed the assumption in cp_print_class_member that member pointer types have the same length as a "long" on the target. If the caller simply passes in the pointer type itself instead of only the associated domain type, that routine can just use the actual length of the pointer type itself. Bye, Ulrich * cp-abi.h (cplus_method_ptr_size): Add TO_TYPE parameter. (cplus_make_method_ptr): Add TYPE parameter. * cp-abi.c (cplus_method_ptr_size): Add TO_TYPE parameter. Pass it on to current_cp_abi.method_ptr_size callback. (cplus_make_method_ptr): Add TYPE parameter. Pass it on to current_cp_abi.make_method_ptr callback. * gdbtypes.c (lookup_methodptr_type): Pass target type argument to cplus_method_ptr_size. * valops.c (value_cast): Pass type argument to cplus_make_method_ptr. (value_struct_elt_for_reference): Likewise. * gnu-v3-abi.c (get_class_arch): New function. (vtable_address_point_offset): Add GDBARCH parameter. Use it instead of current_gdbarch. Update all callers. (gnuv3_get_vtable): Likewise. (gnuv3_get_virtual_fn): Likewise. (gnuv3_rtti_type): Call get_class_arch to determine architecture. Use it instead of current_gdbarch. (gnuv3_virtual_fn_field): Likewise. (gnuv3_baseclass_offset): Likewise. (gnuv3_print_method_ptr): Likewise. (gnuv3_method_ptr_to_value): Likewise. (gnuv3_method_ptr_size): Add TYPE parameter. Use it to determine class architecture. Use architecture types instead of builtin types. (gnuv3_make_method_ptr): Likewise. * cp-valprint.c (cp_print_class_member): Expect pointer type instead of class type. Use its length when extracting value. * c-valprint.c (c_val_print): Update call to cp_print_class_member. Index: gdb-head/gdb/cp-abi.c =================================================================== --- gdb-head.orig/gdb/cp-abi.c +++ gdb-head/gdb/cp-abi.c @@ -113,19 +113,20 @@ cplus_print_method_ptr (const gdb_byte * } int -cplus_method_ptr_size (void) +cplus_method_ptr_size (struct type *to_type) { if (current_cp_abi.method_ptr_size == NULL) error (_("GDB does not support pointers to methods on this target")); - return (*current_cp_abi.method_ptr_size) (); + return (*current_cp_abi.method_ptr_size) (to_type); } void -cplus_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual) +cplus_make_method_ptr (struct type *type, gdb_byte *contents, + CORE_ADDR value, int is_virtual) { if (current_cp_abi.make_method_ptr == NULL) error (_("GDB does not support pointers to methods on this target")); - (*current_cp_abi.make_method_ptr) (contents, value, is_virtual); + (*current_cp_abi.make_method_ptr) (type, contents, value, is_virtual); } CORE_ADDR Index: gdb-head/gdb/cp-abi.h =================================================================== --- gdb-head.orig/gdb/cp-abi.h +++ gdb-head/gdb/cp-abi.h @@ -151,21 +151,20 @@ extern int baseclass_offset (struct type void cplus_print_method_ptr (const gdb_byte *contents, struct type *type, struct ui_file *stream); -/* Return the size of a pointer to member function for the current - architecture. */ -int cplus_method_ptr_size (void); +/* Return the size of a pointer to member function of type TO_TYPE. */ +int cplus_method_ptr_size (struct type *to_type); /* Return the method which should be called by applying METHOD_PTR to *THIS_P, and adjust *THIS_P if necessary. */ struct value *cplus_method_ptr_to_value (struct value **this_p, struct value *method_ptr); -/* Create the byte pattern in CONTENTS representing a pointer to - member function at ADDRESS (if IS_VIRTUAL is 0) or with virtual - table offset ADDRESS (if IS_VIRTUAL is 1). This is the opposite - of cplus_method_ptr_to_value. */ -void cplus_make_method_ptr (gdb_byte *CONTENTS, CORE_ADDR address, - int is_virtual); +/* Create the byte pattern in CONTENTS representing a pointer of + type TYPE to member function at ADDRESS (if IS_VIRTUAL is 0) + or with virtual table offset ADDRESS (if IS_VIRTUAL is 1). + This is the opposite of cplus_method_ptr_to_value. */ +void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS, + CORE_ADDR address, int is_virtual); /* Determine if we are currently in a C++ thunk. If so, get the address of the routine we are thunking to and continue to there instead. */ @@ -195,8 +194,8 @@ struct cp_abi_ops const bfd_byte *valaddr, CORE_ADDR address); void (*print_method_ptr) (const gdb_byte *contents, struct type *type, struct ui_file *stream); - int (*method_ptr_size) (void); - void (*make_method_ptr) (gdb_byte *, CORE_ADDR, int); + int (*method_ptr_size) (struct type *); + void (*make_method_ptr) (struct type *, gdb_byte *, CORE_ADDR, int); struct value * (*method_ptr_to_value) (struct value **, struct value *); CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR); int (*pass_by_reference) (struct type *type); Index: gdb-head/gdb/cp-valprint.c =================================================================== --- gdb-head.orig/gdb/cp-valprint.c +++ gdb-head/gdb/cp-valprint.c @@ -538,16 +538,16 @@ cp_find_class_member (struct type **doma } void -cp_print_class_member (const gdb_byte *valaddr, struct type *domain, +cp_print_class_member (const gdb_byte *valaddr, struct type *type, struct ui_file *stream, char *prefix) { /* VAL is a byte offset into the structure type DOMAIN. Find the name of the field for that offset and print it. */ + struct type *domain = TYPE_DOMAIN_TYPE (type); + LONGEST val = extract_signed_integer (valaddr, TYPE_LENGTH (type)); unsigned int fieldno; - LONGEST val = unpack_long (builtin_type_long, valaddr); - /* Pointers to data members are usually byte offsets into an object. Because a data member can have offset zero, and a NULL pointer to member must be distinct from any valid non-NULL pointer to Index: gdb-head/gdb/c-valprint.c =================================================================== --- gdb-head.orig/gdb/c-valprint.c +++ gdb-head/gdb/c-valprint.c @@ -189,9 +189,7 @@ c_val_print (struct type *type, const gd print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } - cp_print_class_member (valaddr + embedded_offset, - TYPE_DOMAIN_TYPE (type), - stream, "&"); + cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); break; case TYPE_CODE_METHODPTR: Index: gdb-head/gdb/gdbtypes.c =================================================================== --- gdb-head.orig/gdb/gdbtypes.c +++ gdb-head/gdb/gdbtypes.c @@ -666,7 +666,7 @@ lookup_methodptr_type (struct type *to_t mtype = alloc_type (TYPE_OBJFILE (to_type)); TYPE_TARGET_TYPE (mtype) = to_type; TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type); - TYPE_LENGTH (mtype) = cplus_method_ptr_size (); + TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type); TYPE_CODE (mtype) = TYPE_CODE_METHODPTR; return mtype; } Index: gdb-head/gdb/gnu-v3-abi.c =================================================================== --- gdb-head.orig/gdb/gnu-v3-abi.c +++ gdb-head/gdb/gnu-v3-abi.c @@ -45,6 +45,21 @@ gnuv3_is_operator_name (const char *name } +/* Determine architecture of class DOMAIN. This architecture is used + to query C++ ABI details (types, method pointer layout, etc.). + + Note that we assume DOMAIN must have been allocated with an OBJFILE; + GDB does not provide any built-in class types. Thus we use the + architecture of that OBJFILE to define the C++ ABI. */ + +static struct gdbarch * +get_class_arch (struct type *domain) +{ + gdb_assert (TYPE_CODE (domain) == TYPE_CODE_CLASS); + gdb_assert (TYPE_OBJFILE (domain) != NULL); + return get_objfile_arch (TYPE_OBJFILE (domain)); +} + /* To help us find the components of a vtable, we build ourselves a GDB type object representing the vtable structure. Following the V3 ABI, it goes something like this: @@ -176,10 +191,9 @@ build_gdb_vtable_type (struct gdbarch *a gdb_gnu_v3_abi_vtable' object to the vtable's "address point" (i.e., where objects' virtual table pointers point). */ static int -vtable_address_point_offset (void) +vtable_address_point_offset (struct gdbarch *gdbarch) { - struct type *vtable_type = gdbarch_data (current_gdbarch, - vtable_type_gdbarch_data); + struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data); return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions) / TARGET_CHAR_BIT); @@ -190,8 +204,8 @@ static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { - struct type *vtable_type = gdbarch_data (current_gdbarch, - vtable_type_gdbarch_data); + struct gdbarch *gdbarch; + struct type *vtable_type; struct type *values_type = check_typedef (value_type (value)); CORE_ADDR vtable_address; struct value *vtable; @@ -208,6 +222,16 @@ gnuv3_rtti_type (struct value *value, if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) return NULL; + /* This routine may be called for Java types that do not have + a proper objfile. Just return NULL for those. */ + if (!TYPE_OBJFILE (values_type) + || !TYPE_OBJFILE (values_type)->obfd) + return NULL; + + /* Determine architecture. */ + gdbarch = get_class_arch (values_type); + vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data); + /* If we can't find the virtual table pointer for values_type, we can't find the RTTI. */ values_type_vptr_fieldno = get_vptr_fieldno (values_type, @@ -229,8 +253,9 @@ gnuv3_rtti_type (struct value *value, } vtable_address = value_as_address (value_field (value, values_type_vptr_fieldno)); - vtable = value_at_lazy (vtable_type, - vtable_address - vtable_address_point_offset ()); + vtable + = value_at_lazy (vtable_type, + vtable_address - vtable_address_point_offset (gdbarch)); /* Find the linker symbol for this vtable. */ vtable_symbol @@ -282,10 +307,9 @@ gnuv3_rtti_type (struct value *value, vtable type for this architecture. */ static struct value * -gnuv3_get_vtable (struct value *container) +gnuv3_get_vtable (struct gdbarch *gdbarch, struct value *container) { - struct type *vtable_type = gdbarch_data (current_gdbarch, - vtable_type_gdbarch_data); + struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data); struct type *vtable_pointer_type; struct value *vtable_pointer; CORE_ADDR vtable_pointer_address, vtable_address; @@ -311,17 +335,17 @@ gnuv3_get_vtable (struct value *containe /* Correct it to point at the start of the virtual table, rather than the address point. */ return value_at_lazy (vtable_type, - vtable_address - vtable_address_point_offset ()); + vtable_address - vtable_address_point_offset (gdbarch)); } /* Return a function pointer for CONTAINER's VTABLE_INDEX'th virtual function, of type FNTYPE. */ static struct value * -gnuv3_get_virtual_fn (struct value *container, struct type *fntype, - int vtable_index) +gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container, + struct type *fntype, int vtable_index) { - struct value *vtable = gnuv3_get_vtable (container); + struct value *vtable = gnuv3_get_vtable (gdbarch, container); struct value *vfn; /* Fetch the appropriate function pointer from the vtable. */ @@ -333,7 +357,7 @@ gnuv3_get_virtual_fn (struct value *cont (i.e. points to the descriptor). We don't need to scale the index by the size of a function descriptor; GCC does that before outputing debug information. */ - if (gdbarch_vtable_function_descriptors (current_gdbarch)) + if (gdbarch_vtable_function_descriptors (gdbarch)) vfn = value_addr (vfn); /* Cast the function pointer to the appropriate type. */ @@ -351,18 +375,22 @@ gnuv3_virtual_fn_field (struct value **v struct type *vfn_base, int offset) { struct type *values_type = check_typedef (value_type (*value_p)); + struct gdbarch *gdbarch; /* Some simple sanity checks. */ if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) error (_("Only classes can have virtual functions.")); + /* Determine architecture. */ + gdbarch = get_class_arch (values_type); + /* Cast our value to the base class which defines this virtual function. This takes care of any necessary `this' adjustments. */ if (vfn_base != values_type) *value_p = value_cast (vfn_base, *value_p); - return gnuv3_get_virtual_fn (*value_p, TYPE_FN_FIELD_TYPE (f, j), + return gnuv3_get_virtual_fn (gdbarch, *value_p, TYPE_FN_FIELD_TYPE (f, j), TYPE_FN_FIELD_VOFFSET (f, j)); } @@ -377,8 +405,9 @@ static int gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr, CORE_ADDR address) { - struct type *vtable_type = gdbarch_data (current_gdbarch, - vtable_type_gdbarch_data); + struct gdbarch *gdbarch; + struct type *vtable_type; + struct type *ptr_type; struct value *vtable; struct type *vbasetype; struct value *offset_val, *vbase_array; @@ -386,6 +415,11 @@ gnuv3_baseclass_offset (struct type *typ long int cur_base_offset, base_offset; int vbasetype_vptr_fieldno; + /* Determine architecture. */ + gdbarch = get_class_arch (type); + vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data); + ptr_type = builtin_type (gdbarch)->builtin_data_ptr; + /* If it isn't a virtual base, this is easy. The offset is in the type definition. */ if (!BASETYPE_VIA_VIRTUAL (type, index)) @@ -397,14 +431,13 @@ gnuv3_baseclass_offset (struct type *typ complete inheritance graph based on the debug info. Neither is worthwhile. */ cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8; - if (cur_base_offset >= - vtable_address_point_offset ()) + if (cur_base_offset >= - vtable_address_point_offset (gdbarch)) error (_("Expected a negative vbase offset (old compiler?)")); - cur_base_offset = cur_base_offset + vtable_address_point_offset (); - if ((- cur_base_offset) % TYPE_LENGTH (builtin_type_void_data_ptr) != 0) + cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch); + if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0) error (_("Misaligned vbase offset.")); - cur_base_offset = cur_base_offset - / ((int) TYPE_LENGTH (builtin_type_void_data_ptr)); + cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type)); /* We're now looking for the cur_base_offset'th entry (negative index) in the vcall_and_vbase_offsets array. We used to cast the object to @@ -425,11 +458,11 @@ gnuv3_baseclass_offset (struct type *typ error (_("Illegal vptr offset in class %s"), TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : ""); - vtable_address = value_as_address (value_at_lazy (builtin_type_void_data_ptr, - address)); - vtable = value_at_lazy (vtable_type, - vtable_address - vtable_address_point_offset ()); - offset_val = value_from_longest(builtin_type_int32, cur_base_offset); + vtable_address = value_as_address (value_at_lazy (ptr_type, address)); + vtable + = value_at_lazy (vtable_type, + vtable_address - vtable_address_point_offset (gdbarch)); + offset_val = value_from_longest (builtin_type_int32, cur_base_offset); vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets); base_offset = value_as_long (value_subscript (vbase_array, offset_val)); return base_offset; @@ -496,6 +529,9 @@ gnuv3_print_method_ptr (const gdb_byte * struct type *type, struct ui_file *stream) { + struct gdbarch *gdbarch; + struct type *funcptr_type; + struct type *offset_type; CORE_ADDR ptr_value; LONGEST adjustment; struct type *domain; @@ -503,13 +539,17 @@ gnuv3_print_method_ptr (const gdb_byte * domain = TYPE_DOMAIN_TYPE (type); + /* Determine architecture. */ + gdbarch = get_class_arch (domain); + funcptr_type = builtin_type (gdbarch)->builtin_func_ptr; + offset_type = builtin_type (gdbarch)->builtin_long; + /* Extract the pointer to member. */ - ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr); - contents += TYPE_LENGTH (builtin_type_void_func_ptr); - adjustment = extract_signed_integer (contents, - TYPE_LENGTH (builtin_type_long)); + ptr_value = extract_typed_address (contents, funcptr_type); + contents += TYPE_LENGTH (funcptr_type); + adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type)); - if (!gdbarch_vbit_in_delta (current_gdbarch)) + if (!gdbarch_vbit_in_delta (gdbarch)) { vbit = ptr_value & 1; ptr_value = ptr_value ^ vbit; @@ -536,7 +576,7 @@ gnuv3_print_method_ptr (const gdb_byte * /* It's a virtual table offset, maybe in this class. Search for a field with the correct vtable offset. First convert it to an index, as used in TYPE_FN_FIELD_VOFFSET. */ - voffset = ptr_value / TYPE_LENGTH (builtin_type_long); + voffset = ptr_value / TYPE_LENGTH (builtin_type (gdbarch)->builtin_long); physname = gnuv3_find_method_in (domain, voffset, adjustment); @@ -575,17 +615,22 @@ gnuv3_print_method_ptr (const gdb_byte * /* GNU v3 implementation of cplus_method_ptr_size. */ static int -gnuv3_method_ptr_size (void) +gnuv3_method_ptr_size (struct type *type) { - return 2 * TYPE_LENGTH (builtin_type_void_data_ptr); + struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type)); + struct gdbarch *gdbarch = get_class_arch (domain_type); + return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr); } /* GNU v3 implementation of cplus_make_method_ptr. */ static void -gnuv3_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual) +gnuv3_make_method_ptr (struct type *type, gdb_byte *contents, + CORE_ADDR value, int is_virtual) { - int size = TYPE_LENGTH (builtin_type_void_data_ptr); + struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type)); + struct gdbarch *gdbarch = get_class_arch (domain_type); + int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr); /* FIXME drow/2006-12-24: The adjustment of "this" is currently always zero, since the method pointer is of the correct type. @@ -596,7 +641,7 @@ gnuv3_make_method_ptr (gdb_byte *content support for adjusting pointers to members when casting them - not currently supported by GDB. */ - if (!gdbarch_vbit_in_delta (current_gdbarch)) + if (!gdbarch_vbit_in_delta (gdbarch)) { store_unsigned_integer (contents, size, value | is_virtual); store_unsigned_integer (contents + size, size, 0); @@ -613,24 +658,30 @@ gnuv3_make_method_ptr (gdb_byte *content static struct value * gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr) { + struct gdbarch *gdbarch; const gdb_byte *contents = value_contents (method_ptr); CORE_ADDR ptr_value; - struct type *final_type, *method_type; + struct type *domain_type, *final_type, *method_type; + struct type *funcptr_type, *offset_type; LONGEST adjustment; struct value *adjval; int vbit; - final_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr))); - final_type = lookup_pointer_type (final_type); + domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr))); + final_type = lookup_pointer_type (domain_type); method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr))); - ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr); - contents += TYPE_LENGTH (builtin_type_void_func_ptr); - adjustment = extract_signed_integer (contents, - TYPE_LENGTH (builtin_type_long)); + /* Determine architecture. */ + gdbarch = get_class_arch (domain_type); + funcptr_type = builtin_type (gdbarch)->builtin_func_ptr; + offset_type = builtin_type (gdbarch)->builtin_long; + + ptr_value = extract_typed_address (contents, funcptr_type); + contents += TYPE_LENGTH (funcptr_type); + adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type)); - if (!gdbarch_vbit_in_delta (current_gdbarch)) + if (!gdbarch_vbit_in_delta (gdbarch)) { vbit = ptr_value & 1; ptr_value = ptr_value ^ vbit; @@ -660,15 +711,17 @@ gnuv3_method_ptr_to_value (struct value You can provoke this case by casting a Base::* to a Derived::*, for instance. */ - *this_p = value_cast (builtin_type_void_data_ptr, *this_p); - adjval = value_from_longest (builtin_type_long, adjustment); + *this_p = value_cast (builtin_type (gdbarch)->builtin_data_ptr, *this_p); + adjval = value_from_longest (offset_type, adjustment); *this_p = value_ptradd (*this_p, adjval); *this_p = value_cast (final_type, *this_p); if (vbit) { - LONGEST voffset = ptr_value / TYPE_LENGTH (builtin_type_long); - return gnuv3_get_virtual_fn (value_ind (*this_p), method_type, voffset); + LONGEST voffset; + voffset = ptr_value / TYPE_LENGTH (builtin_type (gdbarch)->builtin_long); + return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p), + method_type, voffset); } else return value_from_pointer (lookup_pointer_type (method_type), ptr_value); Index: gdb-head/gdb/valops.c =================================================================== --- gdb-head.orig/gdb/valops.c +++ gdb-head/gdb/valops.c @@ -466,7 +466,7 @@ value_cast (struct type *type, struct va && value_as_long (arg2) == 0) { struct value *result = allocate_value (type); - cplus_make_method_ptr (value_contents_writeable (result), 0, 0); + cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0); return result; } else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT @@ -2612,7 +2612,8 @@ value_struct_elt_for_reference (struct t { result = allocate_value (lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j))); - cplus_make_method_ptr (value_contents_writeable (result), + cplus_make_method_ptr (value_type (result), + value_contents_writeable (result), TYPE_FN_FIELD_VOFFSET (f, j), 1); } else if (noside == EVAL_AVOID_SIDE_EFFECTS) @@ -2635,7 +2636,8 @@ value_struct_elt_for_reference (struct t else { result = allocate_value (lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j))); - cplus_make_method_ptr (value_contents_writeable (result), + cplus_make_method_ptr (value_type (result), + value_contents_writeable (result), VALUE_ADDRESS (v), 0); } } -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com