From 79d5b63a4560a9be0c4bbcfc38c7615cd13b735e Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Fri, 5 Jul 2002 16:23:13 +0000 Subject: [PATCH] 2002-07-05 Daniel Jacobowitz Fix PR gdb/595, gdb/602 * gnu-v3-abi.c (gnuv3_baseclass_offset): Remove unused variables. Don't call value_cast, just read the vtable pointer; update comments to match. --- gdb/ChangeLog | 7 +++++++ gdb/gnu-v3-abi.c | 33 ++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cddf6595be9..f1b366bb28f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2002-07-05 Daniel Jacobowitz + + Fix PR gdb/595, gdb/602 + * gnu-v3-abi.c (gnuv3_baseclass_offset): Remove unused variables. + Don't call value_cast, just read the vtable pointer; update comments + to match. + 2002-07-05 Grace Sainsbury * config/mcore/tm-mcore.h: Remove file. diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index e86af89d557..a9ab4941cfd 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -374,15 +374,11 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr, { struct type *vtable_type = gdbarch_data (current_gdbarch, vtable_type_gdbarch_data); - struct type *basetype = TYPE_BASECLASS (type, index); - struct value *full_object, *vbase_object, *orig_object; - struct value *vtable, *orig_typeinfo, *orig_base_info; - struct type *orig_type, *vbasetype; + struct value *vtable; + struct type *vbasetype; struct value *offset_val, *vbase_array; CORE_ADDR vtable_address; long int cur_base_offset, base_offset; - int to_top; - int baseclasses, i; /* If it isn't a virtual base, this is easy. The offset is in the type definition. */ @@ -405,15 +401,22 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr, / ((int) TYPE_LENGTH (builtin_type_void_data_ptr)); /* We're now looking for the cur_base_offset'th entry (negative index) - in the vcall_and_vbase_offsets array. */ - - orig_object = value_at_lazy (type, address, NULL); - vbasetype = TYPE_VPTR_BASETYPE (VALUE_TYPE (orig_object)); - vbase_object = value_cast (vbasetype, orig_object); - - vtable_address - = value_as_address (value_field (vbase_object, - TYPE_VPTR_FIELDNO (vbasetype))); + in the vcall_and_vbase_offsets array. We used to cast the object to + its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO; + however, that cast can not be done without calling baseclass_offset again + if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the + v3 C++ ABI Section 2.4.I.2.b. Fortunately the ABI guarantees that the + vtable pointer will be located at the beginning of the object, so we can + bypass the casting. Verify that the TYPE_VPTR_FIELDNO is in fact at the + start of whichever baseclass it resides in, as a sanity measure. */ + + vbasetype = TYPE_VPTR_BASETYPE (type); + if (TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0) + 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, NULL)); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (), NULL); -- 2.30.2