diff options
-rw-r--r-- | gdb/ChangeLog | 52 | ||||
-rw-r--r-- | gdb/Makefile.in | 12 | ||||
-rw-r--r-- | gdb/config/sparc/linux.mh | 13 | ||||
-rw-r--r-- | gdb/config/sparc/linux.mt | 5 | ||||
-rw-r--r-- | gdb/config/sparc/nm-linux.h | 16 | ||||
-rw-r--r-- | gdb/config/sparc/tm-linux.h | 21 | ||||
-rw-r--r-- | gdb/configure.host | 1 | ||||
-rw-r--r-- | gdb/configure.tgt | 1 | ||||
-rw-r--r-- | gdb/sparc-linux-nat.c | 101 | ||||
-rw-r--r-- | gdb/sparc-linux-tdep.c | 46 | ||||
-rw-r--r-- | gdb/sparc-nat.c | 434 | ||||
-rw-r--r-- | gdb/sparc-sol2-nat.c | 9 | ||||
-rw-r--r-- | gdb/sparc-sol2-tdep.c | 160 | ||||
-rw-r--r-- | gdb/sparc-tdep.c | 173 | ||||
-rw-r--r-- | gdb/sparc-tdep.h | 42 |
15 files changed, 497 insertions, 589 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d328a59a74a..b586f685245 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,55 @@ +2003-10-25 Mark Kettenis <kettenis@gnu.org> + + * sparc-tdep.h (struct sparc_gregset): New. + (sparc_sol2_supply_gregset, sparc_sol2_collect_gregset, + sparc_sol2_supply_fpregset, sparc_sol2_collect_fpregset): Remove + prototypes. + (sparc_supply_gregset, sparc_collect_gregset, + sparc_supply_fpregset, sparc_collect_fpregset): New prototypes. + (sparc32_sunos4_gregset, sparc32_sol2_gregset): New extern + declarations. + (sparc32_sol2_init_abi): Rename from sparc_sol2_init_abi. + * sparc-tdep.c (sparc_supply_gregset, sparc_collect_gregset, + sparc_supply_fpregset, sparc_collect_fpregset): New function. + (sparc32_sunos4_gregset): New variable. + * sparc-sol2-tdep.c (sparc_sol2_R_PSR, sparc_sol2_R_PC, + sparc_sol2_R_nPC, sparc_sol2_R_Y, sparc_sol2_R_WIM, + sparc_sol2_R_TBR): Remove variables. + (sparc_sol2_supply_gregset, sparc_sol2_collect_gregset, + sparc_sol2_supply_fpregset, sparc_sol2_collect_fpregset): Remove + functions. + (sparc32_sol2_gregset): New variable. + (sparc32_sol2_sigtramp_frame_cache): Rename from + sparc_sol2_sigtramp_frame_cache. + (sparc32_sol2_sigtramp_frame_this_id): Rename from + sparc_sol2_sigtramp_frame_this_id. + (sparc32_sol2_sigtramp_frame_prev_register): Rename from + sparc_sol2_sigtramp_frame_prev_register. + (sparc32_sol2_sigtramp_frame_unwind): Rename from + sparc_sol2_sigtramp_frame_unwind. + (sparc32_sol2_sigtramp_frame_sniffer): Rename from + sparc_sol2_sigtramp_frame_sniffer. + (sparc32_sol2_init_abi): Rename from sparc_sol2_init_abi. + (_initialize_sparc_sol2_tdep): Update. + * sparc-linux-tdep.c: New file. + * sparc-nat.o: Replace with new file. + * sparc-linux-nat.c: Remove file. + * config/sparc/linux.mh (XM_FILE, HOST_IPC): Remove. + (NATDEPFILES): Add sparc-sol2-nat.o and core-regset.o. Remove + sparc-linux-nat.o. + * config/sparc/linux.mt (TDEPFILES): Add sparc-sol2-tdep.o and + sparc-linux-tdep.o. + * config/sparc/nm-linux.h: Don't include "config/nm-svr4.h" and + "solib.h". Add protection against multiple inclusion. + (KERNEL_U_SIZE): Don't define. + (kernel_u_size): Remove prototype. + * config/sparc/tm-linux.h: Replace with new file. + * configure.tgt: Add sparc-*-linux*. + * configure.host: Add sparc-*-linux*. + * Makefile.in (ALLDEPFILES): Add sparc-linux-tdep.c and + sparc-nat.c. + (sparc-nat.o, sparc-linux-tdep.o): New dependencies. + 2003-10-18 Mark Kettenis <kettenis@gnu.org> Integrate SPARC and UltraSPARC targets. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ee1ff70f847..22eb5508ee2 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1293,8 +1293,8 @@ ALLDEPFILES = \ ser-go32.c ser-pipe.c ser-tcp.c \ sh-tdep.c sh64-tdep.c shnbsd-tdep.c shnbsd-nat.c \ solib.c solib-irix.c solib-svr4.c solib-sunos.c \ - sparc-tdep.c sparc-sol2-tdep.c \ - sparc-sol2-nat.c sparcbsd-nat.c \ + sparc-tdep.c sparc-linux-tdep.c sparc-sol2-tdep.c \ + sparc-nat.c sparc-sol2-nat.c sparcbsd-nat.c \ sparc64-tdep.c sparc64fbsd-tdep.c \ sparc64fbsd-nat.c \ sun3-nat.c \ @@ -2302,17 +2302,21 @@ source.o: source.c $(defs_h) $(symtab_h) $(expression_h) $(language_h) \ $(gdb_string_h) $(gdb_stat_h) $(gdbcore_h) $(gdb_regex_h) \ $(symfile_h) $(objfiles_h) $(annotate_h) $(gdbtypes_h) $(linespec_h) \ $(filenames_h) $(completer_h) $(ui_out_h) +sparc-nat.o: sparc-nat.c $(defs_h) $(inferior_h) $(regcache_h) $(gdb_wait_h) \ + $(sparc_tdep_h) sparc-tdep.o: sparc-tdep.c $(defs_h) $(arch_utils_h) $(dis_asm_h) $(frame_h) \ $(frame_base_h) $(frame_unwind_h) $(gdbcore_h) $(gdbtypes_h) \ $(inferior_h) $(symtab_h) $(objfiles_h) $(osabi_h) $(regcache_h) \ $(target_h) $(value_h) $(gdb_assert_h) $(gdb_string_h) \ $(sparc_tdep_h) +sparc-linux-tdep.o: sparc-linux-tdep.c $(defs_h) $(gdbarch_h) $(osabi_h) \ + $(sparc_tdep_h) +sparc-sol2-nat.o: sparc-sol2-nat.c $(defs_h) $(gregset_h) $(regcache_h) \ + $(sparc_tdep_h) sparc-sol2-tdep.o: sparc-sol2-tdep.c $(defs_h) $(frame_h) $(frame_base_h) \ $(frame_unwind_h) $(gdbcore_h) $(symtab_h) $(objfiles_h) $(osabi_h) \ $(regcache_h) $(target_h) $(trad_frame_h) $(gdb_assert_h) \ $(gdb_string_h) $(sparc_tdep_h) -sparc-sol2-nat.o: sparc-sol2-nat.c $(defs_h) $(gregset_h) $(regcache_h) \ - $(sparc_tdep_h) sparcbsd-nat.o: sparcbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ $(sparc64_tdep_h) $(sparcbsd_nat_h) sparc64-tdep.o: sparc64-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \ diff --git a/gdb/config/sparc/linux.mh b/gdb/config/sparc/linux.mh index f36dbb1ae34..ed68cc78aea 100644 --- a/gdb/config/sparc/linux.mh +++ b/gdb/config/sparc/linux.mh @@ -1,14 +1,11 @@ -# Host: Sparcstation, running GNU/Linux. - -XM_FILE= xm-linux.h - +# Host: GNU/Linux SPARC NAT_FILE= nm-linux.h -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o \ - proc-service.o thread-db.o lin-lwp.o sparc-linux-nat.o \ +NATDEPFILES= sparc-nat.o sparc-sol2-nat.o \ + corelow.o core-regset.o fork-child.o \ + infptrace.o inftarg.o \ + proc-service.o thread-db.o lin-lwp.o \ linux-proc.o gcore.o linux-nat.o # The dynamically loaded libthread_db needs access to symbols in the # gdb executable. LOADLIBES = -ldl -rdynamic - -HOST_IPC=-DBSD_IPC diff --git a/gdb/config/sparc/linux.mt b/gdb/config/sparc/linux.mt index d6cf773a8ee..e053f302c4f 100644 --- a/gdb/config/sparc/linux.mt +++ b/gdb/config/sparc/linux.mt @@ -1,3 +1,4 @@ -# Target: Sparcstation, running Linux -TDEPFILES= sparc-tdep.o solib.o solib-svr4.o solib-legacy.o +# Target: GNU/Linux SPARC +TDEPFILES= sparc-tdep.o sparc-sol2-tdep.o sparc-linux-tdep.o \ + solib.o solib-svr4.o solib-legacy.o TM_FILE= tm-linux.h diff --git a/gdb/config/sparc/nm-linux.h b/gdb/config/sparc/nm-linux.h index a156eba0707..68ff1f1c57e 100644 --- a/gdb/config/sparc/nm-linux.h +++ b/gdb/config/sparc/nm-linux.h @@ -1,7 +1,7 @@ -/* Macro definitions for running gdb on a Sparc running GNU/Linux. +/* Native-dependent definitions for GNU/Linux SPARC. - Copyright 1989, 1992, 1996, 1998, 1999, 2000, 2002 Free Software - Foundation, Inc. + Copyright 1989, 1992, 1996, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. This file is part of GDB. @@ -20,13 +20,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "config/nm-sysv4.h" +#ifndef NM_LINUX_H +#define NM_LINUX_H + #include "config/nm-linux.h" -#include "solib.h" #define FETCH_INFERIOR_REGISTERS -/* Return sizeof user struct to callers in less machine dependent routines */ - -#define KERNEL_U_SIZE kernel_u_size() -extern int kernel_u_size (void); +#endif /* nm-linux.h */ diff --git a/gdb/config/sparc/tm-linux.h b/gdb/config/sparc/tm-linux.h index 63be2b885a5..ae853ba0acb 100644 --- a/gdb/config/sparc/tm-linux.h +++ b/gdb/config/sparc/tm-linux.h @@ -1,7 +1,6 @@ -/* Macro definitions for GDB for a Sparc running GNU/Linux. +/* Target-dependent definitions for GNU/Linux SPARC. - Copyright 1989, 1992, 1994, 1995, 1998, 1999, 2002 Free Software - Foundation, Inc. + Copyright 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -17,16 +16,14 @@ 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. */ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef TM_SPARCLINUX_H -#define TM_SPARCLINUX_H +#ifndef TM_LINUX_H +#define TM_LINUX_H -#include "sparc/tm-sparc.h" +#define GDB_MULTI_ARCH GDB_MULTI_ARCH_TM -#define SIGCONTEXT_PC_OFFSET 12 +/* Shared library support. */ +#include "solib.h" -#include "config/tm-linux.h" - -#endif /* TM_SPARCLINUX_H */ +#endif /* tm-linux.h */ diff --git a/gdb/configure.host b/gdb/configure.host index 991643ad5f7..6622803f183 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -131,6 +131,7 @@ s390*-*-*) gdb_host=s390 ;; sh*-*-netbsdelf*) gdb_host=nbsd ;; sparc-*-solaris2*) gdb_host=sol2 ;; +sparc-*-linux*) gdb_host=linux ;; sparc64-*-freebsd*) gdb_host=fbsd ;; vax-*-bsd*) gdb_host=vaxbsd ;; diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 28f4be9a485..b36ecc69678 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -203,6 +203,7 @@ sh-*-nto*) gdb_target=nto ;; sh*) gdb_target=embed ;; sparc-*-solaris2*) gdb_target=sol2 ;; +sparc-*-linux*) gdb_target=linux ;; sparc-*-*) gdb_target=sparc ;; xstormy16-*-*) gdb_target=xstormy16 ;; diff --git a/gdb/sparc-linux-nat.c b/gdb/sparc-linux-nat.c deleted file mode 100644 index f43cb593b20..00000000000 --- a/gdb/sparc-linux-nat.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Native-dependent code for GNU/Linux SPARC. - - Copyright 2001, 2002, 2003 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. */ - -#include "defs.h" -#include "regcache.h" -#include "sparc-tdep.h" - -#include <sys/procfs.h> - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -void -supply_gregset (elf_gregset_t *gregsetp) -{ - elf_greg_t *regp = (elf_greg_t *) gregsetp; - int i; - - for (i = G0_REGNUM; i <= I7_REGNUM; i++) - supply_register (i, (char *) (regp + (i - G0_REGNUM))); - - supply_register (PS_REGNUM, (char *) (regp + 32)); - - supply_register (PC_REGNUM, (char *) (regp + 33)); - supply_register (DEPRECATED_NPC_REGNUM, (char *) (regp + 34)); - supply_register (Y_REGNUM, (char *) (regp + 35)); - - supply_register (WIM_REGNUM, (char *) (regp + 36)); - supply_register (TBR_REGNUM, (char *) (regp + 37)); - - /* Fill inaccessible registers with zero. */ - supply_register (CPS_REGNUM, NULL); -} - -void -fill_gregset (elf_gregset_t *gregsetp, int regno) -{ - elf_greg_t *regp = (elf_greg_t *) gregsetp; - int i; - - for (i = G0_REGNUM; i <= I7_REGNUM; i++) - if (regno == -1 || regno == i) - regcache_collect (i, regp + (i - G0_REGNUM)); - - if (regno == -1 || regno == PS_REGNUM) - regcache_collect (PS_REGNUM, regp + 32); - - if (regno == -1 || regno == PC_REGNUM) - regcache_collect (PC_REGNUM, regp + 33); - if (regno == -1 || regno == DEPRECATED_NPC_REGNUM) - regcache_collect (DEPRECATED_NPC_REGNUM, regp + 34); - if (regno == -1 || regno == Y_REGNUM) - regcache_collect (Y_REGNUM, regp + 35); - - if (regno == -1 || regno == WIM_REGNUM) - regcache_collect (WIM_REGNUM, regp + 36); - if (regno == -1 || regno == TBR_REGNUM) - regcache_collect (TBR_REGNUM, regp + 37); -} - -void -supply_fpregset (elf_fpregset_t *fpregsetp) -{ - int i; - - for (i = FP0_REGNUM; i < FP0_REGNUM + 32; i++) - supply_register (i, (char *) &fpregsetp->pr_fr.pr_regs[i - FP0_REGNUM]); - - supply_register (FPS_REGNUM, (char *) &fpregsetp->pr_fsr); -} - -void -fill_fpregset (elf_fpregset_t *fpregsetp, int regno) -{ - int i; - - for (i = FP0_REGNUM; i < FP0_REGNUM + 32; i++) - if (regno == -1 || regno == i) - regcache_collect (i, &fpregsetp->pr_fr.pr_regs[i - FP0_REGNUM]); - - if (regno == -1 || regno == FPS_REGNUM) - regcache_collect (FPS_REGNUM, &fpregsetp->pr_fsr); -} diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c new file mode 100644 index 00000000000..3ba72f68908 --- /dev/null +++ b/gdb/sparc-linux-tdep.c @@ -0,0 +1,46 @@ +/* Target-dependent code for GNU/Linux SPARC. + + Copyright 2003 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. */ + +#include "defs.h" +#include "gdbarch.h" +#include "osabi.h" + +#include "sparc-tdep.h" + +static void +sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* GNU/Linux is very similar to Solaris ... */ + sparc32_sol2_init_abi (info, gdbarch); + + /* ... but doesn't have kernel-assisted single-stepping support. */ + set_gdbarch_software_single_step (gdbarch, sparc_software_single_step); +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern void _initialize_sparc_linux_tdep (void); + +void +_initialize_sparc_linux_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_LINUX, + sparc32_linux_init_abi); +} diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c index a4df86507b7..bbf2b4e5b07 100644 --- a/gdb/sparc-nat.c +++ b/gdb/sparc-nat.c @@ -1,7 +1,6 @@ -/* Functions specific to running gdb native on a SPARC running SunOS4. +/* Native-dependent code for SPARC. - Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -22,363 +21,176 @@ #include "defs.h" #include "inferior.h" -#include "target.h" -#include "gdbcore.h" #include "regcache.h" -#include "sparc-tdep.h" +/* We need a data structure for use with ptrace(2). SunOS 4 has + `struct regs' and `struct fp_status' in <machine/reg.h>. BSD's + have `struct reg' and `struct fpreg' in <machine/reg.h>. GNU/Linux + has the same structures as SunOS 4, but they're in <asm/reg.h>, + which is a kernel header. As a general rule we avoid including + GNU/Linux kernel headers. Fortunately GNU/Linux has a `gregset_t' + and a `fpregset_t' that are equivalent to `struct regs' and `struct + fp_status' in <sys/ucontext.h>, which is automatically included by + <signal.h>. Settling on using the `gregset_t' and `fpregset_t' + typedefs, providing them for the other systems, therefore solves + the puzzle. */ -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif #include <signal.h> #include <sys/ptrace.h> #include "gdb_wait.h" -#ifdef __linux__ -#include <asm/reg.h> -#else +#ifdef HAVE_MACHINE_REG_H #include <machine/reg.h> +#ifdef HAVE_STRUCT_REG +typedef struct reg gregset_t; +typedef struct fpreg fpregset_t; +#else +typedef struct regs gregset_t; +typedef struct fp_status fpregset_t; +#endif #endif -#include <sys/user.h> -/* We don't store all registers immediately when requested, since they - get sent over in large chunks anyway. Instead, we accumulate most - of the changes and send them over once. "deferred_stores" keeps - track of which sets of registers we have locally-changed copies of, - so we only need send the groups that have changed. */ +#include "sparc-tdep.h" -#define INT_REGS 1 -#define STACK_REGS 2 -#define FP_REGS 4 +/* Register set description. */ +const struct sparc_gregset *sparc_gregset; -/* Fetch one or more registers from the inferior. REGNO == -1 to get - them all. We actually fetch more than requested, when convenient, - marking them as valid so we won't fetch them again. */ +/* Determine whether `gregset_t' contains register REGNUM. */ -void -fetch_inferior_registers (int regno) +int +sparc_gregset_supplies_p (int regnum) { - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int i; - int fetch_pid; - - /* NOTE: cagney/2002-12-03: This code assumes that the currently - selected light weight processes' registers can be written - directly into the selected thread's register cache. This works - fine when given an 1:1 LWP:thread model (such as found on - GNU/Linux) but will, likely, have problems when used on an N:1 - (userland threads) or N:M (userland multiple LWP) model. In the - case of the latter two, the LWP's registers do not necessarily - belong to the selected thread (the LWP could be in the middle of - executing the thread switch code). - - These functions should instead be paramaterized with an explicit - object (struct regcache, struct thread_info?) into which the LWPs - registers can be written. */ - - fetch_pid = TIDGET (inferior_ptid); - if (fetch_pid == 0) - fetch_pid = PIDGET (inferior_ptid); - - /* We should never be called with deferred stores, because a prerequisite - for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */ - if (deferred_stores) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - DO_DEFERRED_STORES; - - /* Global and Out regs are fetched directly, as well as the control - registers. If we're getting one of the in or local regs, - and the stack pointer has not yet been fetched, - we have to do that first, since they're found in memory relative - to the stack pointer. */ - if (regno < O7_REGNUM /* including -1 */ - || regno >= Y_REGNUM - || (!deprecated_register_valid[SP_REGNUM] && regno < I7_REGNUM)) - { - if (0 != ptrace (PTRACE_GETREGS, fetch_pid, - (PTRACE_ARG3_TYPE) & inferior_registers, 0)) - perror ("ptrace_getregs"); - - deprecated_registers[DEPRECATED_REGISTER_BYTE (0)] = 0; - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (1)], - &inferior_registers.r_g1, 15 * REGISTER_RAW_SIZE (G0_REGNUM)); - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] - = inferior_registers.r_ps; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] - = inferior_registers.r_pc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (DEPRECATED_NPC_REGNUM)] - = inferior_registers.r_npc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; - - for (i = G0_REGNUM; i <= O7_REGNUM; i++) - deprecated_register_valid[i] = 1; - deprecated_register_valid[Y_REGNUM] = 1; - deprecated_register_valid[PS_REGNUM] = 1; - deprecated_register_valid[PC_REGNUM] = 1; - deprecated_register_valid[DEPRECATED_NPC_REGNUM] = 1; - /* If we don't set these valid, read_register_bytes() rereads - all the regs every time it is called! FIXME. */ - deprecated_register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */ - deprecated_register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */ - deprecated_register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */ - } + /* Integer registers. */ + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM) + || (regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_L7_REGNUM) + || (regnum >= SPARC_I0_REGNUM && regnum <= SPARC_I7_REGNUM)) + return 1; + + /* Control registers. */ + if (regnum == SPARC32_PC_REGNUM + || regnum == SPARC32_NPC_REGNUM + || regnum == SPARC32_PSR_REGNUM + || regnum == SPARC32_Y_REGNUM) + return 1; + + return 0; +} - /* Floating point registers */ - if (regno == -1 || - regno == FPS_REGNUM || - (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)) - { - if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid, - (PTRACE_ARG3_TYPE) & inferior_fp_registers, - 0)) - perror ("ptrace_getfpregs"); - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], - &inferior_fp_registers, sizeof inferior_fp_registers.fpu_fr); - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPS_REGNUM)], - &inferior_fp_registers.Fpu_fsr, sizeof (FPU_FSR_TYPE)); - for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) - deprecated_register_valid[i] = 1; - deprecated_register_valid[FPS_REGNUM] = 1; - } +/* Determine whether `fpregset_t' contains register REGNUM. */ - /* These regs are saved on the stack by the kernel. Only read them - all (16 ptrace calls!) if we really need them. */ - if (regno == -1) - { - CORE_ADDR sp = *(unsigned int *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; - target_read_memory (sp, &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM)); - for (i = L0_REGNUM; i <= I7_REGNUM; i++) - deprecated_register_valid[i] = 1; - } - else if (regno >= L0_REGNUM && regno <= I7_REGNUM) - { - CORE_ADDR sp = *(unsigned int *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; - i = DEPRECATED_REGISTER_BYTE (regno); - if (deprecated_register_valid[regno]) - printf_unfiltered ("register %d valid and read\n", regno); - target_read_memory (sp + i - DEPRECATED_REGISTER_BYTE (L0_REGNUM), - &deprecated_registers[i], REGISTER_RAW_SIZE (regno)); - deprecated_register_valid[regno] = 1; - } +static int +sparc_fpregset_supplies_p (int regnum) +{ + /* Floating-point registers. */ + if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) + return 1; + + /* Control registers. */ + if (regnum == SPARC32_FSR_REGNUM) + return 1; + + return 0; } -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ void -store_inferior_registers (int regno) +fetch_inferior_registers (int regnum) { - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - int wanna_store = INT_REGS + STACK_REGS + FP_REGS; - int store_pid; - - /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers - about threaded assumptions. */ - store_pid = TIDGET (inferior_ptid); - if (store_pid == 0) - store_pid = PIDGET (inferior_ptid); - - /* First decide which pieces of machine-state we need to modify. - Default for regno == -1 case is all pieces. */ - if (regno >= 0) - { - if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32) - { - wanna_store = FP_REGS; - } - else - { - if (regno == SP_REGNUM) - wanna_store = INT_REGS + STACK_REGS; - else if (regno < L0_REGNUM || regno > I7_REGNUM) - wanna_store = INT_REGS; - else if (regno == FPS_REGNUM) - wanna_store = FP_REGS; - else - wanna_store = STACK_REGS; - } - } + struct regcache *regcache = current_regcache; - /* See if we're forcing the stores to happen now, or deferring. */ - if (regno == -2) + if (regnum == SPARC_G0_REGNUM) { - wanna_store = deferred_stores; - deferred_stores = 0; - } - else - { - if (wanna_store == STACK_REGS) - { - /* Fall through and just store one stack reg. If we deferred - it, we'd have to store them all, or remember more info. */ - } - else - { - deferred_stores |= wanna_store; - return; - } + regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL); + return; } - if (wanna_store & STACK_REGS) + if (regnum == -1 || sparc_gregset_supplies_p (regnum)) { - CORE_ADDR sp = *(unsigned int *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; + gregset_t regs; - if (regno < 0 || regno == SP_REGNUM) - { - if (!deprecated_register_valid[L0_REGNUM + 5]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM)); - } - else - { - if (!deprecated_register_valid[regno]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - target_write_memory (sp + DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (L0_REGNUM), - &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); - } + if (ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); + sparc_supply_gregset (sparc_gregset, regcache, -1, ®s); + if (regnum != -1) + return; } - if (wanna_store & INT_REGS) + if (regnum == -1 || sparc_fpregset_supplies_p (regnum)) { - if (!deprecated_register_valid[G1_REGNUM]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - - memcpy (&inferior_registers.r_g1, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - - inferior_registers.r_ps = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)]; - inferior_registers.r_pc = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)]; - inferior_registers.r_npc = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (DEPRECATED_NPC_REGNUM)]; - inferior_registers.r_y = - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (Y_REGNUM)]; - - if (0 != ptrace (PTRACE_SETREGS, store_pid, - (PTRACE_ARG3_TYPE) & inferior_registers, 0)) - perror ("ptrace_setregs"); - } + fpregset_t fpregs; - if (wanna_store & FP_REGS) - { - if (!deprecated_register_valid[FP0_REGNUM + 9]) - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - memcpy (&inferior_fp_registers, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], - sizeof inferior_fp_registers.fpu_fr); - memcpy (&inferior_fp_registers.Fpu_fsr, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (FPS_REGNUM)], - sizeof (FPU_FSR_TYPE)); - if (0 != - ptrace (PTRACE_SETFPREGS, store_pid, - (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) - perror ("ptrace_setfpregs"); + if (ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating point status"); + + sparc_supply_fpregset (regcache, -1, &fpregs); } } -/* Provide registers to GDB from a core file. +void +store_inferior_registers (int regnum) +{ + struct regcache *regcache = current_regcache; - CORE_REG_SECT points to an array of bytes, which are the contents - of a `note' from a core file which BFD thinks might contain - register contents. CORE_REG_SIZE is its size. + if (regnum == -1 || sparc_gregset_supplies_p (regnum)) + { + gregset_t regs; - WHICH says which register set corelow suspects this is: - 0 --- the general-purpose register set - 2 --- the floating-point register set + if (ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't get registers"); - IGNORE is unused. */ + sparc_collect_gregset (sparc_gregset, regcache, regnum, ®s); -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR ignore) -{ + if (ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) ®s, 0) == -1) + perror_with_name ("Couldn't write registers"); - if (which == 0) - { + /* Deal with the stack regs. */ + if (regnum == -1 || regnum == SPARC_SP_REGNUM + || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)) + { + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_collect_rwindow (regcache, sp, regnum); + } - /* Integer registers */ - -#define gregs ((struct regs *)core_reg_sect) - /* G0 *always* holds 0. */ - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (0)] = 0; - - /* The globals and output registers. */ - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, - 15 * REGISTER_RAW_SIZE (G1_REGNUM)); - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (DEPRECATED_NPC_REGNUM)] = gregs->r_npc; - *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; - - /* My best guess at where to get the locals and input - registers is exactly where they usually are, right above - the stack pointer. If the core dump was caused by a bus error - from blowing away the stack pointer (as is possible) then this - won't work, but it's worth the try. */ - { - int sp; - - sp = *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (SP_REGNUM)]; - if (0 != target_read_memory (sp, - &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)], - 16 * REGISTER_RAW_SIZE (L0_REGNUM))) - { - /* fprintf_unfiltered so user can still use gdb */ - fprintf_unfiltered (gdb_stderr, - "Couldn't read input and local registers from core file\n"); - } - } + if (regnum != -1) + return; } - else if (which == 2) + + if (regnum == -1 || sparc_fpregset_supplies_p (regnum)) { + fpregset_t fpregs; - /* Floating point registers */ + if (ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't get floating-point registers"); -#define fpuregs ((struct fpu *) core_reg_sect) - if (core_reg_size >= sizeof (struct fpu)) - { - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], - fpuregs->fpu_regs, sizeof (fpuregs->fpu_regs)); - memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FPS_REGNUM)], - &fpuregs->fpu_fsr, sizeof (FPU_FSR_TYPE)); - } - else - fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n"); - } -} + sparc_collect_fpregset (regcache, regnum, &fpregs); -int -kernel_u_size (void) -{ - return (sizeof (struct user)); + if (ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_ARG3_TYPE) &fpregs, 0) == -1) + perror_with_name ("Couldn't write floating-point registers"); + + if (regnum != -1) + return; + } } -/* Register that we are able to handle sparc core file formats. - FIXME: is this really bfd_target_unknown_flavour? */ - -static struct core_fns sparc_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_sparc_nat (void); void -_initialize_core_sparc (void) +_initialize_sparc_nat (void) { - add_core_fns (&sparc_core_fns); + /* Deafult to using SunOS 4 register sets. */ + if (sparc_gregset == NULL) + sparc_gregset = &sparc32_sunos4_gregset; } diff --git a/gdb/sparc-sol2-nat.c b/gdb/sparc-sol2-nat.c index aa14aa4c0dc..5b3113a372c 100644 --- a/gdb/sparc-sol2-nat.c +++ b/gdb/sparc-sol2-nat.c @@ -34,23 +34,24 @@ void supply_gregset (prgregset_t *gregs) { - sparc_sol2_supply_gregset (current_regcache, -1, gregs); + sparc_supply_gregset (&sparc32_sol2_gregset, current_regcache, -1, gregs); } void supply_fpregset (prfpregset_t *fpregs) { - sparc_sol2_supply_fpregset (current_regcache, -1, fpregs); + sparc_supply_fpregset (current_regcache, -1, fpregs); } void fill_gregset (prgregset_t *gregs, int regnum) { - sparc_sol2_collect_gregset (current_regcache, regnum, gregs); + sparc_collect_gregset (&sparc32_sol2_gregset, + current_regcache, regnum, gregs); } void fill_fpregset (prfpregset_t *fpregs, int regnum) { - sparc_sol2_collect_fpregset (current_regcache, regnum, fpregs); + sparc_collect_fpregset (current_regcache, regnum, fpregs); } diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c index abd40c8ce37..49b3c3e7f81 100644 --- a/gdb/sparc-sol2-tdep.c +++ b/gdb/sparc-sol2-tdep.c @@ -37,116 +37,19 @@ #include "sparc-tdep.h" /* From <sys/regset.h>. */ -const int sparc_sol2_R_PSR = 32; -const int sparc_sol2_R_PC = 33; -const int sparc_sol2_R_nPC = 34; -const int sparc_sol2_R_Y = 35; -const int sparc_sol2_R_WIM = 36; -const int sparc_sol2_R_TBR = 37; - -void -sparc_sol2_supply_gregset (struct regcache *regcache, - int regnum, const void *gregs) -{ - const char *regs = gregs; - int i; - - if (regnum == SPARC32_PSR_REGNUM || regnum == -1) - regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, - regs + sparc_sol2_R_PSR * 4); - - if (regnum == SPARC32_PC_REGNUM || regnum == -1) - regcache_raw_supply (regcache, SPARC32_PC_REGNUM, - regs + sparc_sol2_R_PC * 4); - - if (regnum == SPARC32_NPC_REGNUM || regnum == -1) - regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, - regs + sparc_sol2_R_nPC * 4); - - if (regnum == SPARC32_Y_REGNUM || regnum == -1) - regcache_raw_supply (regcache, SPARC32_Y_REGNUM, - regs + sparc_sol2_R_Y * 4); - - if ((regnum >= SPARC_G0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) - { - for (i = SPARC_G0_REGNUM; i <= SPARC_I7_REGNUM; i++) - { - if (regnum == i || regnum == -1) - regcache_raw_supply (regcache, i, - (regs + (i - SPARC_G0_REGNUM) * 4)); - } - } -} - -void -sparc_sol2_collect_gregset (const struct regcache *regcache, - int regnum, void *gregs) +const struct sparc_gregset sparc32_sol2_gregset = { - char *regs = gregs; - int i; - - if (regnum == SPARC32_PSR_REGNUM || regnum == -1) - regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, - regs + sparc_sol2_R_PSR * 4); - - if (regnum == SPARC32_PC_REGNUM || regnum == -1) - regcache_raw_collect (regcache, SPARC32_PC_REGNUM, - regs + sparc_sol2_R_PC * 4); - - if (regnum == SPARC32_NPC_REGNUM || regnum == -1) - regcache_raw_collect (regcache, SPARC32_NPC_REGNUM, - regs + sparc_sol2_R_nPC * 4); - - if (regnum == SPARC32_Y_REGNUM || regnum == -1) - regcache_raw_collect (regcache, SPARC32_Y_REGNUM, - regs + sparc_sol2_R_Y * 4); - - if ((regnum >= SPARC_G0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) - { - /* %g0 is always zero. */ - for (i = SPARC_G1_REGNUM; i <= SPARC_I7_REGNUM; i++) - { - if (regnum == i || regnum == -1) - regcache_raw_collect (regcache, i, - (regs + (i - SPARC_G0_REGNUM) * 4)); - } - } -} - -void -sparc_sol2_supply_fpregset (struct regcache *regcache, - int regnum, const void *fpregs) -{ - const char *regs = fpregs; - int i; - - for (i = 0; i < 32; i++) - { - if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) - regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); - } - - if (regnum == SPARC32_FSR_REGNUM || regnum == -1) - regcache_raw_supply (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4); -} - -void -sparc_sol2_collect_fpregset (const struct regcache *regcache, - int regnum, void *fpregs) -{ - char *regs = fpregs; - int i; - - for (i = 0; i < 32; i++) - { - if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) - regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); - } - - if (regnum == SPARC32_FSR_REGNUM || regnum == -1) - regcache_raw_collect (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4); -} + 32 * 4, /* %psr */ + 33 * 4, /* %pc */ + 34 * 4, /* %npc */ + 35 * 4, /* %y */ + 36 * 4, /* %wim */ + 37 * 4, /* %tbr */ + 1 * 4, /* %g1 */ + 16 * 4, /* %l0 */ +}; + static int sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) { @@ -154,8 +57,8 @@ sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) } static struct sparc32_frame_cache * -sparc_sol2_sigtramp_frame_cache (struct frame_info *next_frame, - void **this_cache) +sparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame, + void **this_cache) { struct sparc32_frame_cache *cache; CORE_ADDR mcontext_addr, addr; @@ -199,53 +102,54 @@ sparc_sol2_sigtramp_frame_cache (struct frame_info *next_frame, } static void -sparc_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, - void **this_cache, struct frame_id *this_id) +sparc32_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) { struct sparc32_frame_cache *cache = - sparc_sol2_sigtramp_frame_cache (next_frame, this_cache); + sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache); (*this_id) = frame_id_build (cache->base, cache->pc); } static void -sparc_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, - void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, - CORE_ADDR *addrp, - int *realnump, void *valuep) +sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, + void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep) { struct sparc32_frame_cache *cache = - sparc_sol2_sigtramp_frame_cache (next_frame, this_cache); + sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache); trad_frame_prev_register (next_frame, cache->saved_regs, regnum, optimizedp, lvalp, addrp, realnump, valuep); } -static const struct frame_unwind sparc_sol2_sigtramp_frame_unwind = +static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind = { SIGTRAMP_FRAME, - sparc_sol2_sigtramp_frame_this_id, - sparc_sol2_sigtramp_frame_prev_register + sparc32_sol2_sigtramp_frame_this_id, + sparc32_sol2_sigtramp_frame_prev_register }; static const struct frame_unwind * -sparc_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) +sparc32_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) { CORE_ADDR pc = frame_pc_unwind (next_frame); char *name; find_pc_partial_function (pc, &name, NULL, NULL); if (sparc_sol2_pc_in_sigtramp (pc, name)) - return &sparc_sol2_sigtramp_frame_unwind; + return &sparc32_sol2_sigtramp_frame_unwind; return NULL; } void -sparc_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -260,7 +164,7 @@ sparc_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Solaris has kernel-assisted single-stepping support. */ set_gdbarch_software_single_step (gdbarch, NULL); - frame_unwind_append_sniffer (gdbarch, sparc_sol2_sigtramp_frame_sniffer); + frame_unwind_append_sniffer (gdbarch, sparc32_sol2_sigtramp_frame_sniffer); } @@ -271,5 +175,5 @@ void _initialize_sparc_sol2_tdep (void) { gdbarch_register_osabi (bfd_arch_sparc, 0, - GDB_OSABI_SOLARIS, sparc_sol2_init_abi); + GDB_OSABI_SOLARIS, sparc32_sol2_init_abi); } diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 291217af439..ecefb8fb295 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1076,6 +1076,179 @@ sparc_collect_rwindow (const struct regcache *regcache, } } } + +/* Helper functions for dealing with register sets. */ + +/* FIXME: kettenis/20031125: Make these handle 64-bit register sets. */ + +void +sparc_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs) +{ + const char *regs = gregs; + int i; + + if (regnum == SPARC32_PSR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, + regs + gregset->r_psr_offset); + + if (regnum == SPARC32_PC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_PC_REGNUM, + regs + gregset->r_pc_offset); + + if (regnum == SPARC32_NPC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, + regs + gregset->r_npc_offset); + + if (regnum == SPARC32_Y_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_Y_REGNUM, + regs + gregset->r_y_offset); + + if (regnum == SPARC_G0_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL); + + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) + { + int offset = gregset->r_g1_offset; + + for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + offset); + offset += 4; + } + } + + if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) + { + /* Not all of the register set variants include Locals and + Inputs. For those that don't, we read them off the stack. */ + if (gregset->r_l0_offset == -1) + { + ULONGEST sp; + + regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + sparc_supply_rwindow (regcache, sp, regnum); + } + else + { + int offset = gregset->r_l0_offset; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + offset); + offset += 4; + } + } + } +} + +void +sparc_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs) +{ + char *regs = gregs; + int i; + + if (regnum == SPARC32_PSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, + regs + gregset->r_psr_offset); + + if (regnum == SPARC32_PC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_PC_REGNUM, + regs + gregset->r_pc_offset); + + if (regnum == SPARC32_NPC_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_NPC_REGNUM, + regs + gregset->r_npc_offset); + + if (regnum == SPARC32_Y_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_Y_REGNUM, + regs + gregset->r_y_offset); + + if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) + { + int offset = gregset->r_g1_offset; + + /* %g0 is always zero. */ + for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_collect (regcache, i, regs + offset); + offset += 4; + } + } + + if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) + { + /* Not all of the register set variants include Locals and + Inputs. For those that don't, we read them off the stack. */ + if (gregset->r_l0_offset != -1) + { + int offset = gregset->r_l0_offset; + + for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_collect (regcache, i, regs + offset); + offset += 4; + } + } + } +} + +void +sparc_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs) +{ + const char *regs = fpregs; + int i; + + for (i = 0; i < 32; i++) + { + if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) + regcache_raw_supply (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); + } + + if (regnum == SPARC32_FSR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4); +} + +void +sparc_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs) +{ + char *regs = fpregs; + int i; + + for (i = 0; i < 32; i++) + { + if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) + regcache_raw_collect (regcache, SPARC_F0_REGNUM + i, regs + (i * 4)); + } + + if (regnum == SPARC32_FSR_REGNUM || regnum == -1) + regcache_raw_collect (regcache, SPARC32_FSR_REGNUM, regs + (32 * 4) + 4); +} + + +/* SunOS 4. */ + +/* From <machine/reg.h>. */ +const struct sparc_gregset sparc32_sunos4_gregset = +{ + 0 * 4, /* %psr */ + 1 * 4, /* %pc */ + 2 * 4, /* %npc */ + 3 * 4, /* %y */ + -1, /* %wim */ + -1, /* %tbr */ + 4 * 4, /* %g1 */ + -1 /* %l0 */ +}; /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/sparc-tdep.h b/gdb/sparc-tdep.h index c82099ff167..bf081a01cc5 100644 --- a/gdb/sparc-tdep.h +++ b/gdb/sparc-tdep.h @@ -26,6 +26,20 @@ struct gdbarch; struct regcache; struct trad_frame_saved_reg; +/* Register offsets for the general-purpose register set. */ + +struct sparc_gregset +{ + int r_psr_offset; + int r_pc_offset; + int r_npc_offset; + int r_y_offset; + int r_wim_offset; + int r_tbr_offset; + int r_g1_offset; + int r_l0_offset; +}; + /* SPARC architecture-specific information. */ struct gdbarch_tdep @@ -129,18 +143,26 @@ extern void sparc_supply_rwindow (struct regcache *regcache, extern void sparc_collect_rwindow (const struct regcache *regcache, CORE_ADDR sp, int regnum); -/* Functions exported from sparc-sol2-tdep.c. */ +/* Register offsets for SunOS 4. */ +extern const struct sparc_gregset sparc32_sunos4_gregset; + +extern void sparc_supply_gregset (const struct sparc_gregset *gregset, + struct regcache *regcache, + int regnum, const void *gregs); +extern void sparc_collect_gregset (const struct sparc_gregset *gregset, + const struct regcache *regcache, + int regnum, void *gregs); +extern void sparc_supply_fpregset (struct regcache *regcache, + int regnum, const void *fpregs); +extern void sparc_collect_fpregset (const struct regcache *regcache, + int regnum, void *fpregs); + +/* Functions and variables exported from sparc-sol2-tdep.c. */ -extern void sparc_sol2_supply_gregset (struct regcache *regcache, - int regnum, const void *gregs); -extern void sparc_sol2_collect_gregset (const struct regcache *regcache, - int regnum, void *gregs); -extern void sparc_sol2_supply_fpregset (struct regcache *regcache, - int regnum, const void *fpregs); -extern void sparc_sol2_collect_fpregset (const struct regcache *regcache, - int regnum, void *regs); +/* Register offsets for Solaris 2. */ +extern const struct sparc_gregset sparc32_sol2_gregset; -extern void sparc_sol2_init_abi (struct gdbarch_info info, +extern void sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); #endif /* sparc-tdep.h */ |