diff options
author | Daniel Jacobowitz <drow@false.org> | 2002-07-05 16:23:13 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2002-07-05 16:23:13 +0000 |
commit | 79d5b63a4560a9be0c4bbcfc38c7615cd13b735e (patch) | |
tree | 1fe4df6c5e4211a6dd6b199ed278f8530a448656 /gdb/gnu-v3-abi.c | |
parent | 3bb912e83b95feffd211a80f5308ce32b6fcbec8 (diff) | |
download | gdb-79d5b63a4560a9be0c4bbcfc38c7615cd13b735e.zip gdb-79d5b63a4560a9be0c4bbcfc38c7615cd13b735e.tar.gz gdb-79d5b63a4560a9be0c4bbcfc38c7615cd13b735e.tar.bz2 |
2002-07-05 Daniel Jacobowitz <drow@mvista.com>
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.
Diffstat (limited to 'gdb/gnu-v3-abi.c')
-rw-r--r-- | gdb/gnu-v3-abi.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index e86af89..a9ab494 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) : "<unknown>"); + + 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); |