This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/SPARC] Add GNU/Linux UltraSPARC


Committed to the SPARC-branch.

Mark

Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>
 
	* sparc64-tdep.h (r_tstate_offset): New define.
	(sparc64_supply_gregset, sparc64_collect_gregset,
	sparc64_supply_fpregset, sparc64_collect_fpregset): New
	prototypes.
	(sparc64_sol2_gregset): New extern declaration.
	(sparc64_sol2_init_abi): New prototype.
	* sparc64-tdep.c: Include "symtab.h" and "objfiles.h".  Don't
	include "sparc-tdep.h".
	(X_RD, X_I): New macros.
	(sparc64_analyze_prologue): Sync with implementation in
	sparc-tdep.c.
	(TSTATE_CWP, TSTATE_ICC, TSTATE_XCC): New macros.
	(PSR_S, PSR_ICC, PSR_VERS, PSR_IMPL, PSR_V8PLUS, PSR_XCC): New
	macros.
	(sparc64_supply_gregset, sparc64_collect_gregset,
	sparc64_supply_fpregset, sparc64_collect_fpregset): New functions.
	* sparc64-nat.c: New file.
	* sparc64-sol2-nat.c: New file.
	* sparc64-sol2-tdep.c: New file.
	* sparc64-linux-nat.c: New file.
	* sparc64-linux-tdep.c: New file.
	* Makefile.in (sparc_tdep_h): New variable.
	(ALLDEPFILES): Add sparc64-sol2-tdep.c, sparc64-linux-tdep.c,
	sparc64-nat.c sparc64-sol2-nat.c and sparc64-linux-nat.c
	(sparc-nat.o, sparc-linux-tdep.o, sparc64-tdep.o): Update
	dependencies.
	(sparc64-nat.o, sparc64-linux-nat.o, sparc64-linux-tdep.o,
	sparc64-sol2-nat.o, sparc64-sol2-tdep.o): New dependencies.
	* configure.tgt: Add sparc64-*-linux*.
	* configure.host: Add sparc64-*-linux*.
	* config/sparc/linux64.mt: New file.
	* config/sparc/linux64.mh: New file.

Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.116.4.2
diff -u -p -r1.116.4.2 configure.tgt
--- configure.tgt 25 Oct 2003 18:42:28 -0000 1.116.4.2
+++ configure.tgt 2 Nov 2003 20:22:32 -0000
@@ -205,6 +205,7 @@ sh*)			gdb_target=embed ;;
 sparc-*-solaris2*)	gdb_target=sol2 ;;
 sparc-*-linux*)		gdb_target=linux ;;
 sparc-*-*)		gdb_target=sparc ;;
+sparc64-*-linux*)	gdb_target=linux64 ;;
 
 xstormy16-*-*)          gdb_target=xstormy16 ;;
 
Index: configure.host
===================================================================
RCS file: /cvs/src/src/gdb/configure.host,v
retrieving revision 1.57.4.2
diff -u -p -r1.57.4.2 configure.host
--- configure.host 25 Oct 2003 18:42:28 -0000 1.57.4.2
+++ configure.host 2 Nov 2003 20:22:33 -0000
@@ -133,6 +133,7 @@ sh*-*-netbsdelf*)	gdb_host=nbsd ;;
 sparc-*-solaris2*)	gdb_host=sol2 ;;
 sparc-*-linux*)		gdb_host=linux ;;
 sparc64-*-freebsd*)	gdb_host=fbsd ;;
+sparc64-*-linux*)	gdb_host=linux64 ;;
 
 vax-*-bsd*)		gdb_host=vaxbsd ;;
 vax-*-ultrix2*)		gdb_host=vaxult2 ;;
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.445.2.4
diff -u -p -r1.445.2.4 Makefile.in
--- Makefile.in 25 Oct 2003 18:42:28 -0000 1.445.2.4
+++ Makefile.in 2 Nov 2003 20:22:35 -0000
@@ -748,6 +748,7 @@ somsolib_h = somsolib.h
 source_h = source.h
 sparc_tdep_h = sparc-tdep.h
 sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h)
+sparc_nat_h = sparc-nat.h
 srec_h = srec.h
 stabsread_h = stabsread.h
 stack_h = stack.h
