2009-10-21 Andrew Stubbs <ams@codesourcery.com>

Joel Brobecker  <brobecker@adacore.com>

	* Makefile.in (HFILES_NO_SRCDIR): Remove shnbsd-tdep.h
	* configure.tgt (sh*-*-linux*): Add corelow.o to gdb_target_obs.
	* sh-linux-tdep.c: Include sh-tdep.h.
	(REGSx16): New macro.
	(gregs_table, fpregs_table): New variables.
	(sh_linux_init_abi): Set core_gregmap and fpregmap.
	* sh-tdep.c: Include regset.h.
	(sh_corefile_supply_regset): New function.
	(sh_corefile_collect_regset): New function.
	(sh_corefile_gregset, sh_corefile_fpregset): New variables.
	(sh_regset_from_core_section): New function.
	(sh_gdbarch_init): Set up tdep value.
	Call set_gdbarch_regset_from_core_section.
	* sh-tdep.h (PC_REGNUM): New enum value.
	(struct sh_corefile_regs): New type.
	(sh_corefile_gregset): Export variable.
	(sh_corefile_supply_regset): New prototype.
	(sh_corefile_collect_regset): New prototype.
	* shnbsd-tdep.c: Remove include of regcache.h, gdb_assert.h and
	shnbsd-tdep.h.
	(regmap): Use new definition using struct sh_corefile_regs.
	(shnbsd_supply_gregset, shnbsd_collect_gregset): Delete.
	(shnbsd_gregset): Delete.
	(shnbsd_regset_from_core_section): Delete.
	(shnbsd_supply_reg, shnbsd_fill_reg): Use new regset interface.
	(shnbsd_init_abi): Set core_gregmap.
	(shnbsd_supply_reg): Delete.
	(shnbsd_fill_reg): Delete.
	(SHNBSD_SIZEOF_GREGS): Move ...
	* shnbsd-nat.c (SHNBSD_SIZEOF_GREGS): ... to here.
	Remove include of shnbsd-tdep.h.
	(shnbsd_fetch_inferior_registers): Replace shnbsd_supply_reg call
	with sh_corefile_supply_regset.
	(shnbsd_store_inferior_registers): Replace shnbsd_fill_reg call with
	sh_corefile_collect_regset.
	* shnbsd-tdep.h: Delete file.
This commit is contained in:
Andrew Stubbs 2009-10-21 14:14:57 +00:00
parent 47607d6f7c
commit c9ac0a72c9
9 changed files with 251 additions and 171 deletions

View File

@ -1,3 +1,43 @@
2009-10-21 Andrew Stubbs <ams@codesourcery.com>
Joel Brobecker <brobecker@adacore.com>
* Makefile.in (HFILES_NO_SRCDIR): Remove shnbsd-tdep.h
* configure.tgt (sh*-*-linux*): Add corelow.o to gdb_target_obs.
* sh-linux-tdep.c: Include sh-tdep.h.
(REGSx16): New macro.
(gregs_table, fpregs_table): New variables.
(sh_linux_init_abi): Set core_gregmap and fpregmap.
* sh-tdep.c: Include regset.h.
(sh_corefile_supply_regset): New function.
(sh_corefile_collect_regset): New function.
(sh_corefile_gregset, sh_corefile_fpregset): New variables.
(sh_regset_from_core_section): New function.
(sh_gdbarch_init): Set up tdep value.
Call set_gdbarch_regset_from_core_section.
* sh-tdep.h (PC_REGNUM): New enum value.
(struct sh_corefile_regs): New type.
(sh_corefile_gregset): Export variable.
(sh_corefile_supply_regset): New prototype.
(sh_corefile_collect_regset): New prototype.
* shnbsd-tdep.c: Remove include of regcache.h, gdb_assert.h and
shnbsd-tdep.h.
(regmap): Use new definition using struct sh_corefile_regs.
(shnbsd_supply_gregset, shnbsd_collect_gregset): Delete.
(shnbsd_gregset): Delete.
(shnbsd_regset_from_core_section): Delete.
(shnbsd_supply_reg, shnbsd_fill_reg): Use new regset interface.
(shnbsd_init_abi): Set core_gregmap.
(shnbsd_supply_reg): Delete.
(shnbsd_fill_reg): Delete.
(SHNBSD_SIZEOF_GREGS): Move ...
* shnbsd-nat.c (SHNBSD_SIZEOF_GREGS): ... to here.
Remove include of shnbsd-tdep.h.
(shnbsd_fetch_inferior_registers): Replace shnbsd_supply_reg call
with sh_corefile_supply_regset.
(shnbsd_store_inferior_registers): Replace shnbsd_fill_reg call with
sh_corefile_collect_regset.
* shnbsd-tdep.h: Delete file.
2009-10-21 Pierre Muller <muller@ics.u-strasbg.fr>
* rs6000-nat.c (exec_one_dummy_insn): Add missing new ASPACE parameter

