This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[09/15] Revert C++ ABI gdbarch changes
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 9 Jun 2009 17:19:15 +0200 (CEST)
- Subject: [09/15] Revert C++ ABI gdbarch changes
Hello,
this patch basically reverts the change introduced here:
http://sourceware.org/ml/gdb-patches/2008-08/msg00700.html
Now that values carry an architecture, we can simply use this
architecture to determine ABI properties of C++ objects.
This removes the need to (ab-)use the TYPE_OBJFILE of C++
types in order to retrieve those properties from the objfile
architecture.
This requires adding a gdbarch parameter to those C++ ABI
functions that do not actually get a value parameter. However,
as the call sites deal with values anyway, these are
straightforward to pass in.
In addition, two other minor changes are included:
- Provide a cplus_member_ptr_size analogous to cplus_method_ptr_size
to remove the hard-coded assumption on member pointer size from
gdbtypes.c (and make it possible to add a current_cp_abi indirection
if required in the future)
- As noone directly calls gnuv2_baseclass_offset any more, the
function can be made static and the gnu-v2-abi.h header file
can be removed.
Bye,
Ulrich
ChangeLog:
* cp-abi.h (baseclass_offset): Add GDBARCH parameter.
(cplus_print_method_ptr): Likewise.
(cplus_make_method_ptr): Likewise.
(cplus_method_ptr_size): Remove TO_TYPE, add GDBARCH parameter.
(cplus_member_ptr_size): Add prototype.
(struct cp_abi_ops): Add GDBARCH parameter to baseclass_offset,
print_method_ptr, make_method_ptr, method_ptr_size; remove TO_TYPE
parameter from method_ptr_size callback.
* cp-abi.c (baseclass_offset): Add GDBARCH parameter, pass on
to current_cp_abi callback routine.
(cplus_print_method_ptr): Likewise.
(cplus_make_method_ptr): Likewise.
(cplus_method_ptr_size): Remove TO_TYPE, add GDBARCH parameter.
Pass changes on to current_cp_abi callback routine.
(cplus_member_ptr_size): New function.
* cp-valprint.c (cp_print_value): Pass architecture to
baseclass_offset.
* p-valprint.c (pascal_object_print_value): Likewise.
* c-valprint.c (c_val_print): Pass architecture to
cplus_print_method_ptr.
* valops.c (value_cast): Pass architecture to cplus_make_method_ptr.
(value_struct_elt_for_reference): Likewise.
(search_struct_field): Pass architecture to baseclass_offset.
(search_struct_method): Likewise.
(find_method_list): Likewise.
* gdbtypes.c (lookup_methodptr_type): Pass current_gdbarch instead
of to_type to cplus_method_ptr_size.
(smash_to_memberptr_type): Call cplus_member_ptr_size.
* gnu-v2-abi.h: Remove file.
* gnu-v2-abi.c: Do not include "gnu-v2-abi.c".
(gnuv2_baseclass_offset): Make static. Add GDBARCH parameter.
Pass to baseclass_offset.
* gnu-v3-abi.c (get_class_arch): Remove.
(gnuv3_rtti_type): Use value architecture instead of get_class_arch.
(gnuv3_virtual_fn_field): Likewise.
(gnuv3_baseclass_offset): Add GDBARCH parameter. Use it instead
of get_class_arch.
(gnuv3_print_method_ptr): Likewise.
(gnuv3_make_method_ptr): Likewise.
(gnuv3_method_ptr_to_value): Likewise.
(gnuv3_method_ptr_size): Replace TO_TYPE parameter by GDBARCH.
Use it instead of get_class_arch.
Index: gdb-head/gdb/cp-abi.c
===================================================================
--- gdb-head.orig/gdb/cp-abi.c
+++ gdb-head/gdb/cp-abi.c
@@ -70,12 +70,13 @@ is_operator_name (const char *name)
}
int
-baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
- CORE_ADDR address)
+baseclass_offset (struct type *type, struct gdbarch *gdbarch, int index,
+ const bfd_byte *valaddr, CORE_ADDR address)
{
if (current_cp_abi.baseclass_offset == NULL)
error (_("ABI doesn't define required function baseclass_offset"));
- return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address);
+ return (*current_cp_abi.baseclass_offset) (type, gdbarch,
+ index, valaddr, address);
}
struct value *
@@ -105,28 +106,38 @@ value_rtti_type (struct value *v, int *f
void
cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
- struct ui_file *stream)
+ struct gdbarch *gdbarch, struct ui_file *stream)
{
if (current_cp_abi.print_method_ptr == NULL)
error (_("GDB does not support pointers to methods on this target"));
- (*current_cp_abi.print_method_ptr) (contents, type, stream);
+ (*current_cp_abi.print_method_ptr) (contents, type, gdbarch, stream);
}
int
-cplus_method_ptr_size (struct type *to_type)
+cplus_member_ptr_size (struct gdbarch *gdbarch)
+{
+ /* Assume that a data member pointer is the same size
+ as a normal pointer. */
+ return gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+}
+
+int
+cplus_method_ptr_size (struct gdbarch *gdbarch)
{
if (current_cp_abi.method_ptr_size == NULL)
error (_("GDB does not support pointers to methods on this target"));
- return (*current_cp_abi.method_ptr_size) (to_type);
+ return (*current_cp_abi.method_ptr_size) (gdbarch);
}
void
-cplus_make_method_ptr (struct type *type, gdb_byte *contents,
+cplus_make_method_ptr (gdb_byte *contents,
+ struct type *type, struct gdbarch *gdbarch,
CORE_ADDR value, int is_virtual)
{
if (current_cp_abi.make_method_ptr == NULL)
error (_("GDB does not support pointers to methods on this target"));
- (*current_cp_abi.make_method_ptr) (type, contents, value, is_virtual);
+ (*current_cp_abi.make_method_ptr) (contents, type, gdbarch,
+ value, is_virtual);
}
CORE_ADDR
Index: gdb-head/gdb/cp-abi.h
===================================================================
--- gdb-head.orig/gdb/cp-abi.h
+++ gdb-head/gdb/cp-abi.h
@@ -143,17 +143,21 @@ extern struct type *value_rtti_type (str
-1 is returned on error. */
-extern int baseclass_offset (struct type *type, int index,
+extern int baseclass_offset (struct type *type,
+ struct gdbarch *gdbarch, int index,
const bfd_byte *valaddr, CORE_ADDR address);
/* Describe the target of a pointer to method. CONTENTS is the byte
pattern representing the pointer to method. TYPE is the pointer to
method type. STREAM is the stream to print it to. */
void cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
- struct ui_file *stream);
+ struct gdbarch *gdbarch, struct ui_file *stream);
-/* Return the size of a pointer to member function of type TO_TYPE. */
-int cplus_method_ptr_size (struct type *to_type);
+/* Return the size of a pointer to data member in GDBARCH. */
+int cplus_member_ptr_size (struct gdbarch *gdbarch);
+
+/* Return the size of a pointer to member function in GDBARCH. */
+int cplus_method_ptr_size (struct gdbarch *gdbarch);
/* Return the method which should be called by applying METHOD_PTR
to *THIS_P, and adjust *THIS_P if necessary. */
@@ -164,7 +168,8 @@ struct value *cplus_method_ptr_to_value
type TYPE to member function at ADDRESS (if IS_VIRTUAL is 0)
or with virtual table offset ADDRESS (if IS_VIRTUAL is 1).
This is the opposite of cplus_method_ptr_to_value. */
-void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
+void cplus_make_method_ptr (gdb_byte *contents,
+ struct type *type, struct gdbarch *gdbarch,
CORE_ADDR address, int is_virtual);
/* Determine if we are currently in a C++ thunk. If so, get the address
@@ -191,12 +196,14 @@ struct cp_abi_ops
int j, struct type * type, int offset);
struct type *(*rtti_type) (struct value *v, int *full, int *top,
int *using_enc);
- int (*baseclass_offset) (struct type *type, int index,
+ int (*baseclass_offset) (struct type *type,
+ struct gdbarch *gdbarch, int index,
const bfd_byte *valaddr, CORE_ADDR address);
void (*print_method_ptr) (const gdb_byte *contents, struct type *type,
- struct ui_file *stream);
- int (*method_ptr_size) (struct type *);
- void (*make_method_ptr) (struct type *, gdb_byte *, CORE_ADDR, int);
+ struct gdbarch *gdbarch, struct ui_file *stream);
+ int (*method_ptr_size) (struct gdbarch *);
+ void (*make_method_ptr) (gdb_byte *, struct type *, struct gdbarch *,
+ CORE_ADDR, int);
struct value * (*method_ptr_to_value) (struct value **, struct value *);
CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
int (*pass_by_reference) (struct type *type);
Index: gdb-head/gdb/cp-valprint.c
===================================================================
--- gdb-head.orig/gdb/cp-valprint.c
+++ gdb-head/gdb/cp-valprint.c
@@ -377,7 +377,7 @@ cp_print_value (struct type *type, struc
thisoffset = offset;
thistype = real_type;
- boffset = baseclass_offset (type, i, valaddr + offset, address);
+ boffset = baseclass_offset (type, gdbarch, i, valaddr + offset, address);
skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
if (BASETYPE_VIA_VIRTUAL (type, i))
Index: gdb-head/gdb/c-valprint.c
===================================================================
--- gdb-head.orig/gdb/c-valprint.c
+++ gdb-head/gdb/c-valprint.c
@@ -219,7 +219,8 @@ c_val_print (struct type *type, struct g
break;
case TYPE_CODE_METHODPTR:
- cplus_print_method_ptr (valaddr + embedded_offset, type, stream);
+ cplus_print_method_ptr (valaddr + embedded_offset,
+ type, gdbarch, stream);
break;
case TYPE_CODE_PTR:
Index: gdb-head/gdb/gdbtypes.c
===================================================================
--- gdb-head.orig/gdb/gdbtypes.c
+++ gdb-head/gdb/gdbtypes.c
@@ -671,7 +671,7 @@ lookup_methodptr_type (struct type *to_t
mtype = alloc_type (TYPE_OBJFILE (to_type));
TYPE_TARGET_TYPE (mtype) = to_type;
TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type);
- TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type);
+ TYPE_LENGTH (mtype) = cplus_method_ptr_size (current_gdbarch);
TYPE_CODE (mtype) = TYPE_CODE_METHODPTR;
return mtype;
}
@@ -992,9 +992,7 @@ smash_to_memberptr_type (struct type *ty
TYPE_OBJFILE (type) = objfile;
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
- /* Assume that a data member pointer is the same size as a normal
- pointer. */
- TYPE_LENGTH (type) = gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+ TYPE_LENGTH (type) = cplus_member_ptr_size (current_gdbarch);
TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
}
Index: gdb-head/gdb/gnu-v2-abi.c
===================================================================
--- gdb-head.orig/gdb/gnu-v2-abi.c
+++ gdb-head/gdb/gnu-v2-abi.c
@@ -28,7 +28,6 @@
#include "demangle.h"
#include "cp-abi.h"
#include "cp-support.h"
-#include "gnu-v2-abi.h"
#include <ctype.h>
@@ -348,8 +347,8 @@ vb_match (struct type *type, int index,
-1 is returned on error. */
-int
-gnuv2_baseclass_offset (struct type *type, int index,
+static int
+gnuv2_baseclass_offset (struct type *type, struct gdbarch *gdbarch, int index,
const bfd_byte *valaddr, CORE_ADDR address)
{
struct type *basetype = TYPE_BASECLASS (type, index);
@@ -377,7 +376,7 @@ gnuv2_baseclass_offset (struct type *typ
for (i = index + 1; i < n_baseclasses; i++)
{
int boffset =
- baseclass_offset (type, i, valaddr, address);
+ baseclass_offset (type, gdbarch, i, valaddr, address);
if (boffset)
return boffset;
}
Index: gdb-head/gdb/gnu-v2-abi.h
===================================================================
--- gdb-head.orig/gdb/gnu-v2-abi.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Abstraction of GNU v2 abi.
-
- Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef GNU_V2_ABI_H
-#define GNU_V2_ABI_H
-
-extern int gnuv2_baseclass_offset (struct type *type, int index,
- const bfd_byte *valaddr,
- CORE_ADDR address);
-
-#endif
Index: gdb-head/gdb/gnu-v3-abi.c
===================================================================
--- gdb-head.orig/gdb/gnu-v3-abi.c
+++ gdb-head/gdb/gnu-v3-abi.c
@@ -45,21 +45,6 @@ gnuv3_is_operator_name (const char *name
}
-/* Determine architecture of class DOMAIN. This architecture is used
- to query C++ ABI details (types, method pointer layout, etc.).
-
- Note that we assume DOMAIN must have been allocated with an OBJFILE;
- GDB does not provide any built-in class types. Thus we use the
- architecture of that OBJFILE to define the C++ ABI. */
-
-static struct gdbarch *
-get_class_arch (struct type *domain)
-{
- gdb_assert (TYPE_CODE (domain) == TYPE_CODE_CLASS);
- gdb_assert (TYPE_OBJFILE (domain) != NULL);
- return get_objfile_arch (TYPE_OBJFILE (domain));
-}
-
/* To help us find the components of a vtable, we build ourselves a
GDB type object representing the vtable structure. Following the
V3 ABI, it goes something like this:
@@ -214,8 +199,8 @@ static struct type *
gnuv3_rtti_type (struct value *value,
int *full_p, int *top_p, int *using_enc_p)
{
- struct gdbarch *gdbarch;
- struct type *vtable_type;
+ struct gdbarch *gdbarch = value_arch (value);
+ struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
struct type *values_type = check_typedef (value_type (value));
CORE_ADDR vtable_address;
struct value *vtable;
@@ -232,16 +217,6 @@ gnuv3_rtti_type (struct value *value,
if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
return NULL;
- /* This routine may be called for Java types that do not have
- a proper objfile. Just return NULL for those. */
- if (!TYPE_OBJFILE (values_type)
- || !TYPE_OBJFILE (values_type)->obfd)
- return NULL;
-
- /* Determine architecture. */
- gdbarch = get_class_arch (values_type);
- vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
-
/* If we can't find the virtual table pointer for values_type, we
can't find the RTTI. */
values_type_vptr_fieldno = get_vptr_fieldno (values_type,
@@ -385,16 +360,13 @@ gnuv3_virtual_fn_field (struct value **v
struct fn_field *f, int j,
struct type *vfn_base, int offset)
{
+ struct gdbarch *gdbarch = value_arch (*value_p);
struct type *values_type = check_typedef (value_type (*value_p));
- struct gdbarch *gdbarch;
/* Some simple sanity checks. */
if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
error (_("Only classes can have virtual functions."));
- /* Determine architecture. */
- gdbarch = get_class_arch (values_type);
-
/* Cast our value to the base class which defines this virtual
function. This takes care of any necessary `this'
adjustments. */
@@ -413,10 +385,9 @@ gnuv3_virtual_fn_field (struct value **v
-1 is returned on error. */
static int
-gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
- CORE_ADDR address)
+gnuv3_baseclass_offset (struct type *type, struct gdbarch *gdbarch, int index,
+ const bfd_byte *valaddr, CORE_ADDR address)
{
- struct gdbarch *gdbarch;
struct type *vtable_type;
struct type *ptr_type;
struct value *vtable;
@@ -427,7 +398,6 @@ gnuv3_baseclass_offset (struct type *typ
int vbasetype_vptr_fieldno;
/* Determine architecture. */
- gdbarch = get_class_arch (type);
vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
@@ -581,10 +551,10 @@ gnuv3_decode_method_ptr (struct gdbarch
static void
gnuv3_print_method_ptr (const gdb_byte *contents,
struct type *type,
+ struct gdbarch *gdbarch,
struct ui_file *stream)
{
struct type *domain = TYPE_DOMAIN_TYPE (type);
- struct gdbarch *gdbarch = get_class_arch (domain);
CORE_ADDR ptr_value;
LONGEST adjustment;
int vbit;
@@ -647,21 +617,18 @@ gnuv3_print_method_ptr (const gdb_byte *
/* GNU v3 implementation of cplus_method_ptr_size. */
static int
-gnuv3_method_ptr_size (struct type *type)
+gnuv3_method_ptr_size (struct gdbarch *gdbarch)
{
- struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
- struct gdbarch *gdbarch = get_class_arch (domain_type);
return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
}
/* GNU v3 implementation of cplus_make_method_ptr. */
static void
-gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
+gnuv3_make_method_ptr (gdb_byte *contents,
+ struct type *type, struct gdbarch *gdbarch,
CORE_ADDR value, int is_virtual)
{
- struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
- struct gdbarch *gdbarch = get_class_arch (domain_type);
int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
/* FIXME drow/2006-12-24: The adjustment of "this" is currently
@@ -690,7 +657,7 @@ gnuv3_make_method_ptr (struct type *type
static struct value *
gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
- struct gdbarch *gdbarch;
+ struct gdbarch *gdbarch = value_arch (method_ptr);
const gdb_byte *contents = value_contents (method_ptr);
CORE_ADDR ptr_value;
struct type *domain_type, *final_type, *method_type;
@@ -704,7 +671,6 @@ gnuv3_method_ptr_to_value (struct value
method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
/* Extract the pointer to member. */
- gdbarch = get_class_arch (domain_type);
vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);
/* First convert THIS to match the containing type of the pointer to
Index: gdb-head/gdb/p-valprint.c
===================================================================
--- gdb-head.orig/gdb/p-valprint.c
+++ gdb-head/gdb/p-valprint.c
@@ -873,7 +873,7 @@ pascal_object_print_value (struct type *
obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
}
- boffset = baseclass_offset (type, i, valaddr, address);
+ boffset = baseclass_offset (type, gdbarch, i, valaddr, address);
if (options->pretty)
{
Index: gdb-head/gdb/valops.c
===================================================================
--- gdb-head.orig/gdb/valops.c
+++ gdb-head/gdb/valops.c
@@ -470,7 +470,8 @@ value_cast (struct type *type, struct va
&& value_as_long (arg2) == 0)
{
struct value *result = allocate_value (type, value_arch (arg2));
- cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0);
+ cplus_make_method_ptr (value_contents_writeable (result),
+ type, value_arch (arg2), 0, 0);
return result;
}
else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT
@@ -1592,7 +1593,7 @@ search_struct_field (char *name, struct
int boffset;
struct value *v2;
- boffset = baseclass_offset (type, i,
+ boffset = baseclass_offset (type, value_arch (arg1), i,
value_contents (arg1) + offset,
value_address (arg1) + offset);
if (boffset == -1)
@@ -1747,7 +1748,8 @@ search_struct_method (char *name, struct
else
base_valaddr = value_contents (*arg1p) + offset;
- base_offset = baseclass_offset (type, i, base_valaddr,
+ base_offset = baseclass_offset (type, value_arch (*arg1p), i,
+ base_valaddr,
value_address (*arg1p) + offset);
if (base_offset == -1)
error (_("virtual baseclass botch"));
@@ -1955,7 +1957,7 @@ find_method_list (struct value **argp, c
if (BASETYPE_VIA_VIRTUAL (type, i))
{
base_offset = value_offset (*argp) + offset;
- base_offset = baseclass_offset (type, i,
+ base_offset = baseclass_offset (type, value_arch (*argp), i,
value_contents (*argp) + base_offset,
value_address (*argp) + base_offset);
if (base_offset == -1)
@@ -2693,8 +2695,9 @@ value_struct_elt_for_reference (struct g
{
ptr = lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j));
result = allocate_value (ptr, gdbarch);
- cplus_make_method_ptr (value_type (result),
- value_contents_writeable (result),
+ cplus_make_method_ptr (value_contents_writeable (result),
+ value_type (result),
+ value_arch (result),
TYPE_FN_FIELD_VOFFSET (f, j), 1);
}
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
@@ -2718,8 +2721,9 @@ value_struct_elt_for_reference (struct g
{
ptr = lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j));
result = allocate_value (ptr, gdbarch);
- cplus_make_method_ptr (value_type (result),
- value_contents_writeable (result),
+ cplus_make_method_ptr (value_contents_writeable (result),
+ value_type (result),
+ value_arch (result),
value_address (v), 0);
}
}
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com