Add shared library support for FR-V FDPIC ABI.

This commit is contained in:
Kevin Buettner
2004-03-13 00:50:53 +00:00
parent ed1bd989f7
commit c4d1051556
7 changed files with 1327 additions and 1 deletions

View File

@ -1,3 +1,18 @@
2004-03-12 Kevin Buettner <kevinb@redhat.com>
Add shared library support for FR-V FDPIC ABI:
* Makefile.in (solib-frv.o): Add dependencies.
* frv-tdep.c (find_func_descr, frv_convert_from_func_ptr_addr):
New functions.
(frv_push_dummy_call): Add support for FDPIC ABI.
(frv_gdbarch_init): Call set_gdbarch_convert_from_func_ptr_addr()
for FDPIC ABI.
* frv-tdep.h (frv_fdpic_find_global_pointer): Declare.
(frv_fdpic_find_canonical_descriptor): Declare.
* solib-frv.c: New file.
* config/frv/frv.mt (TDEPFILES): Add solib.o and solib-frv.o.
* config/frv/tm-frv.h (solib.h): Include.
2004-03-12 Kevin Buettner <kevinb@redhat.com>
* Makefile.in (elf_frv_h, frv_tdep_h): Define.

View File

@ -2298,6 +2298,9 @@ solib.o: solib.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) $(symfile_h) \
$(objfiles_h) $(gdbcore_h) $(command_h) $(target_h) $(frame_h) \
$(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) $(gdbcmd_h) \
$(completer_h) $(filenames_h) $(exec_h) $(solist_h) $(readline_h)
solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) $(gdbcore_h) \
$(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) $(language_h) \
$(command_h) $(gdbcmd_h) $(elf_frv_h)
solib-irix.o: solib-irix.c $(defs_h) $(symtab_h) $(bfd_h) $(symfile_h) \
$(objfiles_h) $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h)
solib-legacy.o: solib-legacy.c $(defs_h) $(gdbcore_h) $(solib_svr4_h)

View File

@ -1,5 +1,5 @@
# Target: Fujitsu FRV processor
TDEPFILES= frv-tdep.o
TDEPFILES= frv-tdep.o solib.o solib-frv.o
TM_FILE= tm-frv.h
SIM_OBS = remote-sim.o
SIM = ../sim/frv/libsim.a

View File

@ -43,3 +43,5 @@ extern CORE_ADDR frv_stopped_data_address(void);
/* Use these macros for watchpoint insertion/deletion. */
#define target_stopped_data_address() frv_stopped_data_address()
#include "solib.h" /* Include support for shared libraries. */

View File

@ -1036,6 +1036,45 @@ frv_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
return align_down (sp, 8);
}
static CORE_ADDR
find_func_descr (struct gdbarch *gdbarch, CORE_ADDR entry_point)
{
CORE_ADDR descr;
char valbuf[4];
descr = frv_fdpic_find_canonical_descriptor (entry_point);
if (descr != 0)
return descr;
/* Construct a non-canonical descriptor from space allocated on
the stack. */
descr = value_as_long (value_allocate_space_in_inferior (8));
store_unsigned_integer (valbuf, 4, entry_point);
write_memory (descr, valbuf, 4);
store_unsigned_integer (valbuf, 4,
frv_fdpic_find_global_pointer (entry_point));
write_memory (descr + 4, valbuf, 4);
return descr;
}
static CORE_ADDR
frv_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
struct target_ops *targ)
{
CORE_ADDR entry_point;
CORE_ADDR got_address;
entry_point = get_target_memory_unsigned (targ, addr, 4);
got_address = get_target_memory_unsigned (targ, addr + 4, 4);
if (got_address == frv_fdpic_find_global_pointer (entry_point))
return entry_point;
else
return addr;
}
static CORE_ADDR
frv_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
struct regcache *regcache, CORE_ADDR bp_addr,
@ -1053,6 +1092,7 @@ frv_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
CORE_ADDR regval;
int stack_space;
int stack_offset;
enum frv_abi abi = frv_abi (gdbarch);
#if 0
printf("Push %d args at sp = %x, struct_return=%d (%x)\n",
@ -1092,6 +1132,22 @@ frv_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
len = 4;
val = valbuf;
}
else if (abi == FRV_ABI_FDPIC
&& len == 4
&& typecode == TYPE_CODE_PTR
&& TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
{
/* The FDPIC ABI requires function descriptors to be passed instead
of entry points. */
store_unsigned_integer
(valbuf, 4,
find_func_descr (gdbarch,
extract_unsigned_integer (VALUE_CONTENTS (arg),
4)));
typecode = TYPE_CODE_PTR;
len = 4;
val = valbuf;
}
else
{
val = (char *) VALUE_CONTENTS (arg);
@ -1129,6 +1185,14 @@ frv_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
always at BP_ADDR. */
regcache_cooked_write_unsigned (regcache, lr_regnum, bp_addr);
if (abi == FRV_ABI_FDPIC)
{
/* Set the GOT register for the FDPIC ABI. */
regcache_cooked_write_unsigned
(regcache, first_gpr_regnum + 15,
frv_fdpic_find_global_pointer (func_addr));
}
/* Finally, update the SP register. */
regcache_cooked_write_unsigned (regcache, sp_regnum, sp);
@ -1449,6 +1513,9 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
set_gdbarch_print_insn (gdbarch, print_insn_frv);
if (frv_abi (gdbarch) == FRV_ABI_FDPIC)
set_gdbarch_convert_from_func_ptr_addr (gdbarch,
frv_convert_from_func_ptr_addr);
return gdbarch;
}

View File

@ -33,3 +33,12 @@ enum frv_abi frv_abi (struct gdbarch *gdbarch);
not. (E.g, -1 will be returned if the ABI isn't the FDPIC ABI.) */
int frv_fdpic_loadmap_addresses (struct gdbarch *gdbarch,
CORE_ADDR *interp_addr, CORE_ADDR *exec_addr);
/* Given a function entry point, find and return the GOT address for the
containing load module. */
CORE_ADDR frv_fdpic_find_global_pointer (CORE_ADDR addr);
/* Given a function entry point, find and return the canonical descriptor
for that function, if one exists. If no canonical descriptor could
be found, return 0. */
CORE_ADDR frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point);

1230
gdb/solib-frv.c Normal file

File diff suppressed because it is too large Load Diff