View File

@ -723,7 +723,7 @@ f-lang.h dwarf2loc.h value.h sparc-tdep.h defs.h target-descriptions.h \
objfiles.h vec.h disasm.h mips-tdep.h ser-base.h \
gdb_curses.h bfd-target.h memattr.h inferior.h ax.h dummy-frame.h \
inflow.h fbsd-nat.h libunwind-frame.h completer.h inf-ttrace.h \
solib-target.h shnbsd-tdep.h gdb_vfork.h alpha-tdep.h dwarf2expr.h \
solib-target.h gdb_vfork.h alpha-tdep.h dwarf2expr.h \
m2-lang.h stack.h charset.h addrmap.h command.h solist.h source.h \
target.h prologue-value.h cp-abi.h tui/tui-hooks.h tui/tui.h \
tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \

View File

@ -420,7 +420,8 @@ score-*-*)
sh*-*-linux*)
# Target: GNU/Linux Super-H
gdb_target_obs="sh-tdep.o sh64-tdep.o sh-linux-tdep.o monitor.o \
dsrec.o solib.o solib-svr4.o symfile-mem.o glibc-tdep.o"
dsrec.o solib.o solib-svr4.o symfile-mem.o \
glibc-tdep.o corelow.o"
gdb_sim=../sim/sh/libsim.a
build_gdbserver=yes
;;

View File

@ -24,6 +24,50 @@
#include "symtab.h"
#include "glibc-tdep.h"
#include "sh-tdep.h"
#define REGSx16(base) \
{(base), 0}, \
{(base) + 1, 4}, \
{(base) + 2, 8}, \
{(base) + 3, 12}, \
{(base) + 4, 16}, \
{(base) + 5, 20}, \
{(base) + 6, 24}, \
{(base) + 7, 28}, \
{(base) + 8, 32}, \
{(base) + 9, 36}, \
{(base) + 10, 40}, \
{(base) + 11, 44}, \
{(base) + 12, 48}, \
{(base) + 13, 52}, \
{(base) + 14, 56}, \
{(base) + 15, 60}
/* Describe the contents of the .reg section of the core file. */
static const struct sh_corefile_regmap gregs_table[] =
{
REGSx16 (R0_REGNUM),
{PC_REGNUM, 64},
{PR_REGNUM, 68},
{SR_REGNUM, 72},
{GBR_REGNUM, 76},
{MACH_REGNUM, 80},
{MACL_REGNUM, 84},
{-1 /* Terminator. */, 0}
};
/* Describe the contents of the .reg2 section of the core file. */
static const struct sh_corefile_regmap fpregs_table[] =
{
REGSx16 (FR0_REGNUM),
/* REGSx16 xfp_regs omitted. */
{FPSCR_REGNUM, 128},
{FPUL_REGNUM, 132},
{-1 /* Terminator. */, 0}
};
static void
sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
@ -36,6 +80,15 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
/* Core files are supported for 32-bit SH only, at present. */
if (info.bfd_arch_info->mach != bfd_mach_sh5)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
tdep->core_gregmap = (struct sh_corefile_regmap *)gregs_table;
tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregs_table;
}
}
/* Provide a prototype to silence -Wmissing-prototypes. */

