* [RFC] Add FR-V Linux core file support
@ 2006-02-14 21:10 Kevin Buettner
2006-02-20 15:31 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2006-02-14 21:10 UTC (permalink / raw)
To: gdb-patches
The patch below adds core file support for FR-V running either
GNU/Linux or uClinux.
The interesting part of this patch is the bit which causes the main
executable to get relocated. I thought at first that I would need to
add a new hook which does for core files what SOLIB_CREATE_INFERIOR_HOOK
does for processes, but this turned out to not be necessary. I was able
to handle the case that I care about by adding a suitable call to
frv_current_sos(). I was surprised, however, that we had (apparently)
never run into this problem before.
Comments?
* 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.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.783
diff -u -p -r1.783 Makefile.in
--- Makefile.in 2 Feb 2006 02:26:48 -0000 1.783
+++ Makefile.in 14 Feb 2006 20:44:37 -0000
@@ -1958,9 +1958,10 @@ frame.o: frame.c $(defs_h) $(frame_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) \
Index: frv-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/frv-linux-tdep.c,v
retrieving revision 1.9
diff -u -p -r1.9 frv-linux-tdep.c
--- frv-linux-tdep.c 17 Dec 2005 22:33:59 -0000 1.9
+++ frv-linux-tdep.c 14 Feb 2006 20:44:37 -0000
@@ -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
return NULL;
}
+\f
+/* 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;
+}
+
+\f
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
Index: solib-frv.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-frv.c,v
retrieving revision 1.12
diff -u -p -r1.12 solib-frv.c
--- solib-frv.c 17 Dec 2005 22:34:02 -0000 1.12
+++ solib-frv.c 14 Feb 2006 20:44:37 -0000
@@ -421,6 +421,14 @@ 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. Normally
+ this is done by SOLIB_CREATE_INFERIOR_HOOK(), however, this hook
+ is not run when loading core files. Rather than create a new hook,
+ we'll do it here if necessary. */
+ 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 +968,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
Index: config/frv/frv.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/frv/frv.mt,v
retrieving revision 1.5
diff -u -p -r1.5 frv.mt
--- config/frv/frv.mt 13 Sep 2004 20:55:39 -0000 1.5
+++ config/frv/frv.mt 14 Feb 2006 20:44:37 -0000
@@ -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
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [RFC] Add FR-V Linux core file support
2006-02-14 21:10 [RFC] Add FR-V Linux core file support Kevin Buettner
@ 2006-02-20 15:31 ` Daniel Jacobowitz
2006-02-20 19:52 ` Kevin Buettner
2006-03-02 0:01 ` Kevin Buettner
0 siblings, 2 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2006-02-20 15:31 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
On Tue, Feb 14, 2006 at 02:10:16PM -0700, Kevin Buettner wrote:
> The patch below adds core file support for FR-V running either
> GNU/Linux or uClinux.
>
> The interesting part of this patch is the bit which causes the main
> executable to get relocated. I thought at first that I would need to
> add a new hook which does for core files what SOLIB_CREATE_INFERIOR_HOOK
> does for processes, but this turned out to not be necessary. I was able
> to handle the case that I care about by adding a suitable call to
> frv_current_sos(). I was surprised, however, that we had (apparently)
> never run into this problem before.
>
> Comments?
Hmm, interesting. Two things poke out at me:
> +/* 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
I assume that there can be threading on this target. That means the
regset functions could be used for libthread_db too; are there going to
be loadmaps there too?
I don't much like faking registers this way, but the FRV port has prior
art - this isn't new - so I won't complain too much. I'd have made
them a separate target object.
> @@ -421,6 +421,14 @@ 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. Normally
> + this is done by SOLIB_CREATE_INFERIOR_HOOK(), however, this hook
> + is not run when loading core files. Rather than create a new hook,
> + we'll do it here if necessary. */
> + 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. */
Was this patch written recently, or forward ported from something a
bit older? I'm thinking 2006-01-24 here. The new post_create_inferior
is called when loading core files, and in turn calls
solib_create_inferior_hook.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC] Add FR-V Linux core file support
2006-02-20 15:31 ` Daniel Jacobowitz
@ 2006-02-20 19:52 ` Kevin Buettner
2006-02-20 19:53 ` Daniel Jacobowitz
2006-03-02 0:01 ` Kevin Buettner
1 sibling, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2006-02-20 19:52 UTC (permalink / raw)
To: gdb-patches
On Mon, 20 Feb 2006 10:30:46 -0500
Daniel Jacobowitz <drow@false.org> wrote:
> > +/* 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
>
> I assume that there can be threading on this target. That means the
> regset functions could be used for libthread_db too; are there going to
> be loadmaps there too?
The gregset struct does not include the loadmap addresses. I considered
adding them but decided against it because they'd be the same for all of
the threads. There's no point in bulking up the gregset for an address
which is only really needed for shared library initialization.
> > @@ -421,6 +421,14 @@ 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. Normally
> > + this is done by SOLIB_CREATE_INFERIOR_HOOK(), however, this hook
> > + is not run when loading core files. Rather than create a new hook,
> > + we'll do it here if necessary. */
> > + 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. */
>
> Was this patch written recently, or forward ported from something a
> bit older? I'm thinking 2006-01-24 here. The new post_create_inferior
> is called when loading core files, and in turn calls
> solib_create_inferior_hook.
Yes, it was forward ported from something quite a bit older. I'll try
removing that bit of code and see if it behaves correctly without it.
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC] Add FR-V Linux core file support
2006-02-20 19:52 ` Kevin Buettner
@ 2006-02-20 19:53 ` Daniel Jacobowitz
2006-02-20 19:59 ` Daniel Jacobowitz
2006-03-02 0:08 ` Kevin Buettner
0 siblings, 2 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2006-02-20 19:53 UTC (permalink / raw)
To: gdb-patches, gdb-patches
On Mon, Feb 20, 2006 at 12:52:15PM -0700, Kevin Buettner wrote:
> The gregset struct does not include the loadmap addresses. I considered
> adding them but decided against it because they'd be the same for all of
> the threads. There's no point in bulking up the gregset for an address
> which is only really needed for shared library initialization.
Make sure GDB doesn't try to scribble a loadmap address into a gregset
when requested by libthread_db, then, if anyone tries to unify this
with the fill_gregset used by linux-thread-db.c :-)
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC] Add FR-V Linux core file support
2006-02-20 19:53 ` Daniel Jacobowitz
@ 2006-02-20 19:59 ` Daniel Jacobowitz
2006-03-02 0:08 ` Kevin Buettner
1 sibling, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2006-02-20 19:59 UTC (permalink / raw)
To: gdb-patches, gdb-patches
On Mon, Feb 20, 2006 at 12:52:15PM -0700, Kevin Buettner wrote:
> The gregset struct does not include the loadmap addresses. I considered
> adding them but decided against it because they'd be the same for all of
> the threads. There's no point in bulking up the gregset for an address
> which is only really needed for shared library initialization.
Make sure GDB doesn't try to scribble a loadmap address into a gregset
when requested by libthread_db, then, if anyone tries to unify this
with the fill_gregset used by linux-thread-db.c :-)
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC] Add FR-V Linux core file support
2006-02-20 19:53 ` Daniel Jacobowitz
2006-02-20 19:59 ` Daniel Jacobowitz
@ 2006-03-02 0:08 ` Kevin Buettner
1 sibling, 0 replies; 9+ messages in thread
From: Kevin Buettner @ 2006-03-02 0:08 UTC (permalink / raw)
To: gdb-patches
On Mon, 20 Feb 2006 14:53:44 -0500
Daniel Jacobowitz <drow@false.org> wrote:
> On Mon, Feb 20, 2006 at 12:52:15PM -0700, Kevin Buettner wrote:
> > The gregset struct does not include the loadmap addresses. I considered
> > adding them but decided against it because they'd be the same for all of
> > the threads. There's no point in bulking up the gregset for an address
> > which is only really needed for shared library initialization.
>
> Make sure GDB doesn't try to scribble a loadmap address into a gregset
> when requested by libthread_db, then, if anyone tries to unify this
> with the fill_gregset used by linux-thread-db.c :-)
I checked on this. At the moment, there's no danger of this occurring
since FR-V doesn't define a fill_gregset function. (Thread support is
handled by the stub.)
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC] Add FR-V Linux core file support
2006-02-20 15:31 ` Daniel Jacobowitz
2006-02-20 19:52 ` Kevin Buettner
@ 2006-03-02 0:01 ` Kevin Buettner
2006-03-16 13:44 ` Kevin Buettner
1 sibling, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2006-03-02 0:01 UTC (permalink / raw)
To: gdb-patches
On Mon, 20 Feb 2006 10:30:46 -0500
Daniel Jacobowitz <drow@false.org> wrote:
> > @@ -421,6 +421,14 @@ 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. Normally
> > + this is done by SOLIB_CREATE_INFERIOR_HOOK(), however, this hook
> > + is not run when loading core files. Rather than create a new hook,
> > + we'll do it here if necessary. */
> > + 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. */
>
> Was this patch written recently, or forward ported from something a
> bit older? I'm thinking 2006-01-24 here. The new post_create_inferior
> is called when loading core files, and in turn calls
> solib_create_inferior_hook.
FYI, I just revisited this. post_create_inferior() does indeed cause
the main executable to be relocated. However, the shared libraries
associated with the post mortem aren't being loaded. (My revised
comment below explains why.) Thus, I'm strongly considering retaining
the call to solib_relocate_main_executable() (within the current_sos
function) and revising the comment as follows:
/* 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.) */
The other alternative is to rework post_create_inferior() so that
SOLIB_ADD is called after SOLIB_CREATE_INFERIOR_HOOK. According to
the comments in post_create_inferior() though, this would not be
desirable since SOLIB_ADD might be called without the correct FROM_TTY
values.
Opinions?
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [RFC] Add FR-V Linux core file support
2006-03-02 0:01 ` Kevin Buettner
@ 2006-03-16 13:44 ` Kevin Buettner
2006-03-16 14:49 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Buettner @ 2006-03-16 13:44 UTC (permalink / raw)
To: gdb-patches
I ended up committing the patch below. I believe that this is largely
the same as the original patch. The only difference is that I've revised
one of the comments in solib-frv.c.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.792
diff -u -p -r1.792 Makefile.in
--- Makefile.in 15 Mar 2006 17:13:36 -0000 1.792
+++ Makefile.in 15 Mar 2006 23:37:43 -0000
@@ -1964,9 +1964,10 @@ frame.o: frame.c $(defs_h) $(frame_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) \
Index: frv-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/frv-linux-tdep.c,v
retrieving revision 1.9
diff -u -p -r1.9 frv-linux-tdep.c
--- frv-linux-tdep.c 17 Dec 2005 22:33:59 -0000 1.9
+++ frv-linux-tdep.c 15 Mar 2006 23:37:43 -0000
@@ -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
return NULL;
}
+\f
+/* 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;
+}
+
+\f
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
Index: solib-frv.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-frv.c,v
retrieving revision 1.12
diff -u -p -r1.12 solib-frv.c
--- solib-frv.c 17 Dec 2005 22:34:02 -0000 1.12
+++ solib-frv.c 15 Mar 2006 23:37:43 -0000
@@ -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
Index: config/frv/frv.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/frv/frv.mt,v
retrieving revision 1.5
diff -u -p -r1.5 frv.mt
--- config/frv/frv.mt 13 Sep 2004 20:55:39 -0000 1.5
+++ config/frv/frv.mt 15 Mar 2006 23:37:43 -0000
@@ -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
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [RFC] Add FR-V Linux core file support
2006-03-16 13:44 ` Kevin Buettner
@ 2006-03-16 14:49 ` Daniel Jacobowitz
0 siblings, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2006-03-16 14:49 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
On Wed, Mar 15, 2006 at 04:40:26PM -0700, Kevin Buettner wrote:
> I ended up committing the patch below. I believe that this is largely
> the same as the original patch. The only difference is that I've revised
> one of the comments in solib-frv.c.
Thanks, and sorry for not getting back to you earlier.
I think that it would be logical to call solib_create_inferior_hook
before solib_add. It might be as simple as adding a whole lot of
from_tty markers somewhere, or otherwise revising how the outputting
works in this area; the current version is a bit incoherent.
The problem associated with swapping the order is fairly ugly; I
believe that if you do that and then attach to a process you'll get
a lot of "symbols for foo are already loaded" messages.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-03-15 23:45 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-02-14 21:10 [RFC] Add FR-V Linux core file support Kevin Buettner
2006-02-20 15:31 ` Daniel Jacobowitz
2006-02-20 19:52 ` Kevin Buettner
2006-02-20 19:53 ` Daniel Jacobowitz
2006-02-20 19:59 ` Daniel Jacobowitz
2006-03-02 0:08 ` Kevin Buettner
2006-03-02 0:01 ` Kevin Buettner
2006-03-16 13:44 ` Kevin Buettner
2006-03-16 14:49 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox