/* Abstraction of GNU v3 abi.
   Contributed by Jim Blandy <jimb@redhat.com>

   Copyright (C) 2001-2017 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/>.  */

#include "defs.h"
#include "value.h"
#include "cp-abi.h"
#include "cp-support.h"
#include "demangle.h"
#include "objfiles.h"
#include "valprint.h"
#include "c-lang.h"
#include "typeprint.h"
#include <algorithm>

static struct cp_abi_ops gnu_v3_abi_ops;

/* A gdbarch key for std::type_info, in the event that it can't be
   found in the debug info.  */

static struct gdbarch_data *std_type_info_gdbarch_data;


static int
gnuv3_is_vtable_name (const char *name)
{
  return startswith (name, "_ZTV");
}

static int
gnuv3_is_operator_name (const char *name)
{
  return startswith (name, CP_OPERATOR_STR);
}


/* 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:

   struct gdb_gnu_v3_abi_vtable {

     / * An array of virtual call and virtual base offsets.  The real
         length of this array depends on the class hierarchy; we use
         negative subscripts to access the elements.  Yucky, but
         better than the alternatives.  * /
     ptrdiff_t vcall_and_vbase_offsets[0];

     / * The offset from a virtual pointer referring to this table
         to the top of the complete object.  * /
     ptrdiff_t offset_to_top;

     / * The type_info pointer for this class.  This is really a
         std::type_info *, but GDB doesn't really look at the
         type_info object itself, so we don't bother to get the type
         exactly right.  * /
     void *type_info;

     / * Virtual table pointers in objects point here.  * /

     / * Virtual function pointers.  Like the vcall/vbase array, the
         real length of this table depends on the class hierarchy.  * /
     void (*virtual_functions[0]) ();

   };

   The catch, of course, is that the exact layout of this table
   depends on the ABI --- word size, endianness, alignment, etc.  So
   the GDB type object is actually a per-architecture kind of thing.

   vtable_type_gdbarch_data is a gdbarch per-architecture data pointer
   which refers to the struct type * for this structure, laid out
   appropriately for the architecture.  */
static struct gdbarch_data *vtable_type_gdbarch_data;


/* Human-readable names for the numbers of the fields above.  */
enum {
  vtable_field_vcall_and_vbase_offsets,
  vtable_field_offset_to_top,
  vtable_field_type_info,
  vtable_field_virtual_functions
};


/* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable',
   described above, laid out appropriately for ARCH.

   We use this function as the gdbarch per-architecture data
   initialization function.  */
static void *
build_gdb_vtable_type (struct gdbarch *arch)
{
  struct type *t;
  struct field *field_list, *field;
  int offset;

  struct type *void_ptr_type
    = builtin_type (arch)->builtin_data_ptr;
  struct type *ptr_to_void_fn_type
    = builtin_type (arch)->builtin_func_ptr;

  /* ARCH can't give us the true ptrdiff_t type, so we guess.  */
  struct type *ptrdiff_type
    = arch_integer_type (arch, gdbarch_ptr_bit (arch), 0, "ptrdiff_t");

  /* We assume no padding is necessary, since GDB doesn't know
     anything about alignment at the moment.  If this assumption bites
     us, we should add a gdbarch method which, given a type, returns
     the alignment that type requires, and then use that here.  */

  /* Build the field list.  */
  field_list = XCNEWVEC (struct field, 4);
  field = &field_list[0];
  offset = 0;

  /* ptrdiff_t vcall_and_vbase_offsets[0]; */
  FIELD_NAME (*field) = "vcall_and_vbase_offsets";
  FIELD_TYPE (*field) = lookup_array_range_type (ptrdiff_type, 0, -1);
  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
  offset += TYPE_LENGTH (FIELD_TYPE (*field));
  field++;

  /* ptrdiff_t offset_to_top; */
  FIELD_NAME (*field) = "offset_to_top";
  FIELD_TYPE (*field) = ptrdiff_type;
  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
  offset += TYPE_LENGTH (FIELD_TYPE (*field));
  field++;

  /* void *type_info; */
  FIELD_NAME (*field) = "type_info";
  FIELD_TYPE (*field) = void_ptr_type;
  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
  offset += TYPE_LENGTH (FIELD_TYPE (*field));
  field++;

  /* void (*virtual_functions[0]) (); */
  FIELD_NAME (*field) = "virtual_functions";
  FIELD_TYPE (*field) = lookup_array_range_type (ptr_to_void_fn_type, 0, -1);
  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
  offset += TYPE_LENGTH (FIELD_TYPE (*field));
  field++;

  /* We assumed in the allocation above that there were four fields.  */
  gdb_assert (field == (field_list + 4));

  t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
  TYPE_NFIELDS (t) = field - field_list;
  TYPE_FIELDS (t) = field_list;
  TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable";
  INIT_CPLUS_SPECIFIC (t);

  return make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
}


/* Return the ptrdiff_t type used in the vtable type.  */
static struct type *
vtable_ptrdiff_type (struct gdbarch *gdbarch)
{
  struct type *vtable_type
    = (struct 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).  */
static int
vtable_address_point_offset (struct gdbarch *gdbarch)
{
  struct type *vtable_type
    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);

  return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
          / TARGET_CHAR_BIT);
}


