diff options
-rw-r--r-- | gdb/ChangeLog | 40 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/configure.tgt | 3 | ||||
-rw-r--r-- | gdb/sh-linux-tdep.c | 53 | ||||
-rw-r--r-- | gdb/sh-tdep.c | 92 | ||||
-rw-r--r-- | gdb/sh-tdep.h | 28 | ||||
-rw-r--r-- | gdb/shnbsd-nat.c | 12 | ||||
-rw-r--r-- | gdb/shnbsd-tdep.c | 166 | ||||
-rw-r--r-- | gdb/shnbsd-tdep.h | 26 |
9 files changed, 251 insertions, 171 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0154ce7..199b652 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 0172782..e5e8cfe 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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 \ diff --git a/gdb/configure.tgt b/gdb/configure.tgt index c123510..b18e3b2 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -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 ;; diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c index 46aad1d..4e9d18c 100644 --- a/gdb/sh-linux-tdep.c +++ b/gdb/sh-linux-tdep.c @@ -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. */ diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 3e509bf..e3fa62f 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -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: diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h index dfa928e..76a6236 100644 --- a/gdb/sh-tdep.h +++ b/gdb/sh-tdep.h @@ -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 */ diff --git a/gdb/shnbsd-nat.c b/gdb/shnbsd-nat.c index 90b0406..1aad4ba 100644 --- a/gdb/shnbsd-nat.c +++ b/gdb/shnbsd-nat.c @@ -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) diff --git a/gdb/shnbsd-tdep.c b/gdb/shnbsd-tdep.c index a0cddc5..18a2a73 100644 --- a/gdb/shnbsd-tdep.c +++ b/gdb/shnbsd-tdep.c @@ -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); diff --git a/gdb/shnbsd-tdep.h b/gdb/shnbsd-tdep.h deleted file mode 100644 index 0443c97..0000000 --- a/gdb/shnbsd-tdep.h +++ /dev/null @@ -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 */ |