Obvious indentation fixes on test sample and test file for MPX registers.
[deliverable/binutils-gdb.git] / gdb / gnu-v3-abi.c
index 7649a48ea72af5776910222e6ebfb1f26bd8f47b..5c040114d862120ebd435c199e1c6d8f8ac25a10 100644 (file)
@@ -1,7 +1,7 @@
 /* Abstraction of GNU v3 abi.
    Contributed by Jim Blandy <jimb@redhat.com>
 
-   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+   Copyright (C) 2001-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "objfiles.h"
 #include "valprint.h"
 #include "c-lang.h"
-#include "exceptions.h"
 #include "typeprint.h"
 
-#include "gdb_assert.h"
-#include "gdb_string.h"
-
 static struct cp_abi_ops gnu_v3_abi_ops;
 
 /* A gdbarch key for std::type_info, in the event that it can't be
@@ -43,13 +39,13 @@ static struct gdbarch_data *std_type_info_gdbarch_data;
 static int
 gnuv3_is_vtable_name (const char *name)
 {
-  return strncmp (name, "_ZTV", 4) == 0;
+  return startswith (name, "_ZTV");
 }
 
 static int
 gnuv3_is_operator_name (const char *name)
 {
-  return strncmp (name, "operator", 8) == 0;
+  return startswith (name, "operator");
 }
 
 
@@ -171,7 +167,7 @@ build_gdb_vtable_type (struct gdbarch *arch)
   TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable";
   INIT_CPLUS_SPECIFIC (t);
 
-  return t;
+  return make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
 }
 
 
@@ -206,6 +202,13 @@ gnuv3_dynamic_class (struct type *type)
 {
   int fieldnum, fieldelem;
 
+  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;
 
@@ -250,9 +253,12 @@ gnuv3_get_vtable (struct gdbarch *gdbarch,
   struct value *vtable_pointer;
   CORE_ADDR vtable_address;
 
+  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 (check_typedef (container_type)))
+  if (!gnuv3_dynamic_class (container_type))
     return NULL;
 
   /* We do not consult the debug information to find the virtual table.
@@ -292,7 +298,7 @@ gnuv3_rtti_type (struct value *value,
   char *atsign;
 
   /* We only have RTTI for class objects.  */
-  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
+  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
     return NULL;
 
   /* Java doesn't have RTTI following the C++ ABI.  */