/* Determine whether structure TYPE is a dynamic class.  Cache the
   result.  */

static int
gnuv3_dynamic_class (struct type *type)
{
  int fieldnum, fieldelem;

  type = check_typedef (type);
  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
	      || TYPE_CODE (type) == TYPE_CODE_UNION);

  if (TYPE_CODE (type) == TYPE_CODE_UNION)
    return 0;

  if (TYPE_CPLUS_DYNAMIC (type))
    return TYPE_CPLUS_DYNAMIC (type) == 1;

  ALLOCATE_CPLUS_STRUCT_TYPE (type);

  for (fieldnum = 0; fieldnum < TYPE_N_BASECLASSES (type); fieldnum++)
    if (BASETYPE_VIA_VIRTUAL (type, fieldnum)
	|| gnuv3_dynamic_class (TYPE_FIELD_TYPE (type, fieldnum)))
      {
	TYPE_CPLUS_DYNAMIC (type) = 1;
	return 1;
      }

  for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
    for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
	 fieldelem++)
      {
	struct fn_field *f = TYPE_FN_FIELDLIST1 (type, fieldnum);

	if (TYPE_FN_FIELD_VIRTUAL_P (f, fieldelem))
	  {
	    TYPE_CPLUS_DYNAMIC (type) = 1;
	    return 1;
	  }
      }

  TYPE_CPLUS_DYNAMIC (type) = -1;
  return 0;
}

/* Find the vtable for a value of CONTAINER_TYPE located at
   CONTAINER_ADDR.  Return a value of the correct vtable type for this
   architecture, or NULL if CONTAINER does not have a vtable.  */

static struct value *
gnuv3_get_vtable (struct gdbarch *gdbarch,
		  struct type *container_type, CORE_ADDR container_addr)
{
  struct type *vtable_type
    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
  struct type *vtable_pointer_type;
  struct value *vtable_pointer;
  CORE_ADDR vtable_address;

  container_type = check_typedef (container_type);
  gdb_assert (TYPE_CODE (container_type) == TYPE_CODE_STRUCT);

  /* If this type does not have a virtual table, don't read the first
     field.  */
  if (!gnuv3_dynamic_class (container_type))
    return NULL;

  /* We do not consult the debug information to find the virtual table.
     The ABI specifies that it is always at offset zero in any class,
     and debug information may not represent it.

     We avoid using value_contents on principle, because the object might
     be large.  */

  /* Find the type "pointer to virtual table".  */
  vtable_pointer_type = lookup_pointer_type (vtable_type);

  /* Load it from the start of the class.  */
  vtable_pointer = value_at (vtable_pointer_type, container_addr);
  vtable_address = value_as_address (vtable_pointer);

  /* Correct it to point at the start of the virtual table, rather
     than the address point.  */
  return value_at_lazy (vtable_type,
			vtable_address
			- vtable_address_point_offset (gdbarch));
}


static struct type *
gnuv3_rtti_type (struct value *value,
                 int *full_p, LONGEST *top_p, int *using_enc_p)
{
  struct gdbarch *gdbarch;
  struct type *values_type = check_typedef (value_type (value));
  struct value *vtable;
  struct minimal_symbol *vtable_symbol;
  const char *vtable_symbol_name;
  const char *class_name;
  struct type *run_time_type;
  LONGEST offset_to_top;
  const char *atsign;

  /* We only have RTTI for class objects.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
    return NULL;

  /* Determine architecture.  */
  gdbarch = get_type_arch (values_type);

  if (using_enc_p)
    *using_enc_p = 0;

  vtable = gnuv3_get_vtable (gdbarch, values_type,
			     value_as_address (value_addr (value)));
  if (vtable == NULL)
    return NULL;

  /* Find the linker symbol for this vtable.  */
  vtable_symbol
    = lookup_minimal_symbol_by_pc (value_address (vtable)
                                   + value_embedded_offset (vtable)).minsym;
  if (! vtable_symbol)
    return NULL;
  
  /* The symbol's demangled name should be something like "vtable for
     CLASS", where CLASS is the name of the run-time type of VALUE.
     If we didn't like this approach, we could instead look in the
     type_info object itself to get the class name.  But this way
     should work just as well, and doesn't read target memory.  */
  vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
  if (vtable_symbol_name == NULL
      || !startswith (vtable_symbol_name, "vtable for "))
    {
      warning (_("can't find linker symbol for virtual table for `%s' value"),
	       TYPE_SAFE_NAME (values_type));
      if (vtable_symbol_name)
	warning (_("  found `%s' instead"), vtable_symbol_name);
      return NULL;
    }
  class_name = vtable_symbol_name + 11;

  /* Strip off @plt and version suffixes.  */
  atsign = strchr (class_name, '@');
  if (atsign != NULL)
    {
      char *copy;

      copy = (char *) alloca (atsign - class_name + 1);
      memcpy (copy, class_name, atsign - class_name);
      copy[atsign - class_name] = '\0';
      class_name = copy;
    }

  /* Try to look up the class name as a type name.  */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465.  */
  run_time_type = cp_lookup_rtti_type (class_name, NULL);
  if (run_time_type == NULL)
    return NULL;

  /* Get the offset from VALUE to the top of the complete object.
     NOTE: this is the reverse of the meaning of *TOP_P.  */
  offset_to_top
    = value_as_long (value_field (vtable, vtable_field_offset_to_top));

  if (full_p)
    *full_p = (- offset_to_top == value_embedded_offset (value)
               && (TYPE_LENGTH (value_enclosing_type (value))
                   >= TYPE_LENGTH (run_time_type)));
  if (top_p)
    *top_p = - offset_to_top;
  return run_time_type;
}

