* lynx-nat.c: Add Sparc support.
authorStu Grossman <grossman@cygnus>
Sat, 22 Jan 1994 01:58:55 +0000 (01:58 +0000)
committerStu Grossman <grossman@cygnus>
Sat, 22 Jan 1994 01:58:55 +0000 (01:58 +0000)
* sparcly-nat.c:  Remove.  It's useless.
* config/sparc/nm-sparclynx.h:  Rewrite.
* config/sparc/sparclynx.mh (NATDEPFILES):  Replace sparcly-nat.o
with lynx-nat.o
* config/sparc/tm-sparclynx.h:  Rewrite.

gdb/ChangeLog
gdb/config/sparc/nm-sparclynx.h
gdb/config/sparc/sparclynx.mh
gdb/config/sparc/tm-sparclynx.h
gdb/lynx-nat.c
gdb/sparcly-nat.c

index 05a8f73c687fee74f2e7721289f7c371cdd84e94..705b3bffa11e662b3c6b16ef3a8075466396761a 100644 (file)
@@ -1,3 +1,12 @@
+Fri Jan 21 17:49:28 1994  Stu Grossman  (grossman at cygnus.com)
+
+       * lynx-nat.c:  Add Sparc support.
+       * sparcly-nat.c:  Remove.  It's useless.
+       * config/sparc/nm-sparclynx.h:  Rewrite.
+       * config/sparc/sparclynx.mh (NATDEPFILES):  Replace sparcly-nat.o
+       with lynx-nat.o
+       * config/sparc/tm-sparclynx.h:  Rewrite.
+
 Fri Jan 21 19:08:48 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
        * rs6000-pinsn.c: Use the new disassembler in the opcodes
index 05a3197021d7001013bd17340903db710390ced0..1bb7d5f3fe7ba41f5feda72f832f21c5f2ee306a 100644 (file)
@@ -20,45 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #ifndef NM_SPARCLYNX_H
 #define NM_SPARCLYNX_H
 
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/mem.h>
-#include <sys/signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/itimer.h>
-#include <sys/file.h>
-#include <sys/proc.h>
-#include "thread.h"
-
-/* This is the amount to subtract from u.u_ar0 to get the offset in
-   the core file of the register values.  */
-
-#define KERNEL_U_ADDR USRSTACK
-
-#undef FLOAT_INFO      /* No float info yet */
-
-#define PTRACE_ARG3_TYPE char*
-
-/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
-#define FETCH_INFERIOR_REGISTERS
-
-/* Thread ID of stopped thread.  */
-
-#define WIFTID(x) (((union wait *)&x)->w_tid)
-
-#define CHILD_WAIT
-
-extern int child_wait PARAMS ((int pid, int *status));
-
-#if 0 /* need sparcly-nat.c to define this */
-/* Lynx needs a special definition of this so that we can
-   print out the pid and thread number seperatly.  */
-
-#undef target_pid_to_str
-#define target_pid_to_str(PID) sparclynx_pid_to_str (PID)
-
-extern char *sparclynx_pid_to_str PARAMS ((int pid));
-#endif
+#include "nm-lynx.h"
 
 #endif /* NM_SPARCLYNX_H */
index cc0d5bae0460b65d88fe1d45d61f4d7d2f08b121..51b94954857d6aa91c74dd00f016d046baf48632 100644 (file)
@@ -2,7 +2,7 @@
 XM_FILE= xm-sparclynx.h
 XDEPFILES= 
 NAT_FILE= nm-sparclynx.h
-NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparcly-nat.o
+NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o lynx-nat.o
 REGEX=regex.o
 REGEX1=regex.o
 GDBSERVER_LIBS= -lbsd
index d62c189f50faaecb685fefefed6469db854326ec..525eeb4e0dbe9d9ecada3cfafd72dfe969b24dfd 100644 (file)
@@ -20,12 +20,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #ifndef TM_SPARCLYNX_H
 #define TM_SPARCLYNX_H
 
