static struct type * gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) { struct type *known_type; struct type *rtti_type; CORE_ADDR vtbl; struct minimal_symbol *minsym; char *demangled_name; struct type *btype; if (full) *full = 0; if (top) *top = -1; if (using_enc) *using_enc = 0; /* Get declared type */ known_type = value_type (v); CHECK_TYPEDEF (known_type); /* RTTI works only or class objects */ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS) return NULL; /* Plan on this changing in the future as i get around to setting the vtables properly for G++ compiled stuff. Also, I'll be using the type info functions, which are always right. Deal with it until then. JCI - This pretty much useless. This gets the "true" type correctly when there is single inheritance - but in all such cases that I could find gdb already knows that. In cases where this points INTO the object (like non-virtual diamond graphs) the demangled name is something like OUTER::INNER and this is not a symbol gdb can resolve, so we fail & return NULL anyway. Seems like this really isn't going to work till we actually call the RTTI function & parse it. */ /* If the type has no vptr fieldno, try to get it filled in */ if (TYPE_VPTR_FIELDNO(known_type) < 0) fill_in_vptr_fieldno(known_type); /* If we still can't find one, give up */ if (TYPE_VPTR_FIELDNO(known_type) < 0) return NULL; /* Make sure our basetype and known type match, otherwise, cast so we can get at the vtable properly. */ btype = TYPE_VPTR_BASETYPE (known_type); CHECK_TYPEDEF (btype); if (btype != known_type ) { v = value_cast (btype, v); if (using_enc) *using_enc=1; } /* We can't use value_ind here, because it would want to use RTTI, and we'd waste a bunch of time figuring out we already know the type. Besides, we don't care about the type, just the actual pointer */ if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0) return NULL; vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type))); /* Try to find a symbol that is the vtable */ minsym=lookup_minimal_symbol_by_pc(vtbl); if (minsym==NULL || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL || !is_vtable_name (demangled_name)) return NULL; /* If we just skip the prefix, we get screwed by namespaces */ demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI); *(strchr(demangled_name,' '))=0; /* Lookup the type for the name */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ rtti_type = cp_lookup_rtti_type (demangled_name, NULL); if (rtti_type == NULL) return NULL; if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1) { if (top) *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8; if (top && ((*top) >0)) { if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type)) { if (full) *full=0; } else { if (full) *full=1; } } } else { if (full) *full=1; } return rtti_type; }
static struct type * gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) { struct type *known_type; struct type *rtti_type; CORE_ADDR vtbl; struct bound_minimal_symbol minsym; char *demangled_name, *p; const char *linkage_name; struct type *btype; struct type *known_type_vptr_basetype; int known_type_vptr_fieldno; if (full) *full = 0; if (top) *top = -1; if (using_enc) *using_enc = 0; /* Get declared type. */ known_type = value_type (v); CHECK_TYPEDEF (known_type); /* RTTI works only or class objects. */ if (TYPE_CODE (known_type) != TYPE_CODE_STRUCT) return NULL; /* Plan on this changing in the future as i get around to setting the vtables properly for G++ compiled stuff. Also, I'll be using the type info functions, which are always right. Deal with it until then. */ /* Try to get the vptr basetype, fieldno. */ known_type_vptr_fieldno = get_vptr_fieldno (known_type, &known_type_vptr_basetype); /* If we can't find it, give up. */ if (known_type_vptr_fieldno < 0) return NULL; /* Make sure our basetype and known type match, otherwise, cast so we can get at the vtable properly. */ btype = known_type_vptr_basetype; CHECK_TYPEDEF (btype); if (btype != known_type ) { v = value_cast (btype, v); if (using_enc) *using_enc=1; } /* We can't use value_ind here, because it would want to use RTTI, and we'd waste a bunch of time figuring out we already know the type. Besides, we don't care about the type, just the actual pointer. */ if (value_address (value_field (v, known_type_vptr_fieldno)) == 0) return NULL; vtbl = value_as_address (value_field (v, known_type_vptr_fieldno)); /* Try to find a symbol that is the vtable. */ minsym=lookup_minimal_symbol_by_pc(vtbl); if (minsym.minsym==NULL || (linkage_name=MSYMBOL_LINKAGE_NAME (minsym.minsym))==NULL || !is_vtable_name (linkage_name)) return NULL; /* If we just skip the prefix, we get screwed by namespaces. */ demangled_name=gdb_demangle(linkage_name,DMGL_PARAMS|DMGL_ANSI); p = strchr (demangled_name, ' '); if (p) *p = '\0'; /* Lookup the type for the name. */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ rtti_type = cp_lookup_rtti_type (demangled_name, NULL); if (rtti_type == NULL) return NULL; if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1) { if (top) *top = TYPE_BASECLASS_BITPOS (rtti_type, TYPE_VPTR_FIELDNO(rtti_type)) / 8; if (top && ((*top) >0)) { if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type)) { if (full) *full=0; } else { if (full) *full=1; } } } else { if (full) *full=1; } return rtti_type; }
static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { struct gdbarch *gdbarch; struct type *values_type = check_typedef (value_type (value)); struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; struct type *run_time_type; LONGEST offset_to_top; char *atsign; /* We only have RTTI for class objects. */ if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) return NULL; /* Java doesn't have RTTI following the C++ ABI. */ if (TYPE_CPLUS_REALLY_JAVA (values_type)) return NULL; /* Determine architecture. */ gdbarch = get_type_arch (values_type); if (using_enc_p) *using_enc_p = 0; vtable = gnuv3_get_vtable (gdbarch, value_type (value), value_as_address (value_addr (value))); if (vtable == NULL) return NULL; /* Find the linker symbol for this vtable. */ vtable_symbol = lookup_minimal_symbol_by_pc (value_address (vtable) + value_embedded_offset (vtable)).minsym; if (! vtable_symbol) return NULL; /* The symbol's demangled name should be something like "vtable for CLASS", where CLASS is the name of the run-time type of VALUE. If we didn't like this approach, we could instead look in the type_info object itself to get the class name. But this way should work just as well, and doesn't read target memory. */ vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol); if (vtable_symbol_name == NULL || strncmp (vtable_symbol_name, "vtable for ", 11)) { warning (_("can't find linker symbol for virtual table for `%s' value"), TYPE_SAFE_NAME (values_type)); if (vtable_symbol_name) warning (_(" found `%s' instead"), vtable_symbol_name); return NULL; } class_name = vtable_symbol_name + 11; /* Strip off @plt and version suffixes. */ atsign = strchr (class_name, '@'); if (atsign != NULL) { char *copy; copy = alloca (atsign - class_name + 1); memcpy (copy, class_name, atsign - class_name); copy[atsign - class_name] = '\0'; class_name = copy; } /* Try to look up the class name as a type name. */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ run_time_type = cp_lookup_rtti_type (class_name, NULL); if (run_time_type == NULL) return NULL; /* Get the offset from VALUE to the top of the complete object. NOTE: this is the reverse of the meaning of *TOP_P. */ offset_to_top = value_as_long (value_field (vtable, vtable_field_offset_to_top)); if (full_p) *full_p = (- offset_to_top == value_embedded_offset (value) && (TYPE_LENGTH (value_enclosing_type (value)) >= TYPE_LENGTH (run_time_type))); if (top_p) *top_p = - offset_to_top; return run_time_type; }
static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { struct gdbarch *gdbarch; struct type *vtable_type; struct type *values_type = check_typedef (value_type (value)); CORE_ADDR vtable_address; struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; struct type *run_time_type; struct type *base_type; LONGEST offset_to_top; struct type *values_type_vptr_basetype; int values_type_vptr_fieldno; /* We only have RTTI for class objects. */ 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, &values_type_vptr_basetype); if (values_type_vptr_fieldno == -1) return NULL; if (using_enc_p) *using_enc_p = 0; /* 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 (values_type_vptr_basetype); 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, values_type_vptr_fieldno)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (gdbarch)); /* Find the linker symbol for this vtable. */ vtable_symbol = lookup_minimal_symbol_by_pc (value_address (vtable) + value_embedded_offset (vtable)); if (! vtable_symbol) return NULL; /* The symbol's demangled name should be something like "vtable for CLASS", where CLASS is the name of the run-time type of VALUE. If we didn't like this approach, we could instead look in the type_info object itself to get the class name. But this way should work just as well, and doesn't read target memory. */ vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol); if (vtable_symbol_name == NULL || strncmp (vtable_symbol_name, "vtable for ", 11)) { warning (_("can't find linker symbol for virtual table for `%s' value"), TYPE_NAME (values_type)); if (vtable_symbol_name) warning (_(" found `%s' instead"), vtable_symbol_name); return NULL; } class_name = vtable_symbol_name + 11; /* Try to look up the class name as a type name. */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ run_time_type = cp_lookup_rtti_type (class_name, NULL); if (run_time_type == NULL) return NULL; /* Get the offset from VALUE to the top of the complete object. NOTE: this is the reverse of the meaning of *TOP_P. */ offset_to_top = value_as_long (value_field (vtable, vtable_field_offset_to_top)); if (full_p) *full_p = (- offset_to_top == value_embedded_offset (value) && (TYPE_LENGTH (value_enclosing_type (value)) >= TYPE_LENGTH (run_time_type))); if (top_p) *top_p = - offset_to_top; return run_time_type; }