From ed09d7da47719a337ed84148e371691270ac17a5 Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Sat, 13 Dec 2008 00:39:53 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 12 ++++++++++++ gdb/gnu-v3-abi.c | 16 +++++++++++++--- gdb/m32c-tdep.c | 14 ++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 68c9fb93245..2b28d737135 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2008-12-12 Kevin Buettner + + * 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 + + * m32c-tdep.c (m32c_gdbarch_init): Call set_gdbarch_vbit_in_delta(). + (m32c_push_dummy_call): Dereference pointer type. + 2008-12-12 Tom Tromey PR cli/2563: diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index c2c348a6103..1027baf70ac 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -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 gdb_gnu_v3_abi_vtable' object to the vtable's "address point" (i.e., where objects' virtual table pointers point). */ @@ -531,7 +541,7 @@ gnuv3_decode_method_ptr (struct gdbarch *gdbarch, LONGEST *adjustment_p) { 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; LONGEST voffset, adjustment; 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 for a field with the correct vtable offset. First convert it 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); @@ -722,7 +732,7 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr) if (vbit) { 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), method_type, voffset); } diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c index b8cd1675c31..2dc41d34d01 100644 --- a/gdb/m32c-tdep.c +++ b/gdb/m32c-tdep.c @@ -2018,6 +2018,10 @@ m32c_push_dummy_call (struct gdbarch *gdbarch, struct value *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 || 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); + /* 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; } -- 2.30.2