/* Return a function pointer for CONTAINER's VTABLE_INDEX'th virtual
   function, of type FNTYPE.  */

static struct value *
gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
		      struct type *fntype, int vtable_index)
{
  struct value *vtable, *vfn;

  /* Every class with virtual functions must have a vtable.  */
  vtable = gnuv3_get_vtable (gdbarch, value_type (container),
			     value_as_address (value_addr (container)));
  gdb_assert (vtable != NULL);

  /* Fetch the appropriate function pointer from the vtable.  */
  vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
                         vtable_index);

  /* If this architecture uses function descriptors directly in the vtable,
     then the address of the vtable entry is actually a "function pointer"
     (i.e. points to the descriptor).  We don't need to scale the index
     by the size of a function descriptor; GCC does that before outputing
     debug information.  */
  if (gdbarch_vtable_function_descriptors (gdbarch))
    vfn = value_addr (vfn);

  /* Cast the function pointer to the appropriate type.  */
  vfn = value_cast (lookup_pointer_type (fntype), vfn);

  return vfn;
}

/* GNU v3 implementation of value_virtual_fn_field.  See cp-abi.h
   for a description of the arguments.  */

static struct value *
gnuv3_virtual_fn_field (struct value **value_p,
                        struct fn_field *f, int j,
			struct type *vfn_base, int offset)
{
  struct type *values_type = check_typedef (value_type (*value_p));
  struct gdbarch *gdbarch;

  /* Some simple sanity checks.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
    error (_("Only classes can have virtual functions."));

  /* Determine architecture.  */
  gdbarch = get_type_arch (values_type);

  /* Cast our value to the base class which defines this virtual
     function.  This takes care of any necessary `this'
     adjustments.  */
  if (vfn_base != values_type)
    *value_p = value_cast (vfn_base, *value_p);

  return gnuv3_get_virtual_fn (gdbarch, *value_p, TYPE_FN_FIELD_TYPE (f, j),
			       TYPE_FN_FIELD_VOFFSET (f, j));
}

/* Compute the offset of the baseclass which is
   the INDEXth baseclass of class TYPE,
   for value at VALADDR (in host) at ADDRESS (in target).
   The result is the offset of the baseclass value relative
   to (the address of)(ARG) + OFFSET.

   -1 is returned on error.  */

static int
gnuv3_baseclass_offset (struct type *type, int index,
			const bfd_byte *valaddr, LONGEST embedded_offset,
			CORE_ADDR address, const struct value *val)
{
  struct gdbarch *gdbarch;
  struct type *ptr_type;
  struct value *vtable;
  struct value *vbase_array;
  long int cur_base_offset, base_offset;

  /* Determine architecture.  */
  gdbarch = get_type_arch (type);
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;

  /* If it isn't a virtual base, this is easy.  The offset is in the
     type definition.  */
  if (!BASETYPE_VIA_VIRTUAL (type, index))
    return TYPE_BASECLASS_BITPOS (type, index) / 8;

  /* To access a virtual base, we need to use the vbase offset stored in
     our vtable.  Recent GCC versions provide this information.  If it isn't
     available, we could get what we needed from RTTI, or from drawing the
     complete inheritance graph based on the debug info.  Neither is
     worthwhile.  */
  cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8;
  if (cur_base_offset >= - vtable_address_point_offset (gdbarch))
    error (_("Expected a negative vbase offset (old compiler?)"));

  cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch);
  if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0)
    error (_("Misaligned vbase offset."));
  cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type));

  vtable = gnuv3_get_vtable (gdbarch, type, address + embedded_offset);
  gdb_assert (vtable != NULL);
  vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
  base_offset = value_as_long (value_subscript (vbase_array, cur_base_offset));
  return base_offset;
}

/* Locate a virtual method in DOMAIN or its non-virtual base classes
   which has virtual table index VOFFSET.  The method has an associated
   "this" adjustment of ADJUSTMENT bytes.  */

static const char *
gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset,
		      LONGEST adjustment)
{
  int i;

  /* Search this class first.  */
  if (adjustment == 0)
    {
      int len;

      len = TYPE_NFN_FIELDS (domain);
      for (i = 0; i < len; i++)
	{
	  int len2, j;
	  struct fn_field *f;

	  f = TYPE_FN_FIELDLIST1 (domain, i);
	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);

	  check_stub_method_group (domain, i);
	  for (j = 0; j < len2; j++)
	    if (TYPE_FN_FIELD_VOFFSET (f, j) == voffset)
	      return TYPE_FN_FIELD_PHYSNAME (f, j);
	}
    }

  /* Next search non-virtual bases.  If it's in a virtual base,
     we're out of luck.  */
  for (i = 0; i < TYPE_N_BASECLASSES (domain); i++)
    {
      int pos;
      struct type *basetype;

      if (BASETYPE_VIA_VIRTUAL (domain, i))
	continue;

      pos = TYPE_BASECLASS_BITPOS (domain, i) / 8;
      basetype = TYPE_FIELD_TYPE (domain, i);
      /* Recurse with a modified adjustment.  We don't need to adjust
	 voffset.  */
      if (adjustment >= pos && adjustment < pos + TYPE_LENGTH (basetype))
	return gnuv3_find_method_in (basetype, voffset, adjustment - pos);
    }

  return NULL;
}

/* Decode GNU v3 method pointer.  */

static int
gnuv3_decode_method_ptr (struct gdbarch *gdbarch,
			 const gdb_byte *contents,
			 CORE_ADDR *value_p,
			 LONGEST *adjustment_p)
{
  struct type *funcptr_type = builtin_type (gdbarch)->builtin_func_ptr;
  struct type *offset_type = vtable_ptrdiff_type (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  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), byte_order);
  contents += TYPE_LENGTH (funcptr_type);
  adjustment = extract_signed_integer (contents,
				       TYPE_LENGTH (offset_type), byte_order);

  if (!gdbarch_vbit_in_delta (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
gnuv3_print_method_ptr (const gdb_byte *contents,
			struct type *type,
			struct ui_file *stream)
{
  struct type *self_type = TYPE_SELF_TYPE (type);
  struct gdbarch *gdbarch = get_type_arch (self_type);
  CORE_ADDR ptr_value;
  LONGEST adjustment;
  int vbit;

  /* Extract the pointer to member.  */
  vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);

  /* Check for NULL.  */
  if (ptr_value == 0 && vbit == 0)
    {
      fprintf_filtered (stream, "NULL");
      return;
    }

  /* Search for a virtual method.  */
  if (vbit)
    {
      CORE_ADDR voffset;
      const char *physname;

      /* 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 (vtable_ptrdiff_type (gdbarch));

      physname = gnuv3_find_method_in (self_type, voffset, adjustment);

      /* If we found a method, print that.  We don't bother to disambiguate
	 possible paths to the method based on the adjustment.  */
      if (physname)
	{
	  char *demangled_name = gdb_demangle (physname,
					       DMGL_ANSI | DMGL_PARAMS);

	  fprintf_filtered (stream, "&virtual ");
	  if (demangled_name == NULL)
	    fputs_filtered (physname, stream);
	  else
	    {
	      fputs_filtered (demangled_name, stream);
	      xfree (demangled_name);
	    }
	  return;
	}
    }
  else if (ptr_value != 0)
    {
      /* Found a non-virtual function: print out the type.  */
      fputs_filtered ("(", stream);
      c_print_type (type, "", stream, -1, 0, &type_print_raw_options);
      fputs_filtered (") ", stream);
    }

  /* We didn't find it; print the raw data.  */
  if (vbit)
    {
      fprintf_filtered (stream, "&virtual table offset ");
      print_longest (stream, 'd', 1, ptr_value);
    }
  else
    {
      struct value_print_options opts;

      get_user_print_options (&opts);
      print_address_demangle (&opts, gdbarch, ptr_value, stream, demangle);
    }

  if (adjustment)
    {
      fprintf_filtered (stream, ", this adjustment ");
      print_longest (stream, 'd', 1, adjustment);
    }
}

/* GNU v3 implementation of cplus_method_ptr_size.  */

static int
gnuv3_method_ptr_size (struct type *type)
{
  struct gdbarch *gdbarch = get_type_arch (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,
		       CORE_ADDR value, int is_virtual)
{
  struct gdbarch *gdbarch = get_type_arch (type);
  int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* FIXME drow/2006-12-24: The adjustment of "this" is currently
     always zero, since the method pointer is of the correct type.
     But if the method pointer came from a base class, this is
     incorrect - it should be the offset to the base.  The best
     fix might be to create the pointer to member pointing at the
     base class and cast it to the derived class, but that requires
     support for adjusting pointers to members when casting them -
     not currently supported by GDB.  */

  if (!gdbarch_vbit_in_delta (gdbarch))
    {
      store_unsigned_integer (contents, size, byte_order, value | is_virtual);
      store_unsigned_integer (contents + size, size, byte_order, 0);
    }
  else
    {
      store_unsigned_integer (contents, size, byte_order, value);
      store_unsigned_integer (contents + size, size, byte_order, is_virtual);
    }
}

/* GNU v3 implementation of cplus_method_ptr_to_value.  */

static struct value *
gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
  struct gdbarch *gdbarch;
  const gdb_byte *contents = value_contents (method_ptr);
  CORE_ADDR ptr_value;
  struct type *self_type, *final_type, *method_type;
  LONGEST adjustment;
  int vbit;

  self_type = TYPE_SELF_TYPE (check_typedef (value_type (method_ptr)));
  final_type = lookup_pointer_type (self_type);

  method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));

  /* Extract the pointer to member.  */
  gdbarch = get_type_arch (self_type);
  vbit = gnuv3_decode_method_ptr (gdbarch, 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.  */
  *this_p = value_cast (final_type, *this_p);

  /* Then apply whatever adjustment is necessary.  This creates a somewhat
     strange pointer: it claims to have type FINAL_TYPE, but in fact it
     might not be a valid FINAL_TYPE.  For instance, it might be a
     base class of FINAL_TYPE.  And if it's not the primary base class,
     then printing it out as a FINAL_TYPE object would produce some pretty
     garbage.

     But we don't really know the type of the first argument in
     METHOD_TYPE either, which is why this happens.  We can't
     dereference this later as a FINAL_TYPE, but once we arrive in the
     called method we'll have debugging information for the type of
     "this" - and that'll match the value we produce here.

     You can provoke this case by casting a Base::* to a Derived::*, for
     instance.  */
  *this_p = value_cast (builtin_type (gdbarch)->builtin_data_ptr, *this_p);
  *this_p = value_ptradd (*this_p, adjustment);
  *this_p = value_cast (final_type, *this_p);

  if (vbit)
    {
      LONGEST voffset;

      voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
      return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
				   method_type, voffset);
    }
  else
    return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
}

