/* Abstraction of GNU v3 abi.
Contributed by Jim Blandy <jimb@redhat.com>
- Copyright (C) 2001-2013 Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "typeprint.h"
#include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
static struct cp_abi_ops gnu_v3_abi_ops;
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);
}
return result;
}
-/* Get the type name given a type_info object. */
+/* Implement the 'get_typename_from_type_info' method. */
static char *
gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
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 obj_section *section;
return 0;
method_stop_pc = SYMBOL_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,
+ ¤t_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)
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;
}