* gnu-v3-abi.c (gnuv3_decode_method_ptr): New function.
(gnuv3_print_method_ptr): Use it. (gnuv3_method_ptr_to_value): Likewise.
This commit is contained in:
parent
60441ab9ed
commit
fead690896
2 changed files with 49 additions and 30 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2008-09-05 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* gnu-v3-abi.c (gnuv3_decode_method_ptr): New function.
|
||||||
|
(gnuv3_print_method_ptr): Use it.
|
||||||
|
(gnuv3_method_ptr_to_value): Likewise.
|
||||||
|
|
||||||
2008-09-05 Ulrich Weigand <uweigand@de.ibm.com>
|
2008-09-05 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
* nto-tdep.h (struct nto_target_ops): Add gdbarch parameter to
|
* nto-tdep.h (struct nto_target_ops): Add gdbarch parameter to
|
||||||
|
|
|
@ -489,6 +489,46 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Decode GNU v3 method pointer. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
gnuv3_decode_method_ptr (const gdb_byte *contents,
|
||||||
|
CORE_ADDR *value_p,
|
||||||
|
LONGEST *adjustment_p)
|
||||||
|
{
|
||||||
|
struct type *funcptr_type = builtin_type_void_func_ptr;
|
||||||
|
struct type *offset_type = builtin_type_long;
|
||||||
|
CORE_ADDR ptr_value;
|
||||||
|
LONGEST voffset, adjustment;
|
||||||
|
int vbit;
|
||||||
|
|
||||||
|
/* Extract the pointer to member. The first element is either a pointer
|
||||||
|
or a vtable offset. For pointers, we need to use extract_typed_address
|
||||||
|
to allow the back-end to convert the pointer to a GDB address -- but
|
||||||
|
vtable offsets we must handle as integers. At this point, we do not
|
||||||
|
yet know which case we have, so we extract the value under both
|
||||||
|
interpretations and choose the right one later on. */
|
||||||
|
ptr_value = extract_typed_address (contents, funcptr_type);
|
||||||
|
voffset = extract_signed_integer (contents, TYPE_LENGTH (funcptr_type));
|
||||||
|
contents += TYPE_LENGTH (funcptr_type);
|
||||||
|
adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type));
|
||||||
|
|
||||||
|
if (!gdbarch_vbit_in_delta (current_gdbarch))
|
||||||
|
{
|
||||||
|
vbit = voffset & 1;
|
||||||
|
voffset = voffset ^ vbit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vbit = adjustment & 1;
|
||||||
|
adjustment = adjustment >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value_p = vbit? voffset : ptr_value;
|
||||||
|
*adjustment_p = adjustment;
|
||||||
|
return vbit;
|
||||||
|
}
|
||||||
|
|
||||||
/* GNU v3 implementation of cplus_print_method_ptr. */
|
/* GNU v3 implementation of cplus_print_method_ptr. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -504,21 +544,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
|
||||||
domain = TYPE_DOMAIN_TYPE (type);
|
domain = TYPE_DOMAIN_TYPE (type);
|
||||||
|
|
||||||
/* Extract the pointer to member. */
|
/* Extract the pointer to member. */
|
||||||
ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
|
vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
|
||||||
contents += TYPE_LENGTH (builtin_type_void_func_ptr);
|
|
||||||
adjustment = extract_signed_integer (contents,
|
|
||||||
TYPE_LENGTH (builtin_type_long));
|
|
||||||
|
|
||||||
if (!gdbarch_vbit_in_delta (current_gdbarch))
|
|
||||||
{
|
|
||||||
vbit = ptr_value & 1;
|
|
||||||
ptr_value = ptr_value ^ vbit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vbit = adjustment & 1;
|
|
||||||
adjustment = adjustment >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for NULL. */
|
/* Check for NULL. */
|
||||||
if (ptr_value == 0 && vbit == 0)
|
if (ptr_value == 0 && vbit == 0)
|
||||||
|
@ -625,21 +651,8 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
|
||||||
|
|
||||||
method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
|
method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
|
||||||
|
|
||||||
ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
|
/* Extract the pointer to member. */
|
||||||
contents += TYPE_LENGTH (builtin_type_void_func_ptr);
|
vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
|
||||||
adjustment = extract_signed_integer (contents,
|
|
||||||
TYPE_LENGTH (builtin_type_long));
|
|
||||||
|
|
||||||
if (!gdbarch_vbit_in_delta (current_gdbarch))
|
|
||||||
{
|
|
||||||
vbit = ptr_value & 1;
|
|
||||||
ptr_value = ptr_value ^ vbit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vbit = adjustment & 1;
|
|
||||||
adjustment = adjustment >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First convert THIS to match the containing type of the pointer to
|
/* First convert THIS to match the containing type of the pointer to
|
||||||
member. This cast may adjust the value of THIS. */
|
member. This cast may adjust the value of THIS. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue