1 /* Copyright (C) 1991,1992,1994,1996,1997,2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 #error This file uses GNU C extensions; you must compile with GCC.
23 /* Get the definition of `struct sigcontext'. */
25 #define sigvec sun_sigvec
26 #define sigstack sun_sigstack
27 #define sigcontext sun_sigcontext
28 #include "/usr/include/sys/signal.h"
52 /* Defined in __sigvec.S. */
53 extern int __raw_sigvec (int sig
, CONST
struct sigvec
*vec
,
56 /* User-specified signal handlers. */
59 static __sighandler_t handlers
[NSIG
];
61 #define handlers _sigfunc
62 extern __sighandler_t _sigfunc
[];
67 /* Handler for all signals that are handled by a user-specified function.
68 Saves and restores the general regs %g2-%g7, the %y register, and
69 all the FPU regs (including %fsr), around calling the user's handler. */
74 /* We use `double' and `long long int' so `std' (store doubleword) insns,
75 which might be faster than single-word stores, will be generated. */
76 register double f0
asm("%f0");
77 register double f2
asm("%f2");
78 register double f4
asm("%f4");
79 register double f6
asm("%f6");
80 register double f8
asm("%f8");
81 register double f10
asm("%f10");
82 register double f12
asm("%f12");
83 register double f14
asm("%f14");
84 register double f16
asm("%f16");
85 register double f18
asm("%f18");
86 register double f20
asm("%f20");
87 register double f22
asm("%f22");
88 register double f24
asm("%f24");
89 register double f26
asm("%f26");
90 register double f28
asm("%f28");
91 register double f30
asm("%f30");
92 register long long int g2
asm("%g2");
93 register long long int g4
asm("%g4");
94 register long long int g6
asm("%g6");
95 register int *fp
asm("%fp");
98 register struct sigcontext
*context
asm("%i0"); /* See end of fn. */
104 long long int glsave
[3];
106 /* SIG isn't really passed as an arg.
107 The args to the signal handler are at fp[16..19]. */
110 context
= (struct sigcontext
*) fp
[18];
113 /* Save the Y register. */
114 asm("rd %%y, %0" : "=r" (y
));
116 /* Save the FPU regs if the FPU enable bit is set in the PSR,
117 and the signal isn't an FP exception. */
118 savefpu
= (context
->sc_psr
& 0x1000) && sig
!= SIGFPE
;
138 /* Force it into a stack slot so the asm won't barf. Sigh. */
140 asm("st %%fsr, %0" : "=m" (fsr
));
143 /* Save the global registers (except for %g1, which is a scratch reg). */
148 /* Call the user's handler. */
149 (*((void (*) (int sig
, int code
, struct sigcontext
*context
,
150 void *addr
)) handlers
[sig
]))
151 (sig
, code
, context
, addr
);
153 /* Restore the Y register. */
154 asm("mov %0, %%y" : : "r" (y
));
158 /* Restore the FPU regs. */
176 asm("ld %0, %%fsr" : : "m" (fsr
));
179 /* Restore the globals. */
184 /* Unwind a frame, and do a "sigcleanup" system call.
185 The system call apparently does a return.
186 I don't know what it's for. Ask Sun. */
187 asm("restore %%g0, 139, %%g1\n"
189 "! this should be i0: %0" /* Useless insn that will never be executed, */
190 /* here to make the compiler happy. */
191 : /* No outputs. */ :
192 /* CONTEXT is bound to %i0. We reference it as an input here to make
193 sure the compiler considers it live at this point, and preserves
194 the value in that register. The restore makes %i0 become %o0, the
195 argument to the system call. */
201 __sigvec (sig
, vec
, ovec
)
203 const struct sigvec
*vec
;
207 extern void _sigtramp (int);
208 #define trampoline _sigtramp
212 __sighandler_t ohandler
;
214 if (sig
<= 0 || sig
>= NSIG
)
216 __set_errno (EINVAL
);
220 mask
= __sigblock (sigmask(sig
));
222 ohandler
= handlers
[sig
];
225 vec
->sv_handler
!= SIG_IGN
&& vec
->sv_handler
!= SIG_DFL
)
227 handlers
[sig
] = vec
->sv_handler
;
229 myvec
.sv_handler
= trampoline
;
233 if (__raw_sigvec(sig
, vec
, ovec
) < 0)
236 (void) __sigsetmask(mask
);
241 if (ovec
!= NULL
&& ovec
->sv_handler
== trampoline
)
242 ovec
->sv_handler
= ohandler
;
244 (void) __sigsetmask (mask
);