* linux-thread-db.c (thread_db_mourn_inferior): Remove breakpoints
[deliverable/binutils-gdb.git] / gdb / sparcnbsd-tdep.c
index bfdb114d2323652ce753c8214d8cf6fd33b3eea3..73dee1409b9b34aa97b5b332e82b5fcd0e85293e 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for NetBSD/sparc.
 
-   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    Contributed by Wasabi Systems, Inc.
 
    This file is part of GDB.
@@ -17,8 +17,8 @@
 
    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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "floatformat.h"
 #include "sparc-tdep.h"
 #include "nbsd-tdep.h"
 
+/* Macros to extract fields from SPARC instructions.  */
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_RS2(i) ((i) & 0x1f)
+#define X_I(i) (((i) >> 13) & 1)
+
 const struct sparc_gregset sparc32nbsd_gregset =
 {
   0 * 4,                       /* %psr */
@@ -224,7 +229,7 @@ sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *next_frame,
                                            int regnum, int *optimizedp,
                                            enum lval_type *lvalp,
                                            CORE_ADDR *addrp,
-                                           int *realnump, void *valuep)
+                                           int *realnump, gdb_byte *valuep)
 {
   struct sparc_frame_cache *cache =
     sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache);
@@ -256,6 +261,30 @@ sparc32nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
   return NULL;
 }
 \f
+/* Return the address of a system call's alternative return
+   address.  */
+
+CORE_ADDR
+sparcnbsd_step_trap (unsigned long insn)
+{
+  if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
+      || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
+    {
+      /* "New" system call.  */
+      ULONGEST number;
+
+      regcache_cooked_read_unsigned (current_regcache,
+                                    SPARC_G1_REGNUM, &number);
+
+      if (number & 0x400)
+       return sparc_address_from_register (SPARC_G2_REGNUM);
+      if (number & 0x800)
+       return sparc_address_from_register (SPARC_G7_REGNUM);
+    }
+
+  return 0;
+}
+\f
 
 static void
 sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
@@ -272,6 +301,9 @@ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->fpregset = regset_alloc (gdbarch, sparc32nbsd_supply_fpregset, NULL);
   tdep->sizeof_fpregset = 33 * 4;
 
+  /* Make sure we can single-step "new" syscalls.  */
+  tdep->step_trap = sparcnbsd_step_trap;
+
   frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer);
 }
 
@@ -281,7 +313,7 @@ sparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   sparc32nbsd_init_abi (info, gdbarch);
 }
 
-static void
+void
 sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   sparc32nbsd_init_abi (info, gdbarch);
This page took 0.024165 seconds and 4 git commands to generate.