@@ -1295,7 +1296,9 @@ ALLDEPFILES = \
 	solib.c solib-irix.c solib-svr4.c solib-sunos.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 \
+	sparc64-tdep.c sparc64-sol2-tdep.c sparc64-linux-tdep.c \
+	sparc64fbsd-tdep.c \
+	sparc64-nat.c sparc64-sol2-nat.c sparc64-linux-nat.c \
 	sparc64fbsd-nat.c \
 	sun3-nat.c \
 	symm-tdep.c symm-nat.c \
@@ -2302,15 +2305,15 @@ source.o: source.c $(defs_h) $(symtab_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-nat.o: sparc-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
+	$(gdb_string_h) $(gdb_wait_h) $(sparc_tdep_h) $(sparc_nat_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)
+	$(solib_svr4_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) \
@@ -2319,11 +2322,21 @@ sparc-sol2-tdep.o: sparc-sol2-tdep.c $(d
 	$(gdb_string_h) $(sparc_tdep_h)
 sparcbsd-nat.o: sparcbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
 	$(sparc64_tdep_h) $(sparcbsd_nat_h)
+sparc64-nat.o: sparc-nat.c $(defs_h) $(gdbarch_h) \
+	$(sparc64_tdep_h) $(sparc_nat_h)
 sparc64-tdep.o: sparc64-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \
 	$(frame_h) $(frame_base_h) $(frame_unwind_h) $(gdbcore_h) \
-	$(gdbtypes_h) $(inferior_h) $(osabi_h) $(regcache_h) $(target_h) \
-	$(value_h) $(gdb_assert_h) $(gdb_string_h) $(sparc_tdep_h) \
+	$(gdbtypes_h) $(inferior_h) $(symtab_h) $(objfiles_h) $(osabi_h) \
+	$(regcache_h) $(target_h) $(value_h) $(gdb_assert_h) $(gdb_string_h) \
+	$(sparc64_tdep_h)
+sparc64-linux-nat.o: sparc64-linux-nat.c $(defs_h) \
+	$(sparc64_tdep_h) $(sparc_nat_h)
+sparc64-linux-tdep.o: sparc64-linux-tdep.c $(defs_h) $(gdbarch_h) \
+	$(osabi_h) $(solib_svr4_h) $(sparc64_tdep_h)
+sparc64-sol2-nat.o: sparc64-sol2-nat.o $(defs_h) $(gregset_h) $(regcache_h) \
 	$(sparc64_tdep_h)
+sparc64-sol2-tdep.c: sparc64-sol2-tdep.o $(defs_h) $(gdbarch_h) $(symtab_h) \
+	$(objfiles_h) $(osabi_h) $(sparc64_tdep_h)
 sparc64fbsd-tdep.o: sparc64fbsd-tdep.c $(defs_h) $(gdbcore_h) $(osabi_h) \
 	$(regcache_h) $(target_h) $(gdb_string_h) $(sparc64_tdep_h)
 sparc64fbsd-nat.o: sparc64fbsd-nat.c $(defs_h) $(sparc64_tdep_h) \
Index: sparc64-linux-nat.c
===================================================================
RCS file: sparc64-linux-nat.c
diff -N sparc64-linux-nat.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sparc64-linux-nat.c 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,48 @@
+/* Native-dependent code for GNU/Linux UltraSPARC.
+
+   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 "sparc64-tdep.h"
+#include "sparc-nat.h"
+
+static const struct sparc_gregset sparc64_linux_ptrace_gregset =
+{
+  16 * 8,			/* "tstate" */
+  17 * 8,			/* %pc */
+  18 * 8,			/* %npc */
+  19 * 8,			/* %y */
+  -1,				/* %wim */
+  -1,				/* %tbr */
+  0 * 8,			/* %g1 */
+  -1,				/* %l0 */
+  4				/* sizeof (%y) */
+};
+
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_sparc64_linux_nat (void);
+
+void
+_initialize_sparc64_linux_nat (void)
+{
+  sparc_gregset = &sparc64_linux_ptrace_gregset;
+}
Index: sparc64-linux-tdep.c
===================================================================
RCS file: sparc64-linux-tdep.c
diff -N sparc64-linux-tdep.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sparc64-linux-tdep.c 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,82 @@
+/* Target-dependent code for GNU/Linux UltraSPARC.
+
+   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 "solib-svr4.h"
+
+#include "sparc64-tdep.h"
+
+static struct link_map_offsets *
+sparc64_linux_svr4_fetch_link_map_offsets (void)
+{
+  static struct link_map_offsets lmo;
+  static struct link_map_offsets *lmp = NULL;
+
+  if (lmp == NULL)
+    {
+      lmp = &lmo;
+
+      /* Everything we need is in the first 16 bytes.  */
+      lmo.r_debug_size = 16;
+      lmo.r_map_offset = 8;
+      lmo.r_map_size   = 8;
+
+      /* Everything we need is in the first 40 bytes.  */
+      lmo.link_map_size = 40;
+      lmo.l_addr_offset = 0;
+      lmo.l_addr_size   = 8;
+      lmo.l_name_offset = 8;
+      lmo.l_name_size   = 8;
+      lmo.l_next_offset = 24;
+      lmo.l_next_size   = 8;
+      lmo.l_prev_offset = 32;
+      lmo.l_prev_size   = 8;
+    }
+
+  return lmp;
+}
+
+static void
+sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* GNU/Linux is very similar to Solaris ...  */
+  sparc64_sol2_init_abi (info, gdbarch);
+
+  /* ... but doesn't have kernel-assisted single-stepping support.  */
+  set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
+
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, sparc64_linux_svr4_fetch_link_map_offsets);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern void _initialize_sparc64_linux_tdep (void);
+
+void
+_initialize_sparc64_linux_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
+			  GDB_OSABI_LINUX, sparc64_linux_init_abi);
+}
Index: sparc64-nat.c
===================================================================
RCS file: sparc64-nat.c
diff -N sparc64-nat.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sparc64-nat.c 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,86 @@
+/* Native-dependent code for GNU/Linux UltraSPARC.
+
+   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 "sparc64-tdep.h"
+#include "sparc-nat.h"
+
+/* Determine whether `gregset_t' contains register REGNUM.  */
+
+static int
+sparc64_gregset_supplies_p (int regnum)
+{
+  if (gdbarch_ptr_bit (current_gdbarch) == 32)
+    return sparc32_gregset_supplies_p (regnum);
+
+  /* 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 == SPARC64_PC_REGNUM
+      || regnum == SPARC64_NPC_REGNUM
+      || regnum == SPARC64_STATE_REGNUM
+      || regnum == SPARC64_Y_REGNUM)
+    return 1;
+
+  return 0;
+}
+
+/* Determine whether `fpregset_t' contains register REGNUM.  */
+
+static int
+sparc64_fpregset_supplies_p (int regnum)
+{
+  if (gdbarch_ptr_bit (current_gdbarch) == 32)
+    return sparc32_fpregset_supplies_p (regnum);
+
+  /* Floating-point registers.  */
+  if ((regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
+      || (regnum >= SPARC64_F32_REGNUM && regnum <= SPARC64_F62_REGNUM))
+    return 1;
+
+  /* Control registers.  */
+  if (regnum == SPARC64_FSR_REGNUM)
+    return 1;
+
+  return 0;
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_sparc64_nat (void);
+
+void
+_initialize_sparc64_nat (void)
+{
+  sparc_supply_gregset = sparc64_supply_gregset;
+  sparc_collect_gregset = sparc64_collect_gregset;
+  sparc_supply_fpregset = sparc64_supply_fpregset;
+  sparc_collect_fpregset = sparc64_collect_fpregset;
+  sparc_gregset_supplies_p = sparc64_gregset_supplies_p;
+  sparc_fpregset_supplies_p = sparc64_fpregset_supplies_p;
+}
Index: sparc64-sol2-nat.c
===================================================================
RCS file: sparc64-sol2-nat.c
diff -N sparc64-sol2-nat.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sparc64-sol2-nat.c 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,57 @@
+/* Native-dependent code for Solaris UltraSPARC.
+
+   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 "regcache.h"
+
+#include <sys/procfs.h>
+#include "gregset.h"
+
+#include "sparc64-tdep.h"
+
+/* These functions provide the (temporary) glue between the Solaris
+   SPARC target dependent code and the machine independent SVR4 /proc
+   support.  */
+
+void
+supply_gregset (prgregset_t *gregs)
+{
+  sparc64_supply_gregset (&sparc64_sol2_gregset, current_regcache, -1, gregs);
+}
+
+void
+supply_fpregset (prfpregset_t *fpregs)
+{
+  sparc64_supply_fpregset (current_regcache, -1, fpregs);
+}
+
+void
+fill_gregset (prgregset_t *gregs, int regnum)
+{
+  sparc64_collect_gregset (&sparc64_sol2_gregset,
+			   current_regcache, regnum, gregs);
+}
+
+void
+fill_fpregset (prfpregset_t *fpregs, int regnum)
+{
+  sparc64_collect_fpregset (current_regcache, regnum, fpregs);
+}
Index: sparc64-sol2-tdep.c
===================================================================
RCS file: sparc64-sol2-tdep.c
diff -N sparc64-sol2-tdep.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sparc64-sol2-tdep.c 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,73 @@
+/* Target-dependent code for Solaris UltraSPARC.
+
+   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 "symtab.h"
+#include "objfiles.h"
+#include "osabi.h"
+
+#include "sparc64-tdep.h"
+
+/* From <sys/regset.h>.  */
+const struct sparc_gregset sparc64_sol2_gregset =
+{
+  32 * 8,			/* "tstate" */
+  33 * 8,			/* %pc */
+  34 * 8,			/* %npc */
+  35 * 8,			/* %y */
+  -1,				/* %wim */
+  -1,				/* %tbr */
+  1 * 8,			/* %g1 */
+  16 * 8,			/* %l0 */
+  8				/* sizeof (%y) */
+};
+
+
+void
+sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  sparc64_init_abi (info, gdbarch);
+
+  /* Solaris has SVR4-style shared libraries...  */
+  set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+  /* ...which means that we need some special handling when doing
+     prologue analysis.  */
+  tdep->plt_entry_size = 16;
+
+  /* Solaris has kernel-assisted single-stepping support.  */
+  set_gdbarch_software_single_step (gdbarch, NULL);
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_sparc64_sol2_tdep (void);
+
+void
+_initialize_sparc64_sol2_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
+			  GDB_OSABI_SOLARIS, sparc64_sol2_init_abi);
+}
Index: sparc64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-tdep.c,v
retrieving revision 1.3.4.1
diff -u -p -r1.3.4.1 sparc64-tdep.c
--- sparc64-tdep.c 18 Oct 2003 18:25:46 -0000 1.3.4.1
+++ sparc64-tdep.c 2 Nov 2003 20:22:35 -0000
@@ -28,6 +28,8 @@
 #include "gdbcore.h"
 #include "gdbtypes.h"
 #include "inferior.h"
+#include "symtab.h"
+#include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
 #include "target.h"
@@ -36,7 +38,6 @@
 #include "gdb_assert.h"
 #include "gdb_string.h"
 
-#include "sparc-tdep.h"
 #include "sparc64-tdep.h"
 
 /* This file implements the The SPARC 64-bit ABI as defined by the
@@ -56,11 +57,13 @@
 
 /* Macros to extract fields from SPARC instructions.  */
 #define X_OP(i) (((i) >> 30) & 0x3)
+#define X_RD(i) (((i) >> 25) & 0x1f)
 #define X_A(i) (((i) >> 29) & 1)
 #define X_COND(i) (((i) >> 25) & 0xf)
 #define X_OP2(i) (((i) >> 22) & 0x7)
 #define X_IMM22(i) ((i) & 0x3fffff)
 #define X_OP3(i) (((i) >> 19) & 0x3f)
+#define X_I(i) (((i) >> 13) & 1)
 /* Sign extension macros.  */
 #define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
 #define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
@@ -526,17 +529,52 @@ static CORE_ADDR
 sparc64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
 			  struct sparc64_frame_cache *cache)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   unsigned long insn;
