]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Initial revision
authorRoland McGrath <roland@gnu.org>
Fri, 17 Jan 1992 05:59:40 +0000 (05:59 +0000)
committerRoland McGrath <roland@gnu.org>
Fri, 17 Jan 1992 05:59:40 +0000 (05:59 +0000)
sysdeps/unix/bsd/sun/sparc/sigcontext.h [new file with mode: 0644]
sysdeps/unix/bsd/sun/sparc/sigtramp.c [new file with mode: 0644]

diff --git a/sysdeps/unix/bsd/sun/sparc/sigcontext.h b/sysdeps/unix/bsd/sun/sparc/sigcontext.h
new file mode 100644 (file)
index 0000000..b61d642
--- /dev/null
@@ -0,0 +1,31 @@
+/* Structure describing state saved while handling a signal.  Sparc version.
+Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+struct sigcontext
+  {
+    int sc_onstack;
+    sigset_t sc_mask;
+
+#define        SPARC_MAXREGWINDOW 31   /* Maximum usable register windows.  */
+    int sc_sp, sc_pc, sc_npc, sc_psr, sc_g1, sc_o0;
+    int sc_wbcnt;              /* Number of outstanding windows.  */
+    PTR sc_spbuf[SPARC_MAXREGWINDOW]; /* SP's for each window.  */
+    int sc_wbuf[SPARC_MAXREGWINDOW][16]; /* Saved register windows.  */
+  };
+
diff --git a/sysdeps/unix/bsd/sun/sparc/sigtramp.c b/sysdeps/unix/bsd/sun/sparc/sigtramp.c
new file mode 100644 (file)
index 0000000..5896e3c
--- /dev/null
@@ -0,0 +1,242 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+
+/* Get the definition of `struct sigcontext'.  */
+#define        KERNEL
+#define        sigvec          sun_sigvec
+#define        sigstack        sun_sigstack
+#define        sigcontext      sun_sigcontext
+#include "/usr/include/sys/signal.h"
+#undef sigvec
+#undef sigstack
+#undef sigcontext
+#undef NSIG
+#undef SIGABRT
+#undef SIGCLD
+#undef SV_ONSTACK
+#undef SV_RESETHAND
+#undef SV_INTERRUPT
+#undef SA_ONSTACK
+#undef SA_NOCLDSTOP
+#undef SIG_ERR
+#undef SIG_DFL
+#undef SIG_IGN
+#undef sigmask
+#undef SIG_BLOCK
+#undef SIG_UNBLOCK
+#undef SIG_SETMASK
+
+#include <signal.h>
+#include <stddef.h>
+#include <errno.h>
+
+/* Defined in __sigvec.S.  */
+extern int EXFUN(__raw_sigvec, (int sig, CONST struct sigvec *vec,
+                               struct sigvec *ovec));
+
+/* User-specified signal handlers.  */
+#define mytramp 1
+#ifdef mytramp
+static __sighandler_t handlers[NSIG];
+#else
+#define handlers _sigfunc
+extern __sighandler_t _sigfunc[];
+#endif
+
+#if mytramp
+
+/* Handler for all signals that are handled by a user-specified function.
+   Saves and restores the general regs %g2-%g7, the %y register, and
+   all the FPU regs (including %fsr), around calling the user's handler.  */
+static void
+DEFUN(trampoline, (sig), int sig)
+{
+  /* We use `double' and `long long int' so `std' (store doubleword) insns,
+     which might be faster than single-word stores, will be generated.  */
+  register double f0 asm("%f0");
+  register double f2 asm("%f2");
+  register double f4 asm("%f4");
+  register double f6 asm("%f6");
+  register double f8 asm("%f8");
+  register double f10 asm("%f10");
+  register double f12 asm("%f12");
+  register double f14 asm("%f14");
+  register double f16 asm("%f16");
+  register double f18 asm("%f18");
+  register double f20 asm("%f20");
+  register double f22 asm("%f22");
+  register double f24 asm("%f24");
+  register double f26 asm("%f26");
+  register double f28 asm("%f28");
+  register double f30 asm("%f30");
+  register long long int g2 asm("%g2");
+  register long long int g4 asm("%g4");
+  register long long int g6 asm("%g6");
+  register int *fp asm("%fp");
+
+  int code;
+  register struct sigcontext *context asm("%i0"); /* See end of fn.  */
+  PTR addr;
+  int y;
+  double fpsave[16];
+  int fsr;
+  int savefpu;
+  long long int glsave[3];
+
+  /* SIG isn't really passed as an arg.
+     The args to the signal handler are at fp[16..19].  */
+  sig = fp[16];
+  code = fp[17];
+  context = (struct sigcontext *) fp[18];
+  addr = (PTR) fp[19];
+
+  /* Save the Y register.  */
+  asm("rd %%y, %0" : "=r" (y));
+
+  /* Save the FPU regs if the FPU enable bit is set in the PSR,
+     and the signal isn't an FP exception.  */
+  savefpu = (context->sc_psr & 0x1000) && sig != SIGFPE;
+  if (savefpu)
+    {
+      fpsave[0] = f0;
+      fpsave[1] = f2;
+      fpsave[2] = f4;
+      fpsave[3] = f6;
+      fpsave[4] = f8;
+      fpsave[5] = f10;
+      fpsave[6] = f12;
+      fpsave[7] = f14;
+      fpsave[8] = f16;
+      fpsave[9] = f18;
+      fpsave[10] = f20;
+      fpsave[11] = f22;
+      fpsave[12] = f24;
+      fpsave[13] = f26;
+      fpsave[14] = f28;
+      fpsave[15] = f30;
+
+      /* Force it into a stack slot so the asm won't barf.  Sigh.  */
+      (void) &fsr;
+      asm("st %%fsr, %0" : "=m" (fsr));
+    }
+
+  /* Save the global registers (except for %g1, which is a scratch reg).  */
+  glsave[0] = g2;
+  glsave[1] = g4;
+  glsave[2] = g6;
+
+  /* Call the user's handler.  */
+  (*((void EXFUN((*), (int sig, int code, struct sigcontext *context,
+                      PTR addr))) handlers[sig]))
+    (sig, code, context, addr);
+
+  /* Restore the Y register.  */
+  asm("mov %0, %%y" : : "r" (y));
+
+  if (savefpu)
+    {
+      /* Restore the FPU regs.  */
+      f0 = fpsave[0];
+      f2 = fpsave[1];
+      f4 = fpsave[2];
+      f6 = fpsave[3];
+      f8 = fpsave[4];
+      f10 = fpsave[5];
+      f12 = fpsave[6];
+      f14 = fpsave[7];
+      f16 = fpsave[8];
+      f18 = fpsave[9];
+      f20 = fpsave[10];
+      f22 = fpsave[11];
+      f24 = fpsave[12];
+      f26 = fpsave[13];
+      f28 = fpsave[14];
+      f30 = fpsave[15];
+
+      asm("ld %0, %%fsr" : : "m" (fsr));
+    }
+
+  /* Restore the globals.  */
+  g2 = glsave[0];
+  g4 = glsave[1];
+  g6 = glsave[2];
+
+  /* Unwind a frame, and do a "sigcleanup" system call.
+     The system call apparently does a return.
+     I don't know what it's for.  Ask Sun.  */
+  asm("restore %%g0, 139, %%g1\n"
+      "ta 0\n"
+      "mov %0, %0"             /* Useless insn that will never be executed, */
+                               /* here to make the compiler happy.  */
+      : /* No outputs.  */ :
+      /* CONTEXT is bound to %i0.  We reference it as an input here to make
+        sure the compiler considers it live at this point, and preserves
+        the value in that register.  The restore makes %i0 become %o0, the
+        argument to the system call.  */
+      "r" (context));
+}
+#endif
+
+int
+DEFUN(__sigvec, (sig, vec, ovec),
+      int sig AND CONST struct sigvec *vec AND struct sigvec *ovec)
+{
+#ifndef        mytramp
+  extern void _sigtramp (int);
+#define        trampoline      _sigtramp
+#endif
+  struct sigvec myvec;
+  int mask;
+  __sighandler_t ohandler;
+
+  if (sig <= 0 || sig >= NSIG)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  mask = __sigblock(sigmask(sig));
+
+  ohandler = handlers[sig];
+
+  if (vec != NULL &&
+      vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL)
+    {
+      handlers[sig] = vec->sv_handler;
+      myvec = *vec;
+      myvec.sv_handler = trampoline;
+      vec = &myvec;
+    }
+
+  if (__raw_sigvec(sig, vec, ovec) < 0)
+    {
+      int save = errno;
+      (void) __sigsetmask(mask);
+      errno = save;
+      return -1;
+    }
+
+  if (ovec != NULL && ovec->sv_handler == trampoline)
+    ovec->sv_handler = ohandler;
+
+  (void) __sigsetmask(mask);
+
+  return 0;
+}