mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 10:22:41 +08:00
Initial revision
This commit is contained in:
parent
daacbef8c7
commit
6231976998
31
sysdeps/unix/bsd/sun/sparc/sigcontext.h
Normal file
31
sysdeps/unix/bsd/sun/sparc/sigcontext.h
Normal file
@ -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. */
|
||||
};
|
||||
|
242
sysdeps/unix/bsd/sun/sparc/sigtramp.c
Normal file
242
sysdeps/unix/bsd/sun/sparc/sigtramp.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user