/* Objects of this type are stored in a hash table and a vector when
   printing the vtables for a class.  */

struct value_and_voffset
{
  /* The value representing the object.  */
  struct value *value;

  /* The maximum vtable offset we've found for any object at this
     offset in the outermost object.  */
  int max_voffset;
};

/* Hash function for value_and_voffset.  */

static hashval_t
hash_value_and_voffset (const void *p)
{
  const struct value_and_voffset *o = (const struct value_and_voffset *) p;

  return value_address (o->value) + value_embedded_offset (o->value);
}

/* Equality function for value_and_voffset.  */

static int
eq_value_and_voffset (const void *a, const void *b)
{
  const struct value_and_voffset *ova = (const struct value_and_voffset *) a;
  const struct value_and_voffset *ovb = (const struct value_and_voffset *) b;

  return (value_address (ova->value) + value_embedded_offset (ova->value)
	  == value_address (ovb->value) + value_embedded_offset (ovb->value));
}

/* Comparison function for value_and_voffset.  */

static bool
compare_value_and_voffset (const struct value_and_voffset *va,
			   const struct value_and_voffset *vb)
{
  CORE_ADDR addra = (value_address (va->value)
		     + value_embedded_offset (va->value));
  CORE_ADDR addrb = (value_address (vb->value)
		     + value_embedded_offset (vb->value));

  return addra < addrb;
}

/* A helper function used when printing vtables.  This determines the
   key (most derived) sub-object at each address and also computes the
   maximum vtable offset seen for the corresponding vtable.  Updates
   OFFSET_HASH and OFFSET_VEC with a new value_and_voffset object, if
   needed.  VALUE is the object to examine.  */

static void
compute_vtable_size (htab_t offset_hash,
		     std::vector<value_and_voffset *> *offset_vec,
		     struct value *value)
{
  int i;
  struct type *type = check_typedef (value_type (value));
  void **slot;
  struct value_and_voffset search_vo, *current_vo;

  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);

  /* If the object is not dynamic, then we are done; as it cannot have
     dynamic base types either.  */
  if (!gnuv3_dynamic_class (type))
    return;

  /* Update the hash and the vec, if needed.  */
  search_vo.value = value;
  slot = htab_find_slot (offset_hash, &search_vo, INSERT);
  if (*slot)
    current_vo = (struct value_and_voffset *) *slot;
  else
    {
      current_vo = XNEW (struct value_and_voffset);
      current_vo->value = value;
      current_vo->max_voffset = -1;
      *slot = current_vo;
      offset_vec->push_back (current_vo);
    }

  /* Update the value_and_voffset object with the highest vtable
     offset from this class.  */
  for (i = 0; i < TYPE_NFN_FIELDS (type); ++i)
    {
      int j;
      struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, i);

      for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
	{
	  if (TYPE_FN_FIELD_VIRTUAL_P (fn, j))
	    {
	      int voffset = TYPE_FN_FIELD_VOFFSET (fn, j);

	      if (voffset > current_vo->max_voffset)
		current_vo->max_voffset = voffset;
	    }
	}
    }

  /* Recurse into base classes.  */
  for (i = 0; i < TYPE_N_BASECLASSES (type); ++i)
    compute_vtable_size (offset_hash, offset_vec, value_field (value, i));
}

/* Helper for gnuv3_print_vtable that prints a single vtable.  */

static void
print_one_vtable (struct gdbarch *gdbarch, struct value *value,
		  int max_voffset,
		  struct value_print_options *opts)
{
  int i;
  struct type *type = check_typedef (value_type (value));
  struct value *vtable;
  CORE_ADDR vt_addr;

  vtable = gnuv3_get_vtable (gdbarch, type,
			     value_address (value)
			     + value_embedded_offset (value));
  vt_addr = value_address (value_field (vtable,
					vtable_field_virtual_functions));

  printf_filtered (_("vtable for '%s' @ %s (subobject @ %s):\n"),
		   TYPE_SAFE_NAME (type),
		   paddress (gdbarch, vt_addr),
		   paddress (gdbarch, (value_address (value)
				       + value_embedded_offset (value))));

