diff options
-rw-r--r-- | gdb/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/frv-tdep.c | 62 | ||||
-rw-r--r-- | gdb/frv-tdep.h | 35 |
3 files changed, 99 insertions, 1 deletions
diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 83a4484..3017d79 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -569,6 +569,7 @@ elf_reloc_macros_h = $(INCLUDE_DIR)/elf/reloc-macros.h elf_sh_h = $(INCLUDE_DIR)/elf/sh.h elf_arm_h = $(INCLUDE_DIR)/elf/arm.h $(elf_reloc_macros_h) elf_bfd_h = $(BFD_SRC)/elf-bfd.h +elf_frv_h = $(INCLUDE_DIR)/elf/frv.h $(elf_reloc_macros_h) libaout_h = $(BFD_SRC)/libaout.h libbfd_h = $(BFD_SRC)/libbfd.h remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.h @@ -658,6 +659,7 @@ f_lang_h = f-lang.h frame_base_h = frame-base.h frame_h = frame.h frame_unwind_h = frame-unwind.h $(frame_h) +frv_tdep_h = frv-tdep.h gdbarch_h = gdbarch.h gdb_assert_h = gdb_assert.h gdbcmd_h = gdbcmd.h $(command_h) $(ui_out_h) @@ -1769,6 +1771,7 @@ frv-tdep.o: frv-tdep.c $(defs_h) $(gdb_string_h) $(inferior_h) $(gdbcore_h) \ $(arch_utils_h) $(regcache_h) $(frame_h) $(frame_unwind_h) \ $(frame_base_h) $(trad_frame_h) $(dis_asm_h) $(gdb_assert_h) \ $(sim_regno_h) $(gdb_sim_frv_h) $(opcodes_frv_desc_h) $(symtab_h) + $(elf_bfd_h) $(elf_frv_h) $(osabi_h) $(frv_tdep_h) f-typeprint.o: f-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \ $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \ $(f_lang_h) $(gdb_string_h) diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c index b7936e7..3c424b0 100644 --- a/gdb/frv-tdep.c +++ b/gdb/frv-tdep.c @@ -34,6 +34,10 @@ #include "gdb/sim-frv.h" #include "opcodes/frv-desc.h" /* for the H_SPR_... enums */ #include "symtab.h" +#include "elf-bfd.h" +#include "elf/frv.h" +#include "osabi.h" +#include "frv-tdep.h" extern void _initialize_frv_tdep (void); @@ -69,6 +73,8 @@ enum { psr_regnum = 129, ccr_regnum = 130, cccr_regnum = 131, + fdpic_loadmap_exec_regnum = 132, + fdpic_loadmap_interp_regnum = 133, tbr_regnum = 135, brr_regnum = 136, dbar0_regnum = 137, @@ -129,6 +135,9 @@ struct frv_unwind_cache /* was struct frame_extra_info */ Fortran. */ struct gdbarch_tdep { + /* Which ABI is in use? */ + enum frv_abi frv_abi; + /* How many general-purpose registers does this variant have? */ int num_gprs; @@ -147,6 +156,41 @@ struct gdbarch_tdep #define CURRENT_VARIANT (gdbarch_tdep (current_gdbarch)) +/* Return the FR-V ABI associated with GDBARCH. */ +enum frv_abi +frv_abi (struct gdbarch *gdbarch) +{ + return gdbarch_tdep (gdbarch)->frv_abi; +} + +/* Fetch the interpreter and executable loadmap addresses (for shared + library support) for the FDPIC ABI. Return 0 if successful, -1 if + 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) +{ + if (frv_abi (gdbarch) != FRV_ABI_FDPIC) + return -1; + else + { + if (interp_addr != NULL) + { + ULONGEST val; + regcache_cooked_read_unsigned (current_regcache, + fdpic_loadmap_interp_regnum, &val); + *interp_addr = val; + } + if (exec_addr != NULL) + { + ULONGEST val; + regcache_cooked_read_unsigned (current_regcache, + fdpic_loadmap_exec_regnum, &val); + *exec_addr = val; + } + return 0; + } +} /* Allocate a new variant structure, and set up default values for all the fields. */ @@ -160,6 +204,7 @@ new_variant (void) var = xmalloc (sizeof (*var)); memset (var, 0, sizeof (*var)); + var->frv_abi = FRV_ABI_EABI; var->num_gprs = 64; var->num_fprs = 64; var->num_hw_watchpoints = 0; @@ -238,6 +283,13 @@ set_variant_num_fprs (struct gdbarch_tdep *var, int num_fprs) } } +static void +set_variant_abi_fdpic (struct gdbarch_tdep *var) +{ + var->frv_abi = FRV_ABI_FDPIC; + var->register_names[fdpic_loadmap_exec_regnum] = xstrdup ("loadmap_exec"); + var->register_names[fdpic_loadmap_interp_regnum] = xstrdup ("loadmap_interp"); +} static const char * frv_register_name (int reg) @@ -1276,6 +1328,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; struct gdbarch_tdep *var; + int elf_flags = 0; /* Check to see if we've already built an appropriate architecture object for this executable. */ @@ -1305,7 +1358,14 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Never heard of this variant. */ return 0; } - + + /* Extract the ELF flags, if available. */ + if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) + elf_flags = elf_elfheader (info.abfd)->e_flags; + + if (elf_flags & EF_FRV_FDPIC) + set_variant_abi_fdpic (var); + gdbarch = gdbarch_alloc (&info, var); set_gdbarch_short_bit (gdbarch, 16); diff --git a/gdb/frv-tdep.h b/gdb/frv-tdep.h new file mode 100644 index 0000000..3bb9d84 --- /dev/null +++ b/gdb/frv-tdep.h @@ -0,0 +1,35 @@ +/* Architecture-dependent code for the Fujitsu FR-V, for GDB, the GNU Debugger. + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Enumerate the possible ABIs for FR-V. */ +enum frv_abi + { + FRV_ABI_EABI, + FRV_ABI_FDPIC + }; + +/* Return the FR-V ABI associated with GDBARCH. */ +enum frv_abi frv_abi (struct gdbarch *gdbarch); + +/* Fetch the interpreter and executable loadmap addresses (for shared + library support) for the FDPIC ABI. Return 0 if successful, -1 if + 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); |