-/* Use generic Sparc definitions. */
+#include "tm-lynx.h"
 
+/* Use generic Sparc definitions. */
 #include "sparc/tm-sparc.h"
 
-/* Include COFF shared library support.  */
-
-#include "coff-solib.h"
-
 #endif /* TM_SPARCLYNX_H */
index 48e52d2a7c285982e21d668b43f8768b585a2df0..4510972cf05c183f744571e227aab856f14a9b4d 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <sys/ptrace.h>
 #include <sys/wait.h>
+#include <sys/fpp.h>
 
 static unsigned long registers_addr PARAMS ((int pid));
 
@@ -95,6 +96,287 @@ static int regmap[] =
 };
 #endif
 
+#ifdef SPARC
+/* Mappings from tm-sparc.h */
+
+#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
+
+static int regmap[] =
+{
+  -1,                          /* g0 */
+  X(g1),
+  X(g2),
+  X(g3),
+  X(g4),
+  -1,                          /* g5->g7 aren't saved by Lynx */
+  -1,
+  -1,
+
+  X(o[0]),
+  X(o[1]),
+  X(o[2]),
+  X(o[3]),
+  X(o[4]),
+  X(o[5]),
+  X(o[6]),                     /* sp */
+  X(o[7]),                     /* ra */
+
+  -1,-1,-1,-1,-1,-1,-1,-1,     /* l0 -> l7 */
+
+  -1,-1,-1,-1,-1,-1,-1,-1,     /* i0 -> i7 */
+
+  FX(f.fregs[0]),              /* f0 */
+  FX(f.fregs[1]),
+  FX(f.fregs[2]),
+  FX(f.fregs[3]),
+  FX(f.fregs[4]),
+  FX(f.fregs[5]),
+  FX(f.fregs[6]),
+  FX(f.fregs[7]),
+  FX(f.fregs[8]),
+  FX(f.fregs[9]),
+  FX(f.fregs[10]),
+  FX(f.fregs[11]),
+  FX(f.fregs[12]),
+  FX(f.fregs[13]),
+  FX(f.fregs[14]),
+  FX(f.fregs[15]),
+  FX(f.fregs[16]),
+  FX(f.fregs[17]),
+  FX(f.fregs[18]),
+  FX(f.fregs[19]),
+  FX(f.fregs[20]),
+  FX(f.fregs[21]),
+  FX(f.fregs[22]),
+  FX(f.fregs[23]),
+  FX(f.fregs[24]),
+  FX(f.fregs[25]),
+  FX(f.fregs[26]),
+  FX(f.fregs[27]),
+  FX(f.fregs[28]),
+  FX(f.fregs[29]),
+  FX(f.fregs[30]),
+  FX(f.fregs[31]),
+
+  X(y),
+  X(psr),
+  X(wim),
+  X(tbr),
+  X(pc),
+  X(npc),
+  FX(fsr),                     /* fpsr */
+  -1,                          /* cpsr */
+};
+#endif
+
+#ifdef SPARC
+
+/* This routine handles some oddball cases for Sparc registers and LynxOS.
+   In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
+   It also handles knows where to find the I & L regs on the stack.  */
+
+void
+fetch_inferior_registers (regno)
+     int regno;
+{
+  int whatregs = 0;
+
+#define WHATREGS_FLOAT 1
+#define WHATREGS_GEN 2
+#define WHATREGS_STACK 4
+
+  if (regno == -1)
+    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
+  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+    whatregs = WHATREGS_STACK;
+  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+    whatregs = WHATREGS_FLOAT;
+  else
+    whatregs = WHATREGS_GEN;
+
+  if (whatregs & WHATREGS_GEN)
+    {
+      struct econtext ec;              /* general regs */
+      char buf[MAX_REGISTER_RAW_SIZE];
+      int retval;
+      int i;
+
+      errno = 0;
+      retval = ptrace (PTRACE_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec,
+                      0);
+      if (errno)
+       perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+  
+      memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
+      supply_register (G0_REGNUM, buf);
+      supply_register (TBR_REGNUM, (char *)&ec.tbr);
+
+      memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
+             4 * REGISTER_RAW_SIZE (G1_REGNUM));
+      for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
+       register_valid[i] = 1;
+
+      supply_register (PS_REGNUM, (char *)&ec.psr);
+      supply_register (Y_REGNUM, (char *)&ec.y);
+      supply_register (PC_REGNUM, (char *)&ec.pc);
+      supply_register (NPC_REGNUM, (char *)&ec.npc);
+      supply_register (WIM_REGNUM, (char *)&ec.wim);
+
+      memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
+             8 * REGISTER_RAW_SIZE (O0_REGNUM));
+      for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
+       register_valid[i] = 1;
+    }
+
+  if (whatregs & WHATREGS_STACK)
+    {
+      CORE_ADDR sp;
+      int i;
+
+      sp = read_register (SP_REGNUM);
+
+      target_xfer_memory (sp, &registers[REGISTER_BYTE(I0_REGNUM)],
+                         8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
+      for (i = I0_REGNUM; i <= I7_REGNUM; i++)
+       register_valid[i] = 1;
+
+      sp += 8 * REGISTER_RAW_SIZE (I0_REGNUM);
+
+      target_xfer_memory (sp, &registers[REGISTER_BYTE(L0_REGNUM)],
+                         8 * REGISTER_RAW_SIZE (L0_REGNUM), 0);
+      for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
+       register_valid[i] = 1;
+    }
+
+  if (whatregs & WHATREGS_FLOAT)
+    {
+      struct fcontext fc;              /* fp regs */
+      int retval;
+      int i;
+
+      errno = 0;
+      retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
+                      0);
+      if (errno)
+       perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+  
+      memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
+             32 * REGISTER_RAW_SIZE (FP0_REGNUM));
+      for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
+       register_valid[i] = 1;
+
+      supply_register (FPS_REGNUM, (char *)&fc.fsr);
+    }
+}
+
+/* This routine handles storing of the I & L regs for the Sparc.  The trick
+   here is that they actually live on the stack.  The really tricky part is
+   that when changing the stack pointer, the I & L regs must be written to
+   where the new SP points, otherwise the regs will be incorrect when the
+   process is started up again.   We assume that the I & L regs are valid at
+   this point.  */
+
+void
+store_inferior_registers (regno)
+     int regno;
+{
+  int whatregs = 0;
+
+  if (regno == -1)
+    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
+  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+    whatregs = WHATREGS_STACK;
+  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+    whatregs = WHATREGS_FLOAT;
+  else if (regno == SP_REGNUM)
+    whatregs = WHATREGS_STACK | WHATREGS_GEN;
+  else
+    whatregs = WHATREGS_GEN;
+
+  if (whatregs & WHATREGS_GEN)
+    {
+      struct econtext ec;              /* general regs */
+      int retval;
+
+      ec.tbr = read_register (TBR_REGNUM);
+      memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
+             4 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+      ec.psr = read_register (PS_REGNUM);
+      ec.y = read_register (Y_REGNUM);
+      ec.pc = read_register (PC_REGNUM);
+      ec.npc = read_register (NPC_REGNUM);
+      ec.wim = read_register (WIM_REGNUM);
+
+      memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
+             8 * REGISTER_RAW_SIZE (O0_REGNUM));
+
+      errno = 0;
+      retval = ptrace (PTRACE_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec,
+                      0);
+      if (errno)
+       perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+    }
+
+  if (whatregs & WHATREGS_STACK)
+    {
+      int regoffset;
+      CORE_ADDR sp;
+
+      sp = read_register (SP_REGNUM);
+
+      if (regno == -1 || regno == SP_REGNUM)
+       {
+         if (!register_valid[L0_REGNUM+5])
+           abort();
+         target_xfer_memory (sp, &registers[REGISTER_BYTE (I0_REGNUM)],
+                             8 * REGISTER_RAW_SIZE (I0_REGNUM), 1);
+         sp += 8 * REGISTER_RAW_SIZE (I0_REGNUM);
+         target_xfer_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+                             8 * REGISTER_RAW_SIZE (L0_REGNUM), 1);
+       }
+      else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+       {
+         if (!register_valid[regno])
+           abort();
+         if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
+           regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
+             + 8 * REGISTER_RAW_SIZE (I0_REGNUM);
+         else
+           regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM);
+         target_xfer_memory (sp + regoffset, &registers[REGISTER_BYTE (regno)],
+                             REGISTER_RAW_SIZE (regno), 1);
+       }
+    }
+
+  if (whatregs & WHATREGS_FLOAT)
+    {
+      struct fcontext fc;              /* fp regs */
+      int retval;
+
+/* We read fcontext first so that we can get good values for fq_t... */
+      errno = 0;
+      retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
+                      0);
+      if (errno)
+       perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+  
+      memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
+             32 * REGISTER_RAW_SIZE (FP0_REGNUM));
+
+      fc.fsr = read_register (FPS_REGNUM);
+
+      errno = 0;
+      retval = ptrace (PTRACE_SETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
+                      0);
+      if (errno)
+       perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
+      }
+}
+#endif
+
+#ifndef SPARC
+
 /* Return the offset relative to the start of the per-thread data to the
    saved context block.  */
 