@@ -305,7 +311,7 @@ gnuv3_rtti_type (struct value *value,
   if (using_enc_p)
     *using_enc_p = 0;
 
-  vtable = gnuv3_get_vtable (gdbarch, value_type (value),
+  vtable = gnuv3_get_vtable (gdbarch, values_type,
                             value_as_address (value_addr (value)));
   if (vtable == NULL)
     return NULL;
@@ -322,9 +328,9 @@ gnuv3_rtti_type (struct value *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 = SYMBOL_DEMANGLED_NAME (vtable_symbol);
+  vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
   if (vtable_symbol_name == NULL
-      || strncmp (vtable_symbol_name, "vtable for ", 11))
+      || !startswith (vtable_symbol_name, "vtable for "))
     {
       warning (_("can't find linker symbol for virtual table for `%s' value"),
               TYPE_SAFE_NAME (values_type));
@@ -410,7 +416,7 @@ gnuv3_virtual_fn_field (struct value **value_p,
   struct gdbarch *gdbarch;
 
   /* Some simple sanity checks.  */
-  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
+  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
     error (_("Only classes can have virtual functions."));
 
   /* Determine architecture.  */
@@ -579,8 +585,8 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
                        struct type *type,
                        struct ui_file *stream)
 {
-  struct type *domain = TYPE_DOMAIN_TYPE (type);
-  struct gdbarch *gdbarch = get_type_arch (domain);
+  struct type *self_type = TYPE_SELF_TYPE (type);
+  struct gdbarch *gdbarch = get_type_arch (self_type);
   CORE_ADDR ptr_value;
   LONGEST adjustment;
   int vbit;
@@ -606,7 +612,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
         to an index, as used in TYPE_FN_FIELD_VOFFSET.  */
       voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
 
-      physname = gnuv3_find_method_in (domain, voffset, adjustment);
+      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.  */
@@ -704,17 +710,17 @@ 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 *domain_type, *final_type, *method_type;
+  struct type *self_type, *final_type, *method_type;
   LONGEST adjustment;
   int vbit;
 
-  domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
-  final_type = lookup_pointer_type (domain_type);
+  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 (domain_type);
+  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
@@ -825,6 +831,8 @@ compute_vtable_size (htab_t offset_hash,
   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))
@@ -896,8 +904,8 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
     {
       /* Initialize it just to avoid a GCC false warning.  */
       CORE_ADDR addr = 0;
+      int got_error = 0;
       struct value *vfn;
-      volatile struct gdb_exception ex;
 
       printf_filtered ("[%d]: ", i);
 
@@ -908,13 +916,18 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
       if (gdbarch_vtable_function_descriptors (gdbarch))
        vfn = value_addr (vfn);
 
-      TRY_CATCH (ex, RETURN_MASK_ERROR)
+      TRY
        {
          addr = value_as_address (vfn);
        }
-      if (ex.reason < 0)
-       printf_filtered (_("<error: %s>"), ex.message);
-      else
+      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");
     }
@@ -953,8 +966,11 @@ gnuv3_print_vtable (struct value *value)
     }
 
   gdbarch = get_type_arch (type);
-  vtable = gnuv3_get_vtable (gdbarch, type,
-                            value_as_address (value_addr (value)));
+
+  vtable = NULL;
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    vtable = gnuv3_get_vtable (gdbarch, type,
+                              value_as_address (value_addr (value)));
 
   if (!vtable)
     {
@@ -1066,7 +1082,7 @@ gnuv3_get_typeid (struct value *value)
   struct gdbarch *gdbarch;
   struct cleanup *cleanup;
   struct value *result;
-  char *typename, *canonical;
+  char *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
@@ -1085,27 +1101,27 @@ gnuv3_get_typeid (struct value *value)
   type = make_cv_type (0, 0, type, NULL);
   gdbarch = get_type_arch (type);
 
-  typename = type_to_string (type);
-  if (typename == NULL)
+  type_name = type_to_string (type);
+  if (type_name == NULL)
     error (_("cannot find typeinfo for unnamed type"));
-  cleanup = make_cleanup (xfree, typename);
+  cleanup = make_cleanup (xfree, type_name);
 
   /* 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 (typename);
+  canonical = cp_canonicalize_string (type_name);
   if (canonical != NULL)
     {
       make_cleanup (xfree, canonical);
-      typename = canonical;
+      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_CLASS
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
       && value_lval_const (value) == lval_memory
       && gnuv3_dynamic_class (type))
     {
@@ -1114,7 +1130,7 @@ gnuv3_get_typeid (struct value *value)
 
       vtable = gnuv3_get_vtable (gdbarch, type, address);
       if (vtable == NULL)
-       error (_("cannot find typeinfo for object of type '%s'"), typename);
+       error (_("cannot find typeinfo for object of type '%s'"), type_name);
       typeinfo_value = value_field (vtable, vtable_field_type_info);
       result = value_ind (value_cast (make_pointer_type (typeinfo_type, NULL),
                                      typeinfo_value));
@@ -1122,31 +1138,94 @@ gnuv3_get_typeid (struct value *value)
   else
     {
       char *sym_name;
-      struct minimal_symbol *minsym;
+      struct bound_minimal_symbol minsym;
 
-      sym_name = concat ("typeinfo for ", typename, (char *) NULL);
+      sym_name = concat ("typeinfo for ", type_name, (char *) NULL);
       make_cleanup (xfree, sym_name);
       minsym = lookup_minimal_symbol (sym_name, NULL, NULL);
 
-      if (minsym == NULL)
-       error (_("could not find typeinfo symbol for '%s'"), typename);
+      if (minsym.minsym == NULL)
+       error (_("could not find typeinfo symbol for '%s'"), type_name);
 
-      result = value_at_lazy (typeinfo_type, SYMBOL_VALUE_ADDRESS (minsym));
+      result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym));
     }
 
   do_cleanups (cleanup);
   return result;
 }
 
+/* Implement the 'get_typename_from_type_info' method.  */
+
+static char *
+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 savestring (class_name, atsign - class_name);
+  return xstrdup (class_name);
+}
+
+/* Implement the 'get_type_from_type_info' method.  */
+
+static struct type *
+gnuv3_get_type_from_type_info (struct value *type_info_ptr)
+{
+  char *type_name;
+  struct cleanup *cleanup;
+  struct value *type_val;
+  struct expression *expr;
+  struct type *result;
+
+  type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
+  cleanup = make_cleanup (xfree, type_name);
+
+  /* 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.  */
+
+  expr = parse_expression (type_name);
+  make_cleanup (xfree, expr);
+
+  type_val = evaluate_type (expr);
+  result = value_type (type_val);
+
+  do_cleanups (cleanup);
+  return result;
+}
+
 /* 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;
+  CORE_ADDR real_stop_pc, method_stop_pc, func_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct minimal_symbol *thunk_sym, *fn_sym;
+  struct bound_minimal_symbol thunk_sym, fn_sym;
   struct obj_section *section;
   const char *thunk_name, *fn_name;
   
@@ -1155,24 +1234,34 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
     real_stop_pc = stop_pc;
 
   /* Find the linker symbol for this potential thunk.  */
-  thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc).minsym;
+  thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc);
   section = find_pc_section (real_stop_pc);
-  if (thunk_sym == NULL || section == NULL)
+  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 = SYMBOL_DEMANGLED_NAME (thunk_sym);
+  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 == NULL)
+  if (fn_sym.minsym == NULL)
     return 0;
 
-  method_stop_pc = SYMBOL_VALUE_ADDRESS (fn_sym);
+  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)
@@ -1208,10 +1297,14 @@ gnuv3_pass_by_reference (struct type *type)
 
   /* We're only interested in things that can have methods.  */
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-      && TYPE_CODE (type) != TYPE_CODE_CLASS
       && 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++)
@@ -1243,11 +1336,19 @@ gnuv3_pass_by_reference (struct type *type)
 
        /* 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
-           && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF
-           && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype,
-                                                                1))) == type)
-         return 1;
+       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
@@ -1292,6 +1393,9 @@ init_gnuv3_ops (void)
   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;
 }
This page took 0.032118 seconds and 4 git commands to generate.