Add FR-V Linux core file support.

This commit is contained in:
Kevin Buettner 2006-03-15 23:38:09 +00:00
parent 4546b4af95
commit 7c699b8111
5 changed files with 205 additions and 4 deletions

View file

@ -1,3 +1,24 @@
2006-03-15 Kevin Buettner <kevinb@redhat.com>
* frv-linux-tdep.c (gdbcore.h, regcache.h, regset.h, gdb_string.h):
Include.
(FRV_ELF_NGREG, FRV_PT_PSR, FRV_PT_ISR, FRV_PT_CCR, FRV_PT_CCCR)
(FRV_PT_LR, FRV_PT_LCR, FRV_PT_PC, FRV_PT_GNER0, FRV_PT_GNER1)
(FRV_PT_IACC0H, FRV_PT_IACC0L, FRV_PT_GR, FRV_PT_TBR)
(FRV_PT_EXEC_FDPIC_LOADMAP, FRV_PT_INTERP_FDPIC_LOADMAP): Define.
(frv_elf_greg_t, frv_elf_gregset_t, frv_elf_fpreg_t)
(frv_elf_fpregset_t): Define types.
(frv_linux_supply_gregset, frv_linux_supply_fpregset)
(frv_linux_regset_from_core_section: New functions.
(frv_linux_gregset, frv_linux_fpregset): New static globals.
(frv_linux_init_abi): Register the `regset_from_core_section' method.
* Makefile.in (frv-linux-tdep.o): Update dependencies.
* solib-frv.c (frv_current_sos): Relocate main executable after
loading core file.
(frv_clear_solib): Clean up space associated with
`main_executable_lm_info'.
* config/frv/frv.mt (TDEPFILES): Add corelow.o to this list.
2006-03-15 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (mips_linux_tdep_h): New.

View file

@ -1964,9 +1964,10 @@ frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \
$(command_h) $(gdbcmd_h) $(observer_h) $(objfiles_h) $(exceptions_h)
frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \
$(gdb_assert_h) $(dummy_frame_h) $(gdb_obstack_h)
frv-linux-tdep.o: frv-linux-tdep.c $(defs_h) $(target_h) $(frame_h) \
$(osabi_h) $(elf_bfd_h) $(elf_frv_h) $(frv_tdep_h) $(trad_frame_h) \
$(frame_unwind_h)
frv-linux-tdep.o: frv-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
$(frame_h) $(osabi_h) $(regcache_h) $(elf_bfd_h) $(elf_frv_h) \
$(frv_tdep_h) $(trad_frame_h) $(frame_unwind_h) $(regset_h) \
$(gdb_string_h)
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) \

View file

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

View file