@@ -142,7 +424,7 @@ fetch_inferior_registers (regno)
 
   ecp = registers_addr (inferior_pid);
 
-  for (regno = reglo; regno <= reghi; regno++)
+  for (regno = reglo; regno <= reghi && regmap[regno] != -1; regno++)
     {
       char buf[MAX_REGISTER_RAW_SIZE];
       int ptrace_fun = PTRACE_PEEKTHREAD;
@@ -189,7 +471,7 @@ store_inferior_registers (regno)
 
   ecp = registers_addr (inferior_pid);
 
-  for (regno = reglo; regno <= reghi; regno++)
+  for (regno = reglo; regno <= reghi && regmap[regno] != -1; regno++)
     {
       int ptrace_fun = PTRACE_POKEUSER;
 
@@ -211,6 +493,7 @@ store_inferior_registers (regno)
        }
     }
 }
+#endif /* ifndef SPARC */
 
 /* Wait for child to do something.  Return pid of child, or -1 in case
    of error; store status through argument pointer OURSTATUS.  */
@@ -231,7 +514,12 @@ child_wait (pid, ourstatus)
       if (attach_flag)
        set_sigint_trap();      /* Causes SIGINT to be passed on to the
                                   attached process. */
-      pid = wait (status);
+      pid = wait (&status);
+#ifdef SPARC
+/* Swap halves of status so that the rest of GDB can understand it */
+      status = (status << 16) | ((unsigned)status >> 16);
+#endif
+
       save_errno = errno;
 
       if (attach_flag)