+  int offset = 0;
+  int dest = -1;
 
   if (current_pc <= pc)
     return current_pc;
 
-  /* Check whether the function starts with a SAVE instruction.  */
+  /* We have to handle to "Procedure Linkage Table" (PLT) special.  On
+     SPARC the linker usually defines a symbol (typically
+     _PROCEDURE_LINKAGE_TABLE_) at the start of the .plt section.
+     This symbol makes us end up here with PC pointing at the start of
+     the PLT and CURRENT_PC probably pointing at a PLT entry.  If we
+     would do our normal prologue analysis, we would probably conclude
+     that we've got a frame when in reality we don't, since the
+     dynamic linker patches up the first PLT with some code that
+     starts with a SAVE instruction.  Patch up PC such that it points
+     at the start of our PLT entry.  */
+  if (tdep->plt_entry_size > 0 && in_plt_section (current_pc, NULL))
+    pc = current_pc - ((current_pc - pc) % tdep->plt_entry_size);
+
   insn = sparc_fetch_instruction (pc);
+
+  /* Recognize a SETHI insn and record its destination.  */
+  if (X_OP (insn) == 0 && X_OP2 (insn) == 0x04)
+    {
+      dest = X_RD (insn);
+      offset += 4;
+
+      insn = sparc_fetch_instruction (pc + 4);
+    }
+
+  /* Allow for an arithmetic operation on DEST or %g1.  */
+  if (X_OP (insn) == 2 && X_I (insn)
+      && (X_RD (insn) == 1 || X_RD (insn) == dest))
+    {
+      offset += 4;
+
+      insn = sparc_fetch_instruction (pc + 8);
+    }
+
+  /* Check for the SAVE instruction that sets up the frame.  */
   if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
     {
       cache->frameless_p = 0;
-      return pc + 4;
+      return pc + offset + 4;
     }
 
   return pc;