@ -20,14 +20,18 @@
Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "frame.h"
#include "osabi.h"
#include "regcache.h"
#include "elf-bfd.h"
#include "elf/frv.h"
#include "frv-tdep.h"
#include "trad-frame.h"
#include "frame-unwind.h"
#include "regset.h"
#include "gdb_string.h"
/* Define the size (in bytes) of an FR-V instruction. */
static const int frv_instr_size = 4;
@ -329,11 +333,162 @@ frv_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
return NULL;
}
/* The FRV kernel defines ELF_NGREG as 46. We add 2 in order to include
the loadmap addresses in the register set. (See below for more info.) */
#define FRV_ELF_NGREG (46 + 2)
typedef unsigned char frv_elf_greg_t[4];
typedef struct { frv_elf_greg_t reg[FRV_ELF_NGREG]; } frv_elf_gregset_t;
typedef unsigned char frv_elf_fpreg_t[4];
typedef struct
{
frv_elf_fpreg_t fr[64];
frv_elf_fpreg_t fner[2];
frv_elf_fpreg_t msr[2];
frv_elf_fpreg_t acc[8];
unsigned char accg[8];
frv_elf_fpreg_t fsr[1];
} frv_elf_fpregset_t;
/* Constants for accessing elements of frv_elf_gregset_t. */
#define FRV_PT_PSR 0
#define FRV_PT_ISR 1
#define FRV_PT_CCR 2
#define FRV_PT_CCCR 3
#define FRV_PT_LR 4
#define FRV_PT_LCR 5
#define FRV_PT_PC 6
#define FRV_PT_GNER0 10
#define FRV_PT_GNER1 11
#define FRV_PT_IACC0H 12
#define FRV_PT_IACC0L 13
/* Note: Only 32 of the GRs will be found in the corefile. */
#define FRV_PT_GR(j) ( 14 + (j)) /* GRj for 0<=j<=63. */
#define FRV_PT_TBR FRV_PT_GR(0) /* gr0 is always 0, so TBR is stuffed
there. */
/* Technically, the loadmap addresses are not part of `pr_reg' as
found in the elf_prstatus struct. The fields which communicate the
loadmap address appear (by design) immediately after `pr_reg'
though, and the BFD function elf32_frv_grok_prstatus() has been
implemented to include these fields in the register section that it
extracts from the core file. So, for our purposes, they may be
viewed as registers. */
#define FRV_PT_EXEC_FDPIC_LOADMAP 46
#define FRV_PT_INTERP_FDPIC_LOADMAP 47
/* Unpack an frv_elf_gregset_t into GDB's register cache. */
static void
frv_linux_supply_gregset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *gregs, size_t len)
{
int regi;
char zerobuf[MAX_REGISTER_SIZE];
const frv_elf_gregset_t *gregsetp = gregs;
memset (zerobuf, 0, MAX_REGISTER_SIZE);
/* gr0 always contains 0. Also, the kernel passes the TBR value in
this slot. */
regcache_raw_supply (regcache, first_gpr_regnum, zerobuf);
for (regi = first_gpr_regnum + 1; regi <= last_gpr_regnum; regi++)
{
if (regi >= first_gpr_regnum + 32)
regcache_raw_supply (regcache, regi, zerobuf);
else
regcache_raw_supply (regcache, regi,
gregsetp->reg[FRV_PT_GR (regi - first_gpr_regnum)]);
}
regcache_raw_supply (regcache, pc_regnum, gregsetp->reg[FRV_PT_PC]);
regcache_raw_supply (regcache, psr_regnum, gregsetp->reg[FRV_PT_PSR]);
regcache_raw_supply (regcache, ccr_regnum, gregsetp->reg[FRV_PT_CCR]);
regcache_raw_supply (regcache, cccr_regnum, gregsetp->reg[FRV_PT_CCCR]);
regcache_raw_supply (regcache, lr_regnum, gregsetp->reg[FRV_PT_LR]);
regcache_raw_supply (regcache, lcr_regnum, gregsetp->reg[FRV_PT_LCR]);
regcache_raw_supply (regcache, gner0_regnum, gregsetp->reg[FRV_PT_GNER0]);
regcache_raw_supply (regcache, gner1_regnum, gregsetp->reg[FRV_PT_GNER1]);
regcache_raw_supply (regcache, tbr_regnum, gregsetp->reg[FRV_PT_TBR]);
regcache_raw_supply (regcache, fdpic_loadmap_exec_regnum,
gregsetp->reg[FRV_PT_EXEC_FDPIC_LOADMAP]);
regcache_raw_supply (regcache, fdpic_loadmap_interp_regnum,
gregsetp->reg[FRV_PT_INTERP_FDPIC_LOADMAP]);
}
/* Unpack an frv_elf_fpregset_t into GDB's register cache. */
static void
frv_linux_supply_fpregset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *gregs, size_t len)
{
int regi;
const frv_elf_fpregset_t *fpregsetp = gregs;
for (regi = first_fpr_regnum; regi <= last_fpr_regnum; regi++)
regcache_raw_supply (regcache, regi, fpregsetp->fr[regi - first_fpr_regnum]);
regcache_raw_supply (regcache, fner0_regnum, fpregsetp->fner[0]);
regcache_raw_supply (regcache, fner1_regnum, fpregsetp->fner[1]);
regcache_raw_supply (regcache, msr0_regnum, fpregsetp->msr[0]);
regcache_raw_supply (regcache, msr1_regnum, fpregsetp->msr[1]);
for (regi = acc0_regnum; regi <= acc7_regnum; regi++)
regcache_raw_supply (regcache, regi, fpregsetp->acc[regi - acc0_regnum]);
regcache_raw_supply (regcache, accg0123_regnum, fpregsetp->accg);
regcache_raw_supply (regcache, accg4567_regnum, fpregsetp->accg + 4);
regcache_raw_supply (regcache, fsr0_regnum, fpregsetp->fsr[0]);
}
/* FRV Linux register sets. */
static struct regset frv_linux_gregset =
{
NULL,
frv_linux_supply_gregset
};
static struct regset frv_linux_fpregset =
{
NULL,
frv_linux_supply_fpregset
};
static const struct regset *
frv_linux_regset_from_core_section (struct gdbarch *gdbarch,
const char *sect_name, size_t sect_size)
{
if (strcmp (sect_name, ".reg") == 0
&& sect_size >= sizeof (frv_elf_gregset_t))
return &frv_linux_gregset;
if (strcmp (sect_name, ".reg2") == 0
&& sect_size >= sizeof (frv_elf_fpregset_t))
return &frv_linux_fpregset;
return NULL;
}
static void
frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
/* Set the sigtramp frame sniffer. */
frame_unwind_append_sniffer (gdbarch, frv_linux_sigtramp_frame_sniffer);
set_gdbarch_regset_from_core_section (gdbarch,
frv_linux_regset_from_core_section);
}
static enum gdb_osabi

View file

@ -421,6 +421,22 @@ frv_current_sos (void)
struct so_list *sos_head = NULL;
struct so_list **sos_next_ptr = &sos_head;
/* Make sure that the main executable has been relocated. This is
required in order to find the address of the global offset table,
which in turn is used to find the link map info. (See lm_base()
for details.)
Note that the relocation of the main executable is also performed
by SOLIB_CREATE_INFERIOR_HOOK(), however, in the case of core
files, this hook is called too late in order to be of benefit to
SOLIB_ADD. SOLIB_ADD eventually calls this this function,
frv_current_sos, and also precedes the call to
SOLIB_CREATE_INFERIOR_HOOK(). (See post_create_inferior() in
infcmd.c.) */
if (main_executable_lm_info == 0 && core_bfd != NULL)
frv_relocate_main_executable ();
/* Fetch the GOT corresponding to the main executable. */
mgot = main_got ();
/* Locate the address of the first link map struct. */
@ -960,6 +976,14 @@ frv_clear_solib (void)
enable_break1_done = 0;
enable_break2_done = 0;
main_lm_addr = 0;
if (main_executable_lm_info != 0)
{
xfree (main_executable_lm_info->map);
xfree (main_executable_lm_info->dyn_syms);
xfree (main_executable_lm_info->dyn_relocs);
xfree (main_executable_lm_info);
main_executable_lm_info = 0;
}
}
static void