View File

@ -43,6 +43,7 @@
#include "doublest.h"
#include "osabi.h"
#include "reggroups.h"
#include "regset.h"
#include "sh-tdep.h"
@ -2738,12 +2739,98 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
}
return 0;
}
/* Supply register REGNUM from the buffer specified by REGS and LEN
in the register set REGSET to register cache REGCACHE.
REGTABLE specifies where each register can be found in REGS.
If REGNUM is -1, do this for all registers in REGSET. */
void
sh_corefile_supply_regset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *regs, size_t len)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset
? tdep->core_gregmap
: tdep->core_fpregmap);
int i;
for (i = 0; regmap[i].regnum != -1; i++)
{
if ((regnum == -1 || regnum == regmap[i].regnum)
&& regmap[i].offset + 4 <= len)
regcache_raw_supply (regcache, regmap[i].regnum,
(char *)regs + regmap[i].offset);
}
}
/* Collect register REGNUM in the register set REGSET from register cache
REGCACHE into the buffer specified by REGS and LEN.
REGTABLE specifies where each register can be found in REGS.
If REGNUM is -1, do this for all registers in REGSET. */
void
sh_corefile_collect_regset (const struct regset *regset,
const struct regcache *regcache,
int regnum, void *regs, size_t len)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset
? tdep->core_gregmap
: tdep->core_fpregmap);
int i;
for (i = 0; regmap[i].regnum != -1; i++)
{
if ((regnum == -1 || regnum == regmap[i].regnum)
&& regmap[i].offset + 4 <= len)
regcache_raw_collect (regcache, regmap[i].regnum,
(char *)regs + regmap[i].offset);
}
}
/* The following two regsets have the same contents, so it is tempting to
unify them, but they are distiguished by their address, so don't. */
struct regset sh_corefile_gregset =
{
NULL,
sh_corefile_supply_regset,
sh_corefile_collect_regset
};
static struct regset sh_corefile_fpregset =
{
NULL,
sh_corefile_supply_regset,
sh_corefile_collect_regset
};
static const struct regset *
sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name,
size_t sect_size)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (tdep->core_gregmap && strcmp (sect_name, ".reg") == 0)
return &sh_corefile_gregset;
if (tdep->core_fpregmap && strcmp (sect_name, ".reg2") == 0)
return &sh_corefile_fpregset;
return NULL;
}
static struct gdbarch *
sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
sh_show_regs = sh_generic_show_regs;
switch (info.bfd_arch_info->mach)
@ -2803,7 +2890,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* None found, create a new architecture from the information
provided. */
gdbarch = gdbarch_alloc (&info, NULL);
tdep = XZALLOC (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
@ -2847,6 +2935,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
dwarf2_frame_set_init_reg (gdbarch, sh_dwarf2_frame_init_reg);
set_gdbarch_regset_from_core_section (gdbarch, sh_regset_from_core_section);
switch (info.bfd_arch_info->mach)
{
case bfd_mach_sh:

View File

@ -30,6 +30,7 @@ enum
ARG0_REGNUM = 4,
ARGLAST_REGNUM = 7,
FP_REGNUM = 14,
PC_REGNUM = 16,
PR_REGNUM = 17,
GBR_REGNUM = 18,
VBR_REGNUM = 19,
@ -85,4 +86,31 @@ enum
extern gdbarch_init_ftype sh64_gdbarch_init;
extern void sh64_show_regs (struct frame_info *);
/* This structure describes a register in a core-file. */
struct sh_corefile_regmap
{
int regnum;
unsigned int offset;
};
struct gdbarch_tdep
{
/* Non-NULL when debugging from a core file. Provides the offset
where each general-purpose register is stored inside the associated
core file section. */
struct sh_corefile_regmap *core_gregmap;
/* Non-NULL when debugging from a core file and when FP registers are
available. Provides the offset where each FP register is stored
inside the associated core file section. */
struct sh_corefile_regmap *core_fpregmap;
};
extern struct regset sh_corefile_gregset;
void sh_corefile_supply_regset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *regs, size_t len);
void sh_corefile_collect_regset (const struct regset *regset,
const struct regcache *regcache,
int regnum, void *regs, size_t len);
#endif /* SH_TDEP_H */

View File

@ -28,7 +28,6 @@
#include <machine/reg.h>
#include "sh-tdep.h"
#include "shnbsd-tdep.h"
#include "inf-ptrace.h"
#include "regcache.h"
@ -40,6 +39,9 @@
|| (regno) == MACH_REGNUM || (regno) == MACL_REGNUM \
|| (regno) == SR_REGNUM)
/* Sizeof `struct reg' in <machine/reg.h>. */
#define SHNBSD_SIZEOF_GREGS (21 * 4)
static void
shnbsd_fetch_inferior_registers (struct target_ops *ops,
struct regcache *regcache, int regno)
@ -52,7 +54,9 @@ shnbsd_fetch_inferior_registers (struct target_ops *ops,
(PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
perror_with_name (_("Couldn't get registers"));
shnbsd_supply_reg (regcache, (char *) &inferior_registers, regno);
sh_corefile_supply_regset (&sh_corefile_gregset, regcache, regno,
(char *) &inferior_registers,
SHNBSD_SIZEOF_GREGS);
if (regno != -1)
return;
@ -71,7 +75,9 @@ shnbsd_store_inferior_registers (struct target_ops *ops,
(PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
perror_with_name (_("Couldn't get registers"));
shnbsd_fill_reg (regcache, (char *) &inferior_registers, regno);
sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
(char *) &inferior_registers,
SHNBSD_SIZEOF_GREGS);
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)

View File

@ -22,163 +22,51 @@
#include "defs.h"
#include "gdbcore.h"
#include "regcache.h"
#include "regset.h"
#include "value.h"
#include "osabi.h"
#include "gdb_assert.h"
#include "gdb_string.h"
#include "sh-tdep.h"
#include "shnbsd-tdep.h"
#include "solib-svr4.h"
/* Convert an r0-r15 register number into an offset into a ptrace
/* Convert a register number into an offset into a ptrace
register structure. */
static const int regmap[] =
static const struct sh_corefile_regmap regmap[] =
{
(20 * 4), /* r0 */
(19 * 4), /* r1 */
(18 * 4), /* r2 */
(17 * 4), /* r3 */
(16 * 4), /* r4 */
(15 * 4), /* r5 */
(14 * 4), /* r6 */
(13 * 4), /* r7 */
(12 * 4), /* r8 */
(11 * 4), /* r9 */
(10 * 4), /* r10 */
( 9 * 4), /* r11 */
( 8 * 4), /* r12 */
( 7 * 4), /* r13 */
( 6 * 4), /* r14 */
( 5 * 4), /* r15 */
{R0_REGNUM, 20 * 4},
{R0_REGNUM + 1, 19 * 4},
{R0_REGNUM + 2, 18 * 4},
{R0_REGNUM + 3, 17 * 4},
{R0_REGNUM + 4, 16 * 4},
{R0_REGNUM + 5, 15 * 4},
{R0_REGNUM + 6, 14 * 4},
{R0_REGNUM + 7, 13 * 4},
{R0_REGNUM + 8, 12 * 4},
{R0_REGNUM + 9, 11 * 4},
{R0_REGNUM + 10, 10 * 4},
{R0_REGNUM + 11, 9 * 4},
{R0_REGNUM + 12, 8 * 4},
{R0_REGNUM + 13, 7 * 4},
{R0_REGNUM + 14, 6 * 4},
{R0_REGNUM + 15, 5 * 4},
{PC_REGNUM, 0 * 4},
{SR_REGNUM, 1 * 4},
{PR_REGNUM, 2 * 4},
{MACH_REGNUM, 3 * 4},
{MACL_REGNUM, 4 * 4},
{-1 /* Terminator. */, 0}
};
/* Sizeof `struct reg' in <machine/reg.h>. */
#define SHNBSD_SIZEOF_GREGS (21 * 4)
/* Supply register REGNUM from the buffer specified by GREGS and LEN
in the general-purpose register set REGSET to register cache
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
static void
shnbsd_supply_gregset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *gregs, size_t len)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
const gdb_byte *regs = gregs;
int i;
gdb_assert (len >= SHNBSD_SIZEOF_GREGS);
if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch),
regs + (0 * 4));
if (regnum == SR_REGNUM || regnum == -1)
regcache_raw_supply (regcache, SR_REGNUM, regs + (1 * 4));
if (regnum == PR_REGNUM || regnum == -1)
regcache_raw_supply (regcache, PR_REGNUM, regs + (2 * 4));
if (regnum == MACH_REGNUM || regnum == -1)
regcache_raw_supply (regcache, MACH_REGNUM, regs + (3 * 4));
if (regnum == MACL_REGNUM || regnum == -1)
regcache_raw_supply (regcache, MACL_REGNUM, regs + (4 * 4));
for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
{
if (regnum == i || regnum == -1)
regcache_raw_supply (regcache, i, regs + regmap[i - R0_REGNUM]);
}
}
/* Collect register REGNUM in the general-purpose register set
REGSET. from register cache REGCACHE into the buffer specified by
GREGS and LEN. If REGNUM is -1, do this for all registers in
REGSET. */
static void
shnbsd_collect_gregset (const struct regset *regset,
const struct regcache *regcache,
int regnum, void *gregs, size_t len)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
gdb_byte *regs = gregs;
int i;
gdb_assert (len >= SHNBSD_SIZEOF_GREGS);
if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch),
regs + (0 * 4));
if (regnum == SR_REGNUM || regnum == -1)
regcache_raw_collect (regcache, SR_REGNUM, regs + (1 * 4));
if (regnum == PR_REGNUM || regnum == -1)
regcache_raw_collect (regcache, PR_REGNUM, regs + (2 * 4));
if (regnum == MACH_REGNUM || regnum == -1)
regcache_raw_collect (regcache, MACH_REGNUM, regs + (3 * 4));
if (regnum == MACL_REGNUM || regnum == -1)
regcache_raw_collect (regcache, MACL_REGNUM, regs + (4 * 4));
for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++)
{
if (regnum == i || regnum == -1)
regcache_raw_collect (regcache, i, regs + regmap[i - R0_REGNUM]);
}
}
/* SH register sets. */
static struct regset shnbsd_gregset =
{
NULL,
shnbsd_supply_gregset,
shnbsd_collect_gregset
};
/* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
static const struct regset *
shnbsd_regset_from_core_section (struct gdbarch *gdbarch,
const char *sect_name, size_t sect_size)
{
if (strcmp (sect_name, ".reg") == 0 && sect_size >= SHNBSD_SIZEOF_GREGS)
return &shnbsd_gregset;
return NULL;
}
void
shnbsd_supply_reg (struct regcache *regcache, const char *regs, int regnum)
{
shnbsd_supply_gregset (&shnbsd_gregset, regcache, regnum,
regs, SHNBSD_SIZEOF_GREGS);
}
void
shnbsd_fill_reg (const struct regcache *regcache, char *regs, int regnum)
{
shnbsd_collect_gregset (&shnbsd_gregset, regcache, regnum,
regs, SHNBSD_SIZEOF_GREGS);
}
static void
shnbsd_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
{
set_gdbarch_regset_from_core_section
(gdbarch, shnbsd_regset_from_core_section);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);

View File

@ -1,26 +0,0 @@
/* Target-dependent definitions for SuperH running NetBSD, for GDB.
Copyright (C) 2002, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Wasabi Systems, 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 3 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, see <http://www.gnu.org/licenses/>. */
#ifndef SH_NBSD_TDEP_H
#define SH_NBSD_TDEP_H
void shnbsd_supply_reg (struct regcache *, const char *, int);
void shnbsd_fill_reg (const struct regcache *, char *, int);
#endif /* SH_NBSD_TDEP_H */