  for (i = 0; i <= max_voffset; ++i)
    {
      /* Initialize it just to avoid a GCC false warning.  */
      CORE_ADDR addr = 0;
      int got_error = 0;
      struct value *vfn;

      printf_filtered ("[%d]: ", i);

      vfn = value_subscript (value_field (vtable,
					  vtable_field_virtual_functions),
			     i);

      if (gdbarch_vtable_function_descriptors (gdbarch))
	vfn = value_addr (vfn);

      TRY
	{
	  addr = value_as_address (vfn);
	}
      CATCH (ex, RETURN_MASK_ERROR)
	{
	  printf_filtered (_("<error: %s>"), ex.message);
	  got_error = 1;
	}
      END_CATCH

      if (!got_error)
	print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
      printf_filtered ("\n");
    }
}

/* Implementation of the print_vtable method.  */

static void
gnuv3_print_vtable (struct value *value)
{
  struct gdbarch *gdbarch;
  struct type *type;
  struct value *vtable;
  struct value_print_options opts;
  int count;

  value = coerce_ref (value);
  type = check_typedef (value_type (value));
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
    {
      value = value_ind (value);
      type = check_typedef (value_type (value));
    }

  get_user_print_options (&opts);

  /* Respect 'set print object'.  */
  if (opts.objectprint)
    {
      value = value_full_object (value, NULL, 0, 0, 0);
      type = check_typedef (value_type (value));
    }

  gdbarch = get_type_arch (type);

  vtable = NULL;
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
    vtable = gnuv3_get_vtable (gdbarch, type,
			       value_as_address (value_addr (value)));

  if (!vtable)
    {
      printf_filtered (_("This object does not have a virtual function table\n"));
      return;
    }

  htab_up offset_hash (htab_create_alloc (1, hash_value_and_voffset,
					  eq_value_and_voffset,
					  xfree, xcalloc, xfree));
  std::vector<value_and_voffset *> result_vec;

  compute_vtable_size (offset_hash.get (), &result_vec, value);
  std::sort (result_vec.begin (), result_vec.end (),
	     compare_value_and_voffset);

  count = 0;
  for (value_and_voffset *iter : result_vec)
    {
      if (iter->max_voffset >= 0)
	{
	  if (count > 0)
	    printf_filtered ("\n");
	  print_one_vtable (gdbarch, iter->value, iter->max_voffset, &opts);
	  ++count;
	}
    }
}

/* Return a GDB type representing `struct std::type_info', laid out
   appropriately for ARCH.

   We use this function as the gdbarch per-architecture data
   initialization function.  */

static void *
build_std_type_info_type (struct gdbarch *arch)
{
  struct type *t;
  struct field *field_list, *field;
  int offset;
  struct type *void_ptr_type
    = builtin_type (arch)->builtin_data_ptr;
  struct type *char_type
    = builtin_type (arch)->builtin_char;
  struct type *char_ptr_type
    = make_pointer_type (make_cv_type (1, 0, char_type, NULL), NULL);

  field_list = XCNEWVEC (struct field, 2);
  field = &field_list[0];
  offset = 0;

  /* The vtable.  */
  FIELD_NAME (*field) = "_vptr.type_info";
  FIELD_TYPE (*field) = void_ptr_type;
  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
  offset += TYPE_LENGTH (FIELD_TYPE (*field));
  field++;

  /* The name.  */
  FIELD_NAME (*field) = "__name";
  FIELD_TYPE (*field) = char_ptr_type;
  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
  offset += TYPE_LENGTH (FIELD_TYPE (*field));
  field++;

  gdb_assert (field == (field_list + 2));

  t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
  TYPE_NFIELDS (t) = field - field_list;
  TYPE_FIELDS (t) = field_list;
  TYPE_TAG_NAME (t) = "gdb_gnu_v3_type_info";
  INIT_CPLUS_SPECIFIC (t);

  return t;
}

/* Implement the 'get_typeid_type' method.  */

static struct type *
gnuv3_get_typeid_type (struct gdbarch *gdbarch)
{
  struct symbol *typeinfo;
  struct type *typeinfo_type;

  typeinfo = lookup_symbol ("std::type_info", NULL, STRUCT_DOMAIN,
			    NULL).symbol;
  if (typeinfo == NULL)
    typeinfo_type
      = (struct type *) gdbarch_data (gdbarch, std_type_info_gdbarch_data);
  else
    typeinfo_type = SYMBOL_TYPE (typeinfo);

  return typeinfo_type;
}

/* Implement the 'get_typeid' method.  */

static struct value *
gnuv3_get_typeid (struct value *value)
{
  struct type *typeinfo_type;
  struct type *type;
  struct gdbarch *gdbarch;
  struct value *result;
  std::string type_name, canonical;

  /* We have to handle values a bit trickily here, to allow this code
     to work properly with non_lvalue values that are really just
     disguised types.  */
  if (value_lval_const (value) == lval_memory)
    value = coerce_ref (value);

  type = check_typedef (value_type (value));

  /* In the non_lvalue case, a reference might have slipped through
     here.  */
  if (TYPE_CODE (type) == TYPE_CODE_REF)
    type = check_typedef (TYPE_TARGET_TYPE (type));

  /* Ignore top-level cv-qualifiers.  */
  type = make_cv_type (0, 0, type, NULL);
  gdbarch = get_type_arch (type);

  type_name = type_to_string (type);
  if (type_name.empty ())
    error (_("cannot find typeinfo for unnamed type"));

  /* We need to canonicalize the type name here, because we do lookups
     using the demangled name, and so we must match the format it
     uses.  E.g., GDB tends to use "const char *" as a type name, but
     the demangler uses "char const *".  */
  canonical = cp_canonicalize_string (type_name.c_str ());
  if (!canonical.empty ())
    type_name = canonical;

  typeinfo_type = gnuv3_get_typeid_type (gdbarch);

  /* We check for lval_memory because in the "typeid (type-id)" case,
     the type is passed via a not_lval value object.  */
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
      && value_lval_const (value) == lval_memory
      && gnuv3_dynamic_class (type))
    {
      struct value *vtable, *typeinfo_value;
      CORE_ADDR address = value_address (value) + value_embedded_offset (value);

      vtable = gnuv3_get_vtable (gdbarch, type, address);
      if (vtable == NULL)
	error (_("cannot find typeinfo for object of type '%s'"),
	       type_name.c_str ());
      typeinfo_value = value_field (vtable, vtable_field_type_info);
      result = value_ind (value_cast (make_pointer_type (typeinfo_type, NULL),
				      typeinfo_value));
    }
  else
    {
      std::string sym_name = std::string ("typeinfo for ") + type_name;
      bound_minimal_symbol minsym
	= lookup_minimal_symbol (sym_name.c_str (), NULL, NULL);

      if (minsym.minsym == NULL)
	error (_("could not find typeinfo symbol for '%s'"), type_name.c_str ());

      result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym));
    }

  return result;
}

/* Implement the 'get_typename_from_type_info' method.  */

static std::string
gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
{
  struct gdbarch *gdbarch = get_type_arch (value_type (type_info_ptr));
  struct bound_minimal_symbol typeinfo_sym;
  CORE_ADDR addr;
  const char *symname;
  const char *class_name;
  const char *atsign;

  addr = value_as_address (type_info_ptr);
  typeinfo_sym = lookup_minimal_symbol_by_pc (addr);
  if (typeinfo_sym.minsym == NULL)
    error (_("could not find minimal symbol for typeinfo address %s"),
	   paddress (gdbarch, addr));

#define TYPEINFO_PREFIX "typeinfo for "
#define TYPEINFO_PREFIX_LEN (sizeof (TYPEINFO_PREFIX) - 1)
  symname = MSYMBOL_DEMANGLED_NAME (typeinfo_sym.minsym);
  if (symname == NULL || strncmp (symname, TYPEINFO_PREFIX,
				  TYPEINFO_PREFIX_LEN))
    error (_("typeinfo symbol '%s' has unexpected name"),
	   MSYMBOL_LINKAGE_NAME (typeinfo_sym.minsym));
  class_name = symname + TYPEINFO_PREFIX_LEN;

  /* Strip off @plt and version suffixes.  */
  atsign = strchr (class_name, '@');
  if (atsign != NULL)
    return std::string (class_name, atsign - class_name);
  return class_name;
}

/* Implement the 'get_type_from_type_info' method.  */

static struct type *
gnuv3_get_type_from_type_info (struct value *type_info_ptr)
{
  /* We have to parse the type name, since in general there is not a
     symbol for a type.  This is somewhat bogus since there may be a
     mis-parse.  Another approach might be to re-use the demangler's
     internal form to reconstruct the type somehow.  */
  std::string type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
  expression_up expr (parse_expression (type_name.c_str ()));
  struct value *type_val = evaluate_type (expr.get ());
  return value_type (type_val);
}

/* Determine if we are currently in a C++ thunk.  If so, get the address
   of the routine we are thunking to and continue to there instead.  */

static CORE_ADDR 
gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
{
  CORE_ADDR real_stop_pc, method_stop_pc, func_addr;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct bound_minimal_symbol thunk_sym, fn_sym;
  struct obj_section *section;
  const char *thunk_name, *fn_name;
  
  real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
  if (real_stop_pc == 0)
    real_stop_pc = stop_pc;

  /* Find the linker symbol for this potential thunk.  */
  thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc);
  section = find_pc_section (real_stop_pc);
  if (thunk_sym.minsym == NULL || section == NULL)
    return 0;

  /* The symbol's demangled name should be something like "virtual
     thunk to FUNCTION", where FUNCTION is the name of the function
     being thunked to.  */
  thunk_name = MSYMBOL_DEMANGLED_NAME (thunk_sym.minsym);
  if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL)
    return 0;

  fn_name = strstr (thunk_name, " thunk to ") + strlen (" thunk to ");
  fn_sym = lookup_minimal_symbol (fn_name, NULL, section->objfile);
  if (fn_sym.minsym == NULL)
    return 0;

  method_stop_pc = BMSYMBOL_VALUE_ADDRESS (fn_sym);

  /* Some targets have minimal symbols pointing to function descriptors
     (powerpc 64 for example).  Make sure to retrieve the address
     of the real function from the function descriptor before passing on
     the address to other layers of GDB.  */
  func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, method_stop_pc,
                                                  &current_target);
  if (func_addr != 0)
    method_stop_pc = func_addr;

  real_stop_pc = gdbarch_skip_trampoline_code
		   (gdbarch, frame, method_stop_pc);
  if (real_stop_pc == 0)
    real_stop_pc = method_stop_pc;

  return real_stop_pc;
}

