summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2003-10-25 18:42:28 +0000
committerMark Kettenis <kettenis@gnu.org>2003-10-25 18:42:28 +0000
commit07231f3828c051ad8214c1792e996673ff62d162 (patch)
tree642db204b0001da90b0c709b03abd35cea2e6fd1
parenta97c84fff5822b4849a1f381e0a66a6ad2084e02 (diff)
downloadgdb-07231f3828c051ad8214c1792e996673ff62d162.tar.gz
* 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.
-rw-r--r--gdb/ChangeLog52
-rw-r--r--gdb/Makefile.in12
-rw-r--r--gdb/config/sparc/linux.mh13
-rw-r--r--gdb/config/sparc/linux.mt5
-rw-r--r--gdb/config/sparc/nm-linux.h16
-rw-r--r--gdb/config/sparc/tm-linux.h21
-rw-r--r--gdb/configure.host1
-rw-r--r--gdb/configure.tgt1
-rw-r--r--gdb/sparc-linux-nat.c101
-rw-r--r--gdb/sparc-linux-tdep.c46
-rw-r--r--gdb/sparc-nat.c434
-rw-r--r--gdb/sparc-sol2-nat.c9
-rw-r--r--gdb/sparc-sol2-tdep.c160
-rw-r--r--gdb/sparc-tdep.c173
-rw-r--r--gdb/sparc-tdep.h42
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) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+ sparc_supply_gregset (sparc_gregset, regcache, -1, &regs);
+ 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) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
- IGNORE is unused. */
+ sparc_collect_gregset (sparc_gregset, regcache, regnum, &regs);
-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) &regs, 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 */