From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21429 invoked by alias); 4 Sep 2008 01:44:06 -0000 Received: (qmail 21417 invoked by uid 22791); 4 Sep 2008 01:44:05 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate1.de.ibm.com (HELO mtagate1.de.ibm.com) (195.212.17.161) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 04 Sep 2008 01:43:13 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate1.de.ibm.com (8.13.1/8.13.1) with ESMTP id m841hAAE022270 for ; Thu, 4 Sep 2008 01:43:10 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v9.0) with ESMTP id m841hAr43133576 for ; Thu, 4 Sep 2008 03:43:10 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m841h93f013013 for ; Thu, 4 Sep 2008 03:43:10 +0200 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id m841h9mH013010 for ; Thu, 4 Sep 2008 03:43:09 +0200 Message-Id: <200809040143.m841h9mH013010@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Thu, 4 Sep 2008 03:43:09 +0200 Subject: [rfc] Use proper extraction routine for C++ pointer-to-method types To: gdb-patches@sourceware.org Date: Thu, 04 Sep 2008 01:44:00 -0000 From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-09/txt/msg00059.txt.bz2 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