* [rfc] Use proper extraction routine for C++ pointer-to-method types
@ 2008-09-04 1:44 Ulrich Weigand
2008-09-04 12:18 ` Daniel Jacobowitz
0 siblings, 1 reply; 3+ messages in thread
From: Ulrich Weigand @ 2008-09-04 1:44 UTC (permalink / raw)
To: gdb-patches
Hello,
the first element of a C++ "pointer-to-method" is either a pointer to
a function, or else an integer representing an offset into the vtable.
The routines in gnu-v3-abi.c currently use extract_typed_address to
retrieve that value, which is certainly correct for the case of a
pointer to (non-virtual) function.
However, on platforms with nontrivial pointer_to_address conversions
this routine (which calls gdbarch_pointer_to_address) may do the
wrong thing for vtable offsets, which need to be treated as integers.
The following patch fixes this by using the appropriate extraction
routine for either variant. To reduce code duplication, the code to
perform this conversion is extracted into a new routine.
Tested on powerpc-linux, powerpc64-linux, and spu-elf with no regression.
Any comments on this?
Bye,
Ulrich
ChangeLog:
* gnu-v3-abi.c (gnuv3_decode_method_ptr): New function.
(gnuv3_print_method_ptr): Use it.
(gnuv3_method_ptr_to_value): Likewise.
Index: src/gdb/gnu-v3-abi.c
===================================================================
--- src.orig/gdb/gnu-v3-abi.c
+++ src/gdb/gnu-v3-abi.c
@@ -489,6 +489,46 @@ gnuv3_find_method_in (struct type *domai
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. */
static void
@@ -504,21 +544,7 @@ gnuv3_print_method_ptr (const gdb_byte *
domain = TYPE_DOMAIN_TYPE (type);
/* Extract the pointer to member. */
- ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
- 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;
- }
+ vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
/* Check for NULL. */
if (ptr_value == 0 && vbit == 0)
@@ -625,21 +651,8 @@ gnuv3_method_ptr_to_value (struct value
method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
- ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
- 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;
- }
+ /* Extract the pointer to member. */
+ vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
/* First convert THIS to match the containing type of the pointer to
member. This cast may adjust the value of THIS. */
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [rfc] Use proper extraction routine for C++ pointer-to-method types
2008-09-04 1:44 [rfc] Use proper extraction routine for C++ pointer-to-method types Ulrich Weigand
@ 2008-09-04 12:18 ` Daniel Jacobowitz
2008-09-05 11:54 ` Ulrich Weigand
0 siblings, 1 reply; 3+ messages in thread
From: Daniel Jacobowitz @ 2008-09-04 12:18 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches
On Thu, Sep 04, 2008 at 03:43:09AM +0200, Ulrich Weigand wrote:
> Any comments on this?
I think this is OK - thanks!
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [rfc] Use proper extraction routine for C++ pointer-to-method types
2008-09-04 12:18 ` Daniel Jacobowitz
@ 2008-09-05 11:54 ` Ulrich Weigand
0 siblings, 0 replies; 3+ messages in thread
From: Ulrich Weigand @ 2008-09-05 11:54 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
> On Thu, Sep 04, 2008 at 03:43:09AM +0200, Ulrich Weigand wrote:
> > Any comments on this?
>
> I think this is OK - thanks!
Checked in, thanks!
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-09-05 11:54 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-04 1:44 [rfc] Use proper extraction routine for C++ pointer-to-method types Ulrich Weigand
2008-09-04 12:18 ` Daniel Jacobowitz
2008-09-05 11:54 ` Ulrich Weigand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox