aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Bothner <per@bothner.com>1994-05-05 00:19:33 +0000
committerPer Bothner <per@bothner.com>1994-05-05 00:19:33 +0000
commit36a2283dad09124b2d980d10adfca84d31aaedcb (patch)
tree4f5c5c0cfbe4d19d0640f1b50d34372ab24ae551
parentd32a92614da2060c30a286d11bfb03146bc8dca6 (diff)
downloadgdb-36a2283dad09124b2d980d10adfca84d31aaedcb.zip
gdb-36a2283dad09124b2d980d10adfca84d31aaedcb.tar.gz
gdb-36a2283dad09124b2d980d10adfca84d31aaedcb.tar.bz2
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.
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/c-valprint.c11
-rw-r--r--gdb/cp-valprint.c35
-rw-r--r--gdb/stabsread.c8
-rw-r--r--gdb/values.c29
5 files changed, 75 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 06b1277..5aacf29 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 0eb3133..cea6889 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 c3bb3a4..0a4c841 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 da4632f..a1b1775 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 244d877..1c833af 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. */