* gnu-v3-abi.c (vtable_ptrdiff_type): New function.
(gnuv3_decode_method_ptr, gnuv3_print_method_ptr) (gnuv3_method_ptr_to_value): Use a better approximation for `ptrdiff_t' instead of `long'. * m32c-tdep.c (m32c_gdbarch_init): Call set_gdbarch_vbit_in_delta(). (m32c_push_dummy_call): Dereference pointer type.
This commit is contained in:
parent
36dcf92c3e
commit
ed09d7da47
3 changed files with 39 additions and 3 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
2008-12-12 Kevin Buettner <kevinb@redhat.com>
|
||||||
|
|
||||||
|
* gnu-v3-abi.c (vtable_ptrdiff_type): New function.
|
||||||
|
(gnuv3_decode_method_ptr, gnuv3_print_method_ptr)
|
||||||
|
(gnuv3_method_ptr_to_value): Use a better approximation for
|
||||||
|
`ptrdiff_t' instead of `long'.
|
||||||
|
|
||||||
|
2008-12-12 Kevin Buettner <kevinb@redhat.com>
|
||||||
|
|
||||||
|
* m32c-tdep.c (m32c_gdbarch_init): Call set_gdbarch_vbit_in_delta().
|
||||||
|
(m32c_push_dummy_call): Dereference pointer type.
|
||||||
|
|
||||||
2008-12-12 Tom Tromey <tromey@redhat.com>
|
2008-12-12 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
PR cli/2563:
|
PR cli/2563:
|
||||||
|
|
|
@ -187,6 +187,16 @@ build_gdb_vtable_type (struct gdbarch *arch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the ptrdiff_t type used in the vtable type. */
|
||||||
|
static struct type *
|
||||||
|
vtable_ptrdiff_type (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
|
||||||
|
|
||||||
|
/* The "offset_to_top" field has the appropriate (ptrdiff_t) type. */
|
||||||
|
return TYPE_FIELD_TYPE (vtable_type, vtable_field_offset_to_top);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the offset from the start of the imaginary `struct
|
/* Return the offset from the start of the imaginary `struct
|
||||||
gdb_gnu_v3_abi_vtable' object to the vtable's "address point"
|
gdb_gnu_v3_abi_vtable' object to the vtable's "address point"
|
||||||
(i.e., where objects' virtual table pointers point). */
|
(i.e., where objects' virtual table pointers point). */
|
||||||
|
@ -531,7 +541,7 @@ gnuv3_decode_method_ptr (struct gdbarch *gdbarch,
|
||||||
LONGEST *adjustment_p)
|
LONGEST *adjustment_p)
|
||||||
{
|
{
|
||||||
struct type *funcptr_type = builtin_type (gdbarch)->builtin_func_ptr;
|
struct type *funcptr_type = builtin_type (gdbarch)->builtin_func_ptr;
|
||||||
struct type *offset_type = builtin_type (gdbarch)->builtin_long;
|
struct type *offset_type = vtable_ptrdiff_type (gdbarch);
|
||||||
CORE_ADDR ptr_value;
|
CORE_ADDR ptr_value;
|
||||||
LONGEST voffset, adjustment;
|
LONGEST voffset, adjustment;
|
||||||
int vbit;
|
int vbit;
|
||||||
|
@ -595,7 +605,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
|
||||||
/* It's a virtual table offset, maybe in this class. Search
|
/* It's a virtual table offset, maybe in this class. Search
|
||||||
for a field with the correct vtable offset. First convert it
|
for a field with the correct vtable offset. First convert it
|
||||||
to an index, as used in TYPE_FN_FIELD_VOFFSET. */
|
to an index, as used in TYPE_FN_FIELD_VOFFSET. */
|
||||||
voffset = ptr_value / TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
|
voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
|
||||||
|
|
||||||
physname = gnuv3_find_method_in (domain, voffset, adjustment);
|
physname = gnuv3_find_method_in (domain, voffset, adjustment);
|
||||||
|
|
||||||
|
@ -722,7 +732,7 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
|
||||||
if (vbit)
|
if (vbit)
|
||||||
{
|
{
|
||||||
LONGEST voffset;
|
LONGEST voffset;
|
||||||
voffset = ptr_value / TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
|
voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
|
||||||
return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
|
return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
|
||||||
method_type, voffset);
|
method_type, voffset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2018,6 +2018,10 @@ m32c_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||||
{
|
{
|
||||||
struct type *func_type = value_type (function);
|
struct type *func_type = value_type (function);
|
||||||
|
|
||||||
|
/* Dereference function pointer types. */
|
||||||
|
if (TYPE_CODE (func_type) == TYPE_CODE_PTR)
|
||||||
|
func_type = TYPE_TARGET_TYPE (func_type);
|
||||||
|
|
||||||
gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC ||
|
gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC ||
|
||||||
TYPE_CODE (func_type) == TYPE_CODE_METHOD);
|
TYPE_CODE (func_type) == TYPE_CODE_METHOD);
|
||||||
|
|
||||||
|
@ -2596,6 +2600,16 @@ m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
|
|
||||||
set_gdbarch_virtual_frame_pointer (arch, m32c_virtual_frame_pointer);
|
set_gdbarch_virtual_frame_pointer (arch, m32c_virtual_frame_pointer);
|
||||||
|
|
||||||
|
/* m32c function boundary addresses are not necessarily even.
|
||||||
|
Therefore, the `vbit', which indicates a pointer to a virtual
|
||||||
|
member function, is stored in the delta field, rather than as
|
||||||
|
the low bit of a function pointer address.
|
||||||
|
|
||||||
|
In order to verify this, see the definition of
|
||||||
|
TARGET_PTRMEMFUNC_VBIT_LOCATION in gcc/defaults.h along with the
|
||||||
|
definition of FUNCTION_BOUNDARY in gcc/config/m32c/m32c.h. */
|
||||||
|
set_gdbarch_vbit_in_delta (arch, 1);
|
||||||
|
|
||||||
return arch;
|
return arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue