Add partial support for g++ code compiled with -fvtable-thunks.
* c-valprint.c (c_val_print): Add vtblprint support when using thunks. * cp-valprint.c (cp_is_vtbl_member): A vtable can be an array of pointers (if using thunks) as well as array of structs (otherwise). * cp-valprint.c (vtbl_ptr_name_old, vtbl_ptr_name): Move to global level, and make the latter non-static (so define_symbol can use it). * stabsread.c (define_symbol): If the type being defined is a pointer type named "__vtbl_ptr_type", set the TYPE_NAME to that name. * symtab.h (VTBL_PREFIX_P): Allow "_VT" as well as "_vt". * values.c (value_virtual_fn_field): Handle thunks. * values.c (value_headof): Minor efficiency hack. * values.c (value_headof): Incomplete thunk support. FIXME.
This commit is contained in:
parent
d32a92614d
commit
36a2283dad
5 changed files with 75 additions and 24 deletions
|
@ -1,3 +1,19 @@
|
||||||
|
Wed May 4 15:30:39 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||||
|
|
||||||
|
Add partial support for g++ code compiled with -fvtable-thunks.
|
||||||
|
* c-valprint.c (c_val_print): Add vtblprint support
|
||||||
|
when using thunks.
|
||||||
|
* cp-valprint.c (cp_is_vtbl_member): A vtable can be an array of
|
||||||
|
pointers (if using thunks) as well as array of structs (otherwise).
|
||||||
|
* cp-valprint.c (vtbl_ptr_name_old, vtbl_ptr_name): Move to global
|
||||||
|
level, and make the latter non-static (so define_symbol can use it).
|
||||||
|
* stabsread.c (define_symbol): If the type being defined is a
|
||||||
|
pointer type named "__vtbl_ptr_type", set the TYPE_NAME to that name.
|
||||||
|
* symtab.h (VTBL_PREFIX_P): Allow "_VT" as well as "_vt".
|
||||||
|
* values.c (value_virtual_fn_field): Handle thunks.
|
||||||
|
* values.c (value_headof): Minor efficiency hack.
|
||||||
|
* values.c (value_headof): Incomplete thunk support. FIXME.
|
||||||
|
|
||||||
Wed May 4 06:56:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
|
Wed May 4 06:56:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
|
||||||
|
|
||||||
* valprint.c (print_longest): Clarify comment about use_local.
|
* valprint.c (print_longest): Clarify comment about use_local.
|
||||||
|
|
|
@ -146,6 +146,15 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (vtblprint && cp_is_vtbl_ptr_type(type))
|
||||||
|
{
|
||||||
|
/* Print the unmangled name if desired. */
|
||||||
|
/* Print vtable entry - we only get here if we ARE using
|
||||||
|
-fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
|
||||||
|
print_address_demangle(extract_address (valaddr, TYPE_LENGTH (type)),
|
||||||
|
stream, demangle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
|
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
|
||||||
{
|
{
|
||||||
cp_print_class_method (valaddr, type, stream);
|
cp_print_class_method (valaddr, type, stream);
|
||||||
|
@ -290,6 +299,8 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||||
if (vtblprint && cp_is_vtbl_ptr_type(type))
|
if (vtblprint && cp_is_vtbl_ptr_type(type))
|
||||||
{
|
{
|
||||||
/* Print the unmangled name if desired. */
|
/* Print the unmangled name if desired. */
|
||||||
|
/* Print vtable entry - we only get here if NOT using
|
||||||
|
-fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
|
||||||
print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
|
print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
|
||||||
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
|
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
|
||||||
stream, demangle);
|
stream, demangle);
|
||||||
|
|
|
@ -150,6 +150,13 @@ cp_print_class_method (valaddr, type, stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This was what it was for gcc 2.4.5 and earlier. */
|
||||||
|
static const char vtbl_ptr_name_old[] =
|
||||||
|
{ CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
|
||||||
|
/* It was changed to this after 2.4.5. */
|
||||||
|
const char vtbl_ptr_name[] =
|
||||||
|
{ '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
|
||||||
|
|
||||||
/* Return truth value for assertion that TYPE is of the type
|
/* Return truth value for assertion that TYPE is of the type
|
||||||
"pointer to virtual function". */
|
"pointer to virtual function". */
|
||||||
|
|
||||||
|
@ -158,12 +165,6 @@ cp_is_vtbl_ptr_type(type)
|
||||||
struct type *type;
|
struct type *type;
|
||||||
{
|
{
|
||||||
char *typename = type_name_no_tag (type);
|
char *typename = type_name_no_tag (type);
|
||||||
/* This was what it was for gcc 2.4.5 and earlier. */
|
|
||||||
static const char vtbl_ptr_name_old[] =
|
|
||||||
{ CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
|
|
||||||
/* It was changed to this after 2.4.5. */
|
|
||||||
static const char vtbl_ptr_name[] =
|
|
||||||
{ '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
|
|
||||||
|
|
||||||
return (typename != NULL
|
return (typename != NULL
|
||||||
&& (STREQ (typename, vtbl_ptr_name)
|
&& (STREQ (typename, vtbl_ptr_name)
|
||||||
|
@ -178,14 +179,20 @@ cp_is_vtbl_member(type)
|
||||||
struct type *type;
|
struct type *type;
|
||||||
{
|
{
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||||
|
{
|
||||||
type = TYPE_TARGET_TYPE (type);
|
type = TYPE_TARGET_TYPE (type);
|
||||||
else
|
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||||
return 0;
|
{
|
||||||
|
type = TYPE_TARGET_TYPE (type);
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_ARRAY
|
if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */
|
||||||
&& TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)
|
|| TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
|
||||||
/* Virtual functions tables are full of pointers to virtual functions. */
|
{
|
||||||
return cp_is_vtbl_ptr_type (TYPE_TARGET_TYPE (type));
|
/* Virtual functions tables are full of pointers
|
||||||
|
to virtual functions. */
|
||||||
|
return cp_is_vtbl_ptr_type (type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1075,7 +1075,13 @@ define_symbol (valu, string, desc, type, objfile)
|
||||||
|
|
||||||
if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL)
|
if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL)
|
||||||
{
|
{
|
||||||
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
|
/* gcc-2.6 or later (when using -fvtable-thunks)
|
||||||
|
emits a unique named type for a vtable entry.
|
||||||
|
Some gdb code depends on that specific name. */
|
||||||
|
extern const char vtbl_ptr_name[];
|
||||||
|
|
||||||
|
if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
|
||||||
|
&& strcmp (SYMBOL_NAME (sym), vtbl_ptr_name))
|
||||||
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
|
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
|
||||||
{
|
{
|
||||||
/* If we are giving a name to a type such as "pointer to
|
/* If we are giving a name to a type such as "pointer to
|
||||||
|
|
15
gdb/values.c
15
gdb/values.c
|
@ -880,8 +880,10 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
|
||||||
a virtual function. */
|
a virtual function. */
|
||||||
entry = value_subscript (vtbl, vi);
|
entry = value_subscript (vtbl, vi);
|
||||||
|
|
||||||
|
if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_STRUCT)
|
||||||
|
{
|
||||||
/* Move the `this' pointer according to the virtual function table. */
|
/* Move the `this' pointer according to the virtual function table. */
|
||||||
VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0))/* + offset*/;
|
VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
|
||||||
|
|
||||||
if (! VALUE_LAZY (arg1))
|
if (! VALUE_LAZY (arg1))
|
||||||
{
|
{
|
||||||
|
@ -890,6 +892,11 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
vfn = value_field (entry, 2);
|
vfn = value_field (entry, 2);
|
||||||
|
}
|
||||||
|
else if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_PTR)
|
||||||
|
vfn = entry;
|
||||||
|
else
|
||||||
|
error ("I'm confused: virtual function table has bad type");
|
||||||
/* Reinstantiate the function pointer with the correct type. */
|
/* Reinstantiate the function pointer with the correct type. */
|
||||||
VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
|
VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
|
||||||
|
|
||||||
|
@ -931,7 +938,8 @@ value_headof (in_arg, btype, dtype)
|
||||||
/* Check that VTBL looks like it points to a virtual function table. */
|
/* Check that VTBL looks like it points to a virtual function table. */
|
||||||
msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl));
|
msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl));
|
||||||
if (msymbol == NULL
|
if (msymbol == NULL
|
||||||
|| !VTBL_PREFIX_P (demangled_name = SYMBOL_NAME (msymbol)))
|
|| (demangled_name = SYMBOL_NAME (msymbol)) == NULL
|
||||||
|
|| !VTBL_PREFIX_P (demangled_name))
|
||||||
{
|
{
|
||||||
/* If we expected to find a vtable, but did not, let the user
|
/* If we expected to find a vtable, but did not, let the user
|
||||||
know that we aren't happy, but don't throw an error.
|
know that we aren't happy, but don't throw an error.
|
||||||
|
@ -950,6 +958,9 @@ value_headof (in_arg, btype, dtype)
|
||||||
{
|
{
|
||||||
entry = value_subscript (vtbl, value_from_longest (builtin_type_int,
|
entry = value_subscript (vtbl, value_from_longest (builtin_type_int,
|
||||||
(LONGEST) i));
|
(LONGEST) i));
|
||||||
|
/* This won't work if we're using thunks. */
|
||||||
|
if (TYPE_CODE (VALUE_TYPE (entry)) != TYPE_CODE_STRUCT)
|
||||||
|
break;
|
||||||
offset = longest_to_int (value_as_long (value_field (entry, 0)));
|
offset = longest_to_int (value_as_long (value_field (entry, 0)));
|
||||||
/* If we use '<=' we can handle single inheritance
|
/* If we use '<=' we can handle single inheritance
|
||||||
* where all offsets are zero - just use the first entry found. */
|
* where all offsets are zero - just use the first entry found. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue