From 36a2283dad09124b2d980d10adfca84d31aaedcb Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Thu, 5 May 1994 00:19:33 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 16 ++++++++++++++++ gdb/c-valprint.c | 11 +++++++++++ gdb/cp-valprint.c | 35 +++++++++++++++++++++-------------- gdb/stabsread.c | 8 +++++++- gdb/values.c | 29 ++++++++++++++++++++--------- 5 files changed, 75 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 06b1277fd7d..5aacf297f46 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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) * valprint.c (print_longest): Clarify comment about use_local. diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 0eb313370a0..cea68899e93 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -146,6 +146,15 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse, print_scalar_formatted (valaddr, type, format, 0, stream); 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) { 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)) { /* 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 */ TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)), stream, demangle); diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index c3bb3a4411b..0a4c841fc0c 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -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 "pointer to virtual function". */ @@ -158,12 +165,6 @@ cp_is_vtbl_ptr_type(type) struct type *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 && (STREQ (typename, vtbl_ptr_name) @@ -178,14 +179,20 @@ cp_is_vtbl_member(type) struct type *type; { if (TYPE_CODE (type) == TYPE_CODE_PTR) - type = TYPE_TARGET_TYPE (type); - else - return 0; - - if (TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT) - /* Virtual functions tables are full of pointers to virtual functions. */ - return cp_is_vtbl_ptr_type (TYPE_TARGET_TYPE (type)); + { + type = TYPE_TARGET_TYPE (type); + if (TYPE_CODE (type) == TYPE_CODE_ARRAY) + { + type = TYPE_TARGET_TYPE (type); + if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */ + || 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); + } + } + } return 0; } diff --git a/gdb/stabsread.c b/gdb/stabsread.c index da4632f5679..a1b1775af8b 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -1075,7 +1075,13 @@ define_symbol (valu, string, desc, type, objfile) 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) { /* If we are giving a name to a type such as "pointer to diff --git a/gdb/values.c b/gdb/values.c index 244d877fb6b..1c833af52c8 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -880,16 +880,23 @@ value_virtual_fn_field (arg1p, f, j, type, offset) a virtual function. */ entry = value_subscript (vtbl, vi); - /* Move the `this' pointer according to the virtual function table. */ - VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0))/* + offset*/; - - if (! VALUE_LAZY (arg1)) + if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_STRUCT) { - VALUE_LAZY (arg1) = 1; - value_fetch_lazy (arg1); - } + /* Move the `this' pointer according to the virtual function table. */ + VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)); + + if (! VALUE_LAZY (arg1)) + { + VALUE_LAZY (arg1) = 1; + value_fetch_lazy (arg1); + } - 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. */ 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. */ msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl)); 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 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, (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))); /* If we use '<=' we can handle single inheritance * where all offsets are zero - just use the first entry found. */ -- 2.30.2