diff options
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/arch-utils.c | 7 | ||||
-rw-r--r-- | gdb/arch-utils.h | 4 | ||||
-rw-r--r-- | gdb/config/powerpc/tm-linux.h | 3 | ||||
-rw-r--r-- | gdb/config/rs6000/tm-rs6000.h | 17 | ||||
-rw-r--r-- | gdb/gdbarch.c | 34 | ||||
-rw-r--r-- | gdb/gdbarch.h | 14 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 1 | ||||
-rw-r--r-- | gdb/rs6000-tdep.c | 10 | ||||
-rw-r--r-- | gdb/valops.c | 5 |
10 files changed, 84 insertions, 28 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a615486..959e04a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +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 diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 02eeaea..d58eb45 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -226,6 +226,13 @@ default_register_sim_regno (int num) 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 diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 579953f..2645a95 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -93,4 +93,8 @@ extern int (*target_architecture_hook) (const struct bfd_arch_info *); 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 diff --git a/gdb/config/powerpc/tm-linux.h b/gdb/config/powerpc/tm-linux.h index 99d4c96..cf3275e 100644 --- a/gdb/config/powerpc/tm-linux.h +++ b/gdb/config/powerpc/tm-linux.h @@ -55,9 +55,6 @@ extern int ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name); #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 diff --git a/gdb/config/rs6000/tm-rs6000.h b/gdb/config/rs6000/tm-rs6000.h index 9bf8381..beb445d 100644 --- a/gdb/config/rs6000/tm-rs6000.h +++ b/gdb/config/rs6000/tm-rs6000.h @@ -97,23 +97,6 @@ extern void aix_process_linenos (void); /* 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 diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 1bdf278..bd705f9 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -232,6 +232,7 @@ struct gdbarch 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; }; @@ -354,6 +355,7 @@ struct gdbarch startup_gdbarch = 0, 0, 0, + 0, /* startup_gdbarch() */ }; @@ -429,6 +431,7 @@ gdbarch_alloc (const struct gdbarch_info *info, 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; @@ -665,6 +668,7 @@ verify_gdbarch (struct gdbarch *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 */ } @@ -1293,6 +1297,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "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, @@ -1949,6 +1959,13 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *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); } @@ -3737,6 +3754,23 @@ set_gdbarch_long_double_format (struct gdbarch *gdbarch, 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. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 82ffdce..87cbbd9 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1338,6 +1338,20 @@ extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struc #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); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 991ec32..11a4a77 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -472,6 +472,7 @@ F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0 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 } diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index fa06340..252ea77 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1541,11 +1541,11 @@ rs6000_create_inferior (int pid) 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) @@ -2196,6 +2196,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); diff --git a/gdb/valops.c b/gdb/valops.c index 8a7f036..7feec53 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1249,12 +1249,7 @@ find_function_addr (value_ptr function, struct type **retval_type) 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 |