* gnu-v3-abi.c (vtable_ptrdiff_type): New function.
authorKevin Buettner <kevinb@redhat.com>
Sat, 13 Dec 2008 00:39:53 +0000 (00:39 +0000)
committerKevin Buettner <kevinb@redhat.com>
Sat, 13 Dec 2008 00:39:53 +0000 (00:39 +0000)
(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
gdb/gnu-v3-abi.c
gdb/m32c-tdep.c

index 68c9fb9..2b28d73 100644 (file)
@@ -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>
 
        PR cli/2563:
index c2c348a..1027baf 100644 (file)
@@ -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);
     }
index b8cd167..2dc41d3 100644 (file)
@@ -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;
 }