New function.
* gdbarch.sh (CONVERT_FROM_FUNC_PTR_ADDR): Add.
* gdbarch.c, gdbarch.h: Regenerate.
* valops.c (find_function_addr): Use CONVERT_FROM_FUNC_PTR_ADDR
unconditionally.
* config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): Delete
definition.
* config/powerpc/tm-linux.h (CONVERT_FROM_FUNC_PTR_ADDR): Remove
undef.
* rs6000-tdep.c (rs6000_convert_from_func_ptr_addr): Fix comment.
(rs6000_gdbarch_init): Register rs6000_convert_from_func_ptr_addr
if not ELFOSABI_LINUX.
+2000-10-26 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * arch-utils.c, arch-utils.h (default_convert_from_func_ptr_addr):
+ New function.
+ * gdbarch.sh (CONVERT_FROM_FUNC_PTR_ADDR): Add.
+ * gdbarch.c, gdbarch.h: Regenerate.
+ * valops.c (find_function_addr): Use CONVERT_FROM_FUNC_PTR_ADDR
+ unconditionally.
+
+ * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): Delete
+ definition.
+ * config/powerpc/tm-linux.h (CONVERT_FROM_FUNC_PTR_ADDR): Remove
+ undef.
+ * rs6000-tdep.c (rs6000_convert_from_func_ptr_addr): Fix comment.
+ (rs6000_gdbarch_init): Register rs6000_convert_from_func_ptr_addr
+ if not ELFOSABI_LINUX.
+
2000-10-25 Kevin Buettner <kevinb@redhat.com>
* config/rs6000/rs6000lynx.mt (TDEPFILES): Revert 2000-10-24
return num;
}
+
+CORE_ADDR
+default_convert_from_func_ptr_addr (CORE_ADDR addr)
+{
+ return addr;
+}
+
/* Functions to manipulate the endianness of the target. */
#ifdef TARGET_BYTE_ORDER_SELECTABLE
extern int default_register_sim_regno (int reg_nr);
+/* Default conversion of function pointer address - returns address. */
+
+extern CORE_ADDR default_convert_from_func_ptr_addr (CORE_ADDR addr);
+
#endif
#define CANNOT_STORE_REGISTER(regno) ((regno) >= MQ_REGNUM)
#endif
-/* Linux doesn't use the PowerOpen ABI for function pointer representation */
-#undef CONVERT_FROM_FUNC_PTR_ADDR
-
#if 0 /* If skip_prologue() isn't too greedy, we don't need this */
/* There is some problem with the debugging symbols generated by the
compiler such that the debugging symbol for the first line of a
/* Default offset from SP where the LR is stored */
#define DEFAULT_LR_SAVE 8
-/* Usually a function pointer's representation is simply the address
- of the function. On the RS/6000 however, a function pointer is
- represented by a pointer to a TOC entry. This TOC entry contains
- three words, the first word is the address of the function, the
- second word is the TOC pointer (r2), and the third word is the
- static chain value. Throughout GDB it is currently assumed that a
- function pointer contains the address of the function, which is not
- easy to fix. In addition, the conversion of a function address to
- a function pointer would require allocation of a TOC entry in the
- inferior's memory space, with all its drawbacks. To be able to
- call C++ virtual methods in the inferior (which are called via
- function pointers), find_function_addr uses this macro to get the
- function address from a function pointer. */
-
-#define CONVERT_FROM_FUNC_PTR_ADDR rs6000_convert_from_func_ptr_addr
-extern CORE_ADDR rs6000_convert_from_func_ptr_addr (CORE_ADDR);
-
/* Flag for machine-specific stuff in shared files. FIXME */
#define IBM6000_TARGET
const struct floatformat * float_format;
const struct floatformat * double_format;
const struct floatformat * long_double_format;
+ gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr;
};
0,
0,
0,
+ 0,
/* startup_gdbarch() */
};
gdbarch->frame_args_skip = -1;
gdbarch->frameless_function_invocation = generic_frameless_function_invocation_not;
gdbarch->extra_stack_alignment_needed = 1;
+ gdbarch->convert_from_func_ptr_addr = default_convert_from_func_ptr_addr;
/* gdbarch_alloc() */
return gdbarch;
gdbarch->double_format = default_double_format (gdbarch);
if (gdbarch->long_double_format == 0)
gdbarch->long_double_format = &floatformat_unknown;
+ /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
}
"gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT # %s\n",
XSTRING (TARGET_LONG_DOUBLE_FORMAT));
#endif
+#ifdef CONVERT_FROM_FUNC_PTR_ADDR
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "CONVERT_FROM_FUNC_PTR_ADDR(addr)",
+ XSTRING (CONVERT_FROM_FUNC_PTR_ADDR (addr)));
+#endif
#ifdef TARGET_ARCHITECTURE
if (TARGET_ARCHITECTURE != NULL)
fprintf_unfiltered (file,
fprintf_unfiltered (file,
"gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT = %ld\n",
(long) TARGET_LONG_DOUBLE_FORMAT);
+#endif
+#ifdef CONVERT_FROM_FUNC_PTR_ADDR
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: CONVERT_FROM_FUNC_PTR_ADDR = 0x%08lx\n",
+ (long) current_gdbarch->convert_from_func_ptr_addr
+ /*CONVERT_FROM_FUNC_PTR_ADDR ()*/);
#endif
if (current_gdbarch->dump_tdep != NULL)
current_gdbarch->dump_tdep (current_gdbarch, file);
gdbarch->long_double_format = long_double_format;
}
+CORE_ADDR
+gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ if (gdbarch->convert_from_func_ptr_addr == 0)
+ internal_error ("gdbarch: gdbarch_convert_from_func_ptr_addr invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_from_func_ptr_addr called\n");
+ return gdbarch->convert_from_func_ptr_addr (addr);
+}
+
+void
+set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
+ gdbarch_convert_from_func_ptr_addr_ftype convert_from_func_ptr_addr)
+{
+ gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr;
+}
+
/* Keep a registrary of per-architecture data-pointers required by GDB
modules. */
#endif
#endif
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (CONVERT_FROM_FUNC_PTR_ADDR)
+#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (default_convert_from_func_ptr_addr (addr))
+#endif
+
+typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (CORE_ADDR addr);
+extern CORE_ADDR gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr);
+extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CONVERT_FROM_FUNC_PTR_ADDR)
+#define CONVERT_FROM_FUNC_PTR_ADDR(addr) (gdbarch_convert_from_func_ptr_addr (current_gdbarch, addr))
+#endif
+#endif
+
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)
v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch)
v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::&floatformat_unknown
+f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::default_convert_from_func_ptr_addr::0
EOF
}
a function pointer would require allocation of a TOC entry in the
inferior's memory space, with all its drawbacks. To be able to
call C++ virtual methods in the inferior (which are called via
- function pointers), find_function_addr uses this macro to get the
+ function pointers), find_function_addr uses this function to get the
function address from a function pointer. */
-/* Return nonzero if ADDR (a function pointer) is in the data space and
- is therefore a special function pointer. */
+/* Return real function address if ADDR (a function pointer) is in the data
+ space and is therefore a special function pointer. */
CORE_ADDR
rs6000_convert_from_func_ptr_addr (CORE_ADDR addr)
set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
+
+ /* Handle RS/6000 function pointers. */
+ set_gdbarch_convert_from_func_ptr_addr (gdbarch,
+ rs6000_convert_from_func_ptr_addr);
}
set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address);
set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address);
if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
|| TYPE_CODE (ftype) == TYPE_CODE_METHOD)
{
-#ifdef CONVERT_FROM_FUNC_PTR_ADDR
- /* FIXME: This is a workaround for the unusual function
- pointer representation on the RS/6000, see comment
- in config/rs6000/tm-rs6000.h */
funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
-#endif
value_type = TYPE_TARGET_TYPE (ftype);
}
else