/* Return nonzero if a type should be passed by reference.

   The rule in the v3 ABI document comes from section 3.1.1.  If the
   type has a non-trivial copy constructor or destructor, then the
   caller must make a copy (by calling the copy constructor if there
   is one or perform the copy itself otherwise), pass the address of
   the copy, and then destroy the temporary (if necessary).

   For return values with non-trivial copy constructors or
   destructors, space will be allocated in the caller, and a pointer
   will be passed as the first argument (preceding "this").

   We don't have a bulletproof mechanism for determining whether a
   constructor or destructor is trivial.  For GCC and DWARF2 debug
   information, we can check the artificial flag.

   We don't do anything with the constructors or destructors,
   but we have to get the argument passing right anyway.  */
static int
gnuv3_pass_by_reference (struct type *type)
{
  int fieldnum, fieldelem;

  type = check_typedef (type);

  /* We're only interested in things that can have methods.  */
  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
      && TYPE_CODE (type) != TYPE_CODE_UNION)
    return 0;

  /* A dynamic class has a non-trivial copy constructor.
     See c++98 section 12.8 Copying class objects [class.copy].  */
  if (gnuv3_dynamic_class (type))
    return 1;

  for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
    for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
	 fieldelem++)
      {
	struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum);
	const char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum);
	struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem);

	/* If this function is marked as artificial, it is compiler-generated,
	   and we assume it is trivial.  */
	if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem))
	  continue;

	/* If we've found a destructor, we must pass this by reference.  */
	if (name[0] == '~')
	  return 1;

	/* If the mangled name of this method doesn't indicate that it
	   is a constructor, we're not interested.

	   FIXME drow/2007-09-23: We could do this using the name of
	   the method and the name of the class instead of dealing
	   with the mangled name.  We don't have a convenient function
	   to strip off both leading scope qualifiers and trailing
	   template arguments yet.  */
	if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem))
	    && !TYPE_FN_FIELD_CONSTRUCTOR (fn, fieldelem))
	  continue;

	/* If this method takes two arguments, and the second argument is
	   a reference to this class, then it is a copy constructor.  */
	if (TYPE_NFIELDS (fieldtype) == 2)
	  {
	    struct type *arg_type = TYPE_FIELD_TYPE (fieldtype, 1);

	    if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
	      {
		struct type *arg_target_type;

	        arg_target_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
		if (class_types_same_p (arg_target_type, type))
		  return 1;
	      }
	  }
      }

  /* Even if all the constructors and destructors were artificial, one
     of them may have invoked a non-artificial constructor or
     destructor in a base class.  If any base class needs to be passed
     by reference, so does this class.  Similarly for members, which
     are constructed whenever this class is.  We do not need to worry
     about recursive loops here, since we are only looking at members
     of complete class type.  Also ignore any static members.  */
  for (fieldnum = 0; fieldnum < TYPE_NFIELDS (type); fieldnum++)
    if (! field_is_static (&TYPE_FIELD (type, fieldnum))
        && gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum)))
      return 1;

  return 0;
}

static void
init_gnuv3_ops (void)
{
  vtable_type_gdbarch_data
    = gdbarch_data_register_post_init (build_gdb_vtable_type);
  std_type_info_gdbarch_data
    = gdbarch_data_register_post_init (build_std_type_info_type);

  gnu_v3_abi_ops.shortname = "gnu-v3";
  gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";
  gnu_v3_abi_ops.doc = "G++ Version 3 ABI";
  gnu_v3_abi_ops.is_destructor_name =
    (enum dtor_kinds (*) (const char *))is_gnu_v3_mangled_dtor;
  gnu_v3_abi_ops.is_constructor_name =
    (enum ctor_kinds (*) (const char *))is_gnu_v3_mangled_ctor;
  gnu_v3_abi_ops.is_vtable_name = gnuv3_is_vtable_name;
  gnu_v3_abi_ops.is_operator_name = gnuv3_is_operator_name;
  gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type;
  gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field;
  gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;
  gnu_v3_abi_ops.print_method_ptr = gnuv3_print_method_ptr;
  gnu_v3_abi_ops.method_ptr_size = gnuv3_method_ptr_size;
  gnu_v3_abi_ops.make_method_ptr = gnuv3_make_method_ptr;
  gnu_v3_abi_ops.method_ptr_to_value = gnuv3_method_ptr_to_value;
  gnu_v3_abi_ops.print_vtable = gnuv3_print_vtable;
  gnu_v3_abi_ops.get_typeid = gnuv3_get_typeid;
  gnu_v3_abi_ops.get_typeid_type = gnuv3_get_typeid_type;
  gnu_v3_abi_ops.get_type_from_type_info = gnuv3_get_type_from_type_info;
  gnu_v3_abi_ops.get_typename_from_type_info
    = gnuv3_get_typename_from_type_info;
  gnu_v3_abi_ops.skip_trampoline = gnuv3_skip_trampoline;
  gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
}

void
_initialize_gnu_v3_abi (void)
{
  init_gnuv3_ops ();

  register_cp_abi (&gnu_v3_abi_ops);
  set_cp_abi_as_auto_default (gnu_v3_abi_ops.shortname);
}