@@ -1203,4 +1241,299 @@ sparc64_init_abi (struct gdbarch_info in
 
   frame_unwind_append_sniffer (gdbarch, sparc64_frame_sniffer);
   frame_base_set_default (gdbarch, &sparc64_frame_base);
+}
+
+
+/* Helper functions for dealing with register sets.  */
+
+#define TSTATE_CWP	0x000000000000001f
+#define TSTATE_ICC	0x0000000f00000000
+#define TSTATE_XCC	0x000000f000000000
+
+#define PSR_S		0x00000080
+#define PSR_ICC		0x00f00000
+#define PSR_VERS	0x0f000000
+#define PSR_IMPL	0xf0000000
+#define PSR_V8PLUS	0xff000000
+#define PSR_XCC		0x000f0000
+
+void
+sparc64_supply_gregset (const struct sparc_gregset *gregset,
+			struct regcache *regcache,
+			int regnum, const void *gregs)
+{
+  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
+  const char *regs = gregs;
+  int i;
+
+  if (sparc32)
+    {
+      if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
+	{
+	  int offset = gregset->r_tstate_offset;
+	  ULONGEST tstate, psr;
+	  char buf[4];
+
+	  tstate = extract_unsigned_integer (regs + offset, 8);
+	  psr = ((tstate & TSTATE_CWP) | PSR_S | ((tstate & TSTATE_ICC) >> 12)
+		 | ((tstate & TSTATE_XCC) >> 20) | PSR_V8PLUS);
+	  store_unsigned_integer (buf, 4, psr);
+	  regcache_raw_supply (regcache, SPARC32_PSR_REGNUM, buf);
+	}
+
+      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC32_PC_REGNUM,
+			     regs + gregset->r_pc_offset + 4);
+
+      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC32_NPC_REGNUM,
+			     regs + gregset->r_npc_offset + 4);
+
+      if (regnum == SPARC32_Y_REGNUM || regnum == -1)
+	{
+	  int offset = gregset->r_y_offset + 8 - gregset->r_y_size;
+	  regcache_raw_supply (regcache, SPARC32_Y_REGNUM, regs + offset);
+	}
+    }
+  else
+    {
+      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC64_STATE_REGNUM,
+			     regs + gregset->r_tstate_offset);
+
+      if (regnum == SPARC64_PC_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC64_PC_REGNUM,
+			     regs + gregset->r_pc_offset);
+
+      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC64_NPC_REGNUM,
+			     regs + gregset->r_npc_offset);
+
+      if (regnum == SPARC64_Y_REGNUM || regnum == -1)
+	{
+	  char buf[8];
+
+	  memset (buf, 0, 8);
+	  memcpy (buf + 8 - gregset->r_y_size,
+		  regs + gregset->r_y_offset, gregset->r_y_size);
+	  regcache_raw_supply (regcache, SPARC64_Y_REGNUM, buf);
+	}
+    }
+
+  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;
+
+      if (sparc32)
+	offset += 4;
+
+      for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
+	{
+	  if (regnum == i || regnum == -1)
+	    regcache_raw_supply (regcache, i, regs + offset);
+	  offset += 8;
+	}
+    }
+
+  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;
+
+	  if (sparc32)
+	    offset += 4;
+
+	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
+	    {
+	      if (regnum == i || regnum == -1)
+		regcache_raw_supply (regcache, i, regs + offset);
+	      offset += 8;
+	    }
+	}
+    }
+}
+
+void
+sparc64_collect_gregset (const struct sparc_gregset *gregset,
+			 const struct regcache *regcache,
+			 int regnum, void *gregs)
+{
+  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
+  char *regs = gregs;
+  int i;
+
+  if (sparc32)
+    {
+      if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
+	{
+	  int offset = gregset->r_tstate_offset;
+	  ULONGEST tstate, psr;
+	  char buf[8];
+
+	  tstate = extract_unsigned_integer (regs + offset, 8);
+	  regcache_raw_collect (regcache, SPARC32_PSR_REGNUM, buf);
+	  psr = extract_unsigned_integer (buf, 4);
+	  tstate |= (psr & PSR_ICC) << 12;
+	  if ((psr & (PSR_VERS | PSR_IMPL)) == PSR_V8PLUS)
+	    tstate |= (psr & PSR_XCC) << 20;
+	  store_unsigned_integer (buf, 8, tstate);
+	  memcpy (regs + offset, buf, 8);
+	}
+
+      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC32_PC_REGNUM,
+			      regs + gregset->r_pc_offset + 4);
+
+      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC32_NPC_REGNUM,
+			      regs + gregset->r_npc_offset + 4);
+
+      if (regnum == SPARC32_Y_REGNUM || regnum == -1)
+	{
+	  int offset = gregset->r_y_offset + 8 - gregset->r_y_size;
+	  regcache_raw_collect (regcache, SPARC32_Y_REGNUM, regs + offset);
+	}
+    }
+  else
+    {
+      if (regnum == SPARC64_STATE_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC64_STATE_REGNUM,
+			      regs + gregset->r_tstate_offset);
+
+      if (regnum == SPARC64_PC_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC64_PC_REGNUM,
+			      regs + gregset->r_pc_offset);
+
+      if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC64_NPC_REGNUM,
+			      regs + gregset->r_npc_offset);
+
+      if (regnum == SPARC64_Y_REGNUM || regnum == -1)
+	{
+	  char buf[8];
+
+	  regcache_raw_collect (regcache, SPARC64_Y_REGNUM, buf);
+	  memcpy (regs + gregset->r_y_offset,
+		  buf + 8 - gregset->r_y_size, gregset->r_y_size);
+	}
+    }
+
+  if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
+    {
+      int offset = gregset->r_g1_offset;
+
+      if (sparc32)
+	offset += 4;
+
+      /* %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 += 8;
+	}
+    }
+
+  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;
+
+	  if (sparc32)
+	    offset += 4;
+
+	  for (i = SPARC_L0_REGNUM; i <= SPARC_I7_REGNUM; i++)
+	    {
+	      if (regnum == i || regnum == -1)
+		regcache_raw_collect (regcache, i, regs + offset);
+	      offset += 8;
+	    }
+	}
+    }
+}
+
+void
+sparc64_supply_fpregset (struct regcache *regcache,
+			 int regnum, const void *fpregs)
+{
+  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
+  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 (sparc32)
+    {
+      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC32_FSR_REGNUM,
+			     regs + (32 * 4) + (16 * 8) + 4);
+    }
+  else
+    {
+      for (i = 0; i < 16; i++)
+	{
+	  if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
+	    regcache_raw_supply (regcache, SPARC64_F32_REGNUM + i,
+				 regs + (32 * 4) + (i * 8));
+	}
+
+      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
+	regcache_raw_supply (regcache, SPARC64_FSR_REGNUM,
+			     regs + (32 * 4) + (16 * 8));
+    }
+}
+
+void
+sparc64_collect_fpregset (const struct regcache *regcache,
+			  int regnum, void *fpregs)
+{
+  int sparc32 = (gdbarch_ptr_bit (current_gdbarch) == 32);
+  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 (sparc32)
+    {
+      if (regnum == SPARC32_FSR_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC32_FSR_REGNUM,
+			      regs + (32 * 4) + (16 * 8) + 4);
+    }
+  else
+    {
+      for (i = 0; i < 16; i++)
+	{
+	  if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1)
+	    regcache_raw_collect (regcache, SPARC64_F32_REGNUM + i,
+				  regs + (32 * 4) + (i * 8));
+	}
+
+      if (regnum == SPARC64_FSR_REGNUM || regnum == -1)
+	regcache_raw_collect (regcache, SPARC64_FSR_REGNUM,
+			      regs + (32 * 4) + (16 * 8));
+    }
 }
Index: sparc64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-tdep.h,v
retrieving revision 1.2.6.1
diff -u -p -r1.2.6.1 sparc64-tdep.h
--- sparc64-tdep.h 18 Oct 2003 18:25:46 -0000 1.2.6.1
+++ sparc64-tdep.h 2 Nov 2003 20:22:35 -0000
@@ -24,6 +24,11 @@
 
 #include "sparc-tdep.h"
 
+/* Register offsets for the general-purpose register set.  */
+
+/* UltraSPARC doesn't have %psr.  */
+#define r_tstate_offset r_psr_offset
+
 /* Register numbers of various important registers.  */
 
 enum sparc64_regnum
@@ -66,6 +71,25 @@ enum sparc64_regnum
 
 extern void sparc64_init_abi (struct gdbarch_info info,
 			      struct gdbarch *gdbarch);
+
+extern void sparc64_supply_gregset (const struct sparc_gregset *gregset,
+				    struct regcache *regcache,
+				    int regnum, const void *gregs);
+extern void sparc64_collect_gregset (const struct sparc_gregset *gregset,
+				     const struct regcache *regcache,
+				     int regnum, void *gregs);
+extern void sparc64_supply_fpregset (struct regcache *regcache,
+				     int regnum, const void *fpregs);
+extern void sparc64_collect_fpregset (const struct regcache *regcache,
+				      int regnum, void *fpregs);
+
+/* Functions and variables exported from sparc64-sol2-tdep.c.  */
+
+/* Register offsets for Solaris 2.  */
+extern const struct sparc_gregset sparc64_sol2_gregset;
+
+extern void sparc64_sol2_init_abi (struct gdbarch_info info,
+				   struct gdbarch *gdbarch);
 
 /* Functions exported from sparc64fbsd-tdep.c.  */
 
Index: config/sparc/linux64.mh
===================================================================
RCS file: config/sparc/linux64.mh
diff -N config/sparc/linux64.mh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ config/sparc/linux64.mh 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,11 @@
+# Host: GNU/Linux UltraSPARC
+NAT_FILE= nm-linux.h
+NATDEPFILES= sparc-nat.o sparc64-nat.o sparc64-sol2-nat.o sparc64-linux-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
Index: config/sparc/linux64.mt
===================================================================
RCS file: config/sparc/linux64.mt
diff -N config/sparc/linux64.mt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ config/sparc/linux64.mt 2 Nov 2003 20:22:35 -0000
@@ -0,0 +1,5 @@
+# Target: GNU/Linux UltraSPARC
+TDEPFILES= sparc64-tdep.o sparc64-sol2-tdep.o sparc64-linux-tdep.o \
+	sparc-tdep.o sparc-sol2-tdep.o sparc-linux-tdep.o \
+	solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]