index 92ab0e87cd67fc23d8106957b2e36eaed654f7d6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,370 +0,0 @@
-/* Native-dependent code for Sparc running LynxOS.
-   Copyright (C) 1989, 1992, 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "defs.h"
-#include "inferior.h"
-#include "target.h"
-
-#include <signal.h>
-#include <sys/ptrace.h>
-#include <sys/wait.h>
-#if 0
-#include <machine/reg.h>
-#endif
-
-/* 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.  */
-
-#define        INT_REGS        1
-#define        STACK_REGS      2
-#define        FP_REGS         4
-
-/* 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.  */
-
-void
-fetch_inferior_registers (regno)
-     int regno;
-{
-#if 0
-  struct regs inferior_registers;
-  struct fp_status inferior_fp_registers;
-  int i;
-
-  /* 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) abort();
-
-  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
-      || (!register_valid[SP_REGNUM] && regno < I7_REGNUM))
-    {
-      if (0 != ptrace (PTRACE_GETREGS, inferior_pid,
-                      (PTRACE_ARG3_TYPE) &inferior_registers, 0))
-       perror("ptrace_getregs");
-      
-      registers[REGISTER_BYTE (0)] = 0;
-      memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
-             15 * REGISTER_RAW_SIZE (G0_REGNUM));
-      *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 
-      *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
-      *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
-      *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
-
-      for (i = G0_REGNUM; i <= O7_REGNUM; i++)
-       register_valid[i] = 1;
-      register_valid[Y_REGNUM] = 1;
-      register_valid[PS_REGNUM] = 1;
-      register_valid[PC_REGNUM] = 1;
-      register_valid[NPC_REGNUM] = 1;
-      /* If we don't set these valid, read_register_bytes() rereads
-        all the regs every time it is called!  FIXME.  */
-      register_valid[WIM_REGNUM] = 1;  /* Not true yet, FIXME */
-      register_valid[TBR_REGNUM] = 1;  /* Not true yet, FIXME */
-      register_valid[FPS_REGNUM] = 1;  /* Not true yet, FIXME */
-      register_valid[CPS_REGNUM] = 1;  /* Not true yet, FIXME */
-    }
-
-  /* Floating point registers */
-  if (regno == -1 || (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
-    {
-      if (0 != ptrace (PTRACE_GETFPREGS, inferior_pid,
-                      (PTRACE_ARG3_TYPE) &inferior_fp_registers,
-                      0))
-           perror("ptrace_getfpregs");
-      memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
-             sizeof inferior_fp_registers.fpu_fr);
-      /* memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)],
-            &inferior_fp_registers.Fpu_fsr,
-            sizeof (FPU_FSR_TYPE));  FIXME???  -- gnu@cyg */
-      for (i = FP0_REGNUM; i <= FP0_REGNUM+31; i++)
-       register_valid[i] = 1;
-      register_valid[FPS_REGNUM] = 1;
-    }
-
-  /* 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)
-    {
-      target_xfer_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
-                         &registers[REGISTER_BYTE (L0_REGNUM)],
-                         16*REGISTER_RAW_SIZE (L0_REGNUM), 0);
-      for (i = L0_REGNUM; i <= I7_REGNUM; i++)
-       register_valid[i] = 1;
-    }
-  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
-    {
-      CORE_ADDR sp = *(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)];
-      i = REGISTER_BYTE (regno);
-      if (register_valid[regno])
-       printf("register %d valid and read\n", regno);
-      target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM),
-                         &registers[i], REGISTER_RAW_SIZE (regno), 0);
-      register_valid[regno] = 1;
-    }
-#endif
-}
-
-/* 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).  */
-
-void
-store_inferior_registers (regno)
-     int regno;
-{
-#if 0
-  struct regs inferior_registers;
-  struct fp_status inferior_fp_registers;
-  int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
-
-  /* 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
-         wanna_store = STACK_REGS;
-      }
-
-  /* See if we're forcing the stores to happen now, or deferring. */
-  if (regno == -2)
-    {
-      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;
-       }
-    }
-
-  if (wanna_store & STACK_REGS)
-    {
-      CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
-
-      if (regno < 0 || regno == SP_REGNUM)
-       {
-         if (!register_valid[L0_REGNUM+5]) abort();
-         target_xfer_memory (sp, 
-                             &registers[REGISTER_BYTE (L0_REGNUM)],
-                             16*REGISTER_RAW_SIZE (L0_REGNUM), 1);
-       }
-      else
-       {
-         if (!register_valid[regno]) abort();
-         target_xfer_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM),
-                             &registers[REGISTER_BYTE (regno)],
-                             REGISTER_RAW_SIZE (regno), 1);
-       }
-       
-    }
-
-  if (wanna_store & INT_REGS)
-    {
-      if (!register_valid[G1_REGNUM]) abort();
-
-      memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
-             15 * REGISTER_RAW_SIZE (G1_REGNUM));
-
-      inferior_registers.r_ps =
-       *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
-      inferior_registers.r_pc =
-       *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
-      inferior_registers.r_npc =
-       *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
-      inferior_registers.r_y =
-       *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
-
-      if (0 != ptrace (PTRACE_SETREGS, inferior_pid,
-                      (PTRACE_ARG3_TYPE) &inferior_registers, 0))
-       perror("ptrace_setregs");
-    }
-
-  if (wanna_store & FP_REGS)
-    {
-      if (!register_valid[FP0_REGNUM+9]) abort();
-      /* Initialize inferior_fp_registers members that gdb doesn't set
-        by reading them from the inferior.  */
-      if (0 !=
-        ptrace (PTRACE_GETFPREGS, inferior_pid,
-                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
-        perror("ptrace_getfpregs");
-      memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
-             sizeof inferior_fp_registers.fpu_fr);
-
-/*    memcpy (&inferior_fp_registers.Fpu_fsr, 
-             &registers[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE));
-****/
-      if (0 !=
-        ptrace (PTRACE_SETFPREGS, inferior_pid,
-                (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
-        perror("ptrace_setfpregs");
-    }
-#endif
-}
-
-
-void
-fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
-  char *core_reg_sect;
-  unsigned core_reg_size;
-  int which;
-  unsigned int ignore; /* reg addr, unused in this version */
-{
-#if 0
-  if (which == 0) {
-
-    /* Integer registers */
-
-#define gregs ((struct regs *)core_reg_sect)
-    /* G0 *always* holds 0.  */
-    *(int *)&registers[REGISTER_BYTE (0)] = 0;
-
-    /* The globals and output registers.  */
-    memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, 
-           15 * REGISTER_RAW_SIZE (G1_REGNUM));
-    *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps;
-    *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc;
-    *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc;
-    *(int *)&registers[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 *)&registers[REGISTER_BYTE (SP_REGNUM)];
-      if (0 != target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)], 
-                         16 * REGISTER_RAW_SIZE (L0_REGNUM)))
-       {
-         /* fprintf so user can still use gdb */
-         fprintf (stderr,
-                  "Couldn't read input and local registers from core file\n");
-       }
-    }
-  } else if (which == 2) {
-
-    /* Floating point registers */
-
-#define fpuregs  ((struct fpu *) core_reg_sect)
-    if (core_reg_size >= sizeof (struct fpu))
-      {
-       memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs,
-               sizeof (fpuregs->fpu_regs));
-       memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr,
-               sizeof (FPU_FSR_TYPE));
-      }
-    else
-      fprintf (stderr, "Couldn't read float regs from core file\n");
-  }
-#endif
-}
-
-/* Wait for child to do something.  Return pid of child, or -1 in case
-   of error; store status through argument pointer STATUS.  */
-
-/* FIXME: Not sparc-specific.  Should be using lynx-nat.c instead; the
-   child_wait's are identical.  */
-
-int
-child_wait (pid, status)
-     int pid;
-     struct target_waitstatus *ourstatus;
-{
-  int save_errno;
-  int thread;
-
-  while (1)
-    {
-      int sig;
-
-      if (attach_flag)
-       set_sigint_trap();      /* Causes SIGINT to be passed on to the
-                                  attached process. */
-      pid = wait (status);
-      save_errno = errno;
-
-      if (attach_flag)
-       clear_sigint_trap();
-
-      if (pid == -1)
-       {
-         if (save_errno == EINTR)
-           continue;
-         fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
-                  safe_strerror (save_errno));
-         /* Claim it exited with unknown signal.  */
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
-         return -1;
-       }
-
-      if (pid != PIDGET (inferior_pid))        /* Some other process?!? */
-       continue;
-
-/*      thread = WIFTID (*status);*/
-      thread = *status >> 16;
-
-      /* Initial thread value can only be acquired via wait, so we have to
-        resort to this hack.  */
-
-      if (TIDGET (inferior_pid) == 0)
-       {
-         inferior_pid = BUILDPID (inferior_pid, thread);
-         add_thread (inferior_pid);
-       }
-
-      pid = BUILDPID (pid, thread);
-
-      store_waitstatus (ourstatus, status);
-
-      return pid;
-    }
-}