1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 /* 10 * Copyright (c) 1980 Regents of the University of California. 11 * All rights reserved. The Berkeley Software License Agreement 12 * specifies the terms and conditions for redistribution. 13 */ 14 15 /* 16 * 4.3BSD signal compatibility functions 17 * 18 * the implementation interprets signal masks equal to -1 as "all of the 19 * signals in the signal set", thereby allowing signals with numbers 20 * above 32 to be blocked when referenced in code such as: 21 * 22 * for (i = 0; i < NSIG; i++) 23 * mask |= sigmask(i) 24 */ 25 26 #include <sys/types.h> 27 #include <sys/siginfo.h> 28 #include <sys/ucontext.h> 29 #include <sys/regset.h> 30 #include <signal.h> 31 #include "signal.h" 32 #include <errno.h> 33 #include <stdio.h> 34 35 #define set2mask(setp) ((setp)->__sigbits[0]) 36 #define mask2set(mask, setp) \ 37 ((mask) == -1 ? sigfillset(setp) : sigemptyset(setp), (((setp)->__sigbits[0]) = (mask))) 38 39 void (*_siguhandler[NSIG])() = { 0 }; 40 41 /* 42 * sigstack is emulated with sigaltstack by guessing an appropriate 43 * value for the stack size - on machines that have stacks that grow 44 * upwards, the ss_sp arguments for both functions mean the same thing, 45 * (the initial stack pointer sigstack() is also the stack base 46 * sigaltstack()), so a "very large" value should be chosen for the 47 * stack size - on machines that have stacks that grow downwards, the 48 * ss_sp arguments mean opposite things, so 0 should be used (hopefully 49 * these machines don't have hardware stack bounds registers that pay 50 * attention to sigaltstack()'s size argument. 51 */ 52 53 #ifdef sun 54 #define SIGSTACKSIZE 0 55 #endif 56 57 58 /* 59 * sigvechandler is the real signal handler installed for all 60 * signals handled in the 4.3BSD compatibility interface - it translates 61 * SVR4 signal hander arguments into 4.3BSD signal handler arguments 62 * and then calls the real handler 63 */ 64 65 static void 66 sigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp) 67 { 68 struct sigcontext sc; 69 int code; 70 char *addr; 71 int i, j; 72 int gwinswitch = 0; 73 74 sc.sc_onstack = ((ucp->uc_stack.ss_flags & SS_ONSTACK) != 0); 75 sc.sc_mask = set2mask(&ucp->uc_sigmask); 76 77 /* 78 * Machine dependent code begins 79 */ 80 sc.sc_sp = ucp->uc_mcontext.gregs[REG_O6]; 81 sc.sc_pc = ucp->uc_mcontext.gregs[REG_PC]; 82 sc.sc_npc = ucp->uc_mcontext.gregs[REG_nPC]; 83 sc.sc_psr = ucp->uc_mcontext.gregs[REG_PSR]; 84 sc.sc_g1 = ucp->uc_mcontext.gregs[REG_G1]; 85 sc.sc_o0 = ucp->uc_mcontext.gregs[REG_O0]; 86 if (ucp->uc_mcontext.gwins != (gwindows_t *)0) { 87 gwinswitch = 1; 88 sc.sc_wbcnt = ucp->uc_mcontext.gwins->wbcnt; 89 for (i = 0; i < MAXWINDOW; i++) { 90 for (j = 0; j < 16; j++) 91 sc.sc_spbuf[i][j] = (int)ucp->uc_mcontext.gwins->spbuf[j]; 92 for (j = 0; j < 8; j++) 93 sc.sc_wbuf[i][j] = ucp->uc_mcontext.gwins->wbuf[i].rw_local[j]; 94 for (j = 0; j < 8; j++) 95 sc.sc_wbuf[i][j+8] = ucp->uc_mcontext.gwins->wbuf[i].rw_in[j]; 96 } 97 } 98 /* 99 * Machine dependent code ends 100 */ 101 102 if (sip != NULL) 103 if ((code = sip->si_code) == BUS_OBJERR) 104 code = SEGV_MAKE_ERR(sip->si_errno); 105 106 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) 107 if (sip != NULL) 108 addr = (char *)sip->si_addr; 109 else 110 addr = SIG_NOADDR; 111 112 (*_siguhandler[sig])(sig, code, &sc, addr); 113 114 if (sc.sc_onstack) 115 ucp->uc_stack.ss_flags |= SS_ONSTACK; 116 else 117 ucp->uc_stack.ss_flags &= ~SS_ONSTACK; 118 mask2set(sc.sc_mask, &ucp->uc_sigmask); 119 120 /* 121 * Machine dependent code begins 122 */ 123 ucp->uc_mcontext.gregs[REG_O6] = sc.sc_sp; 124 ucp->uc_mcontext.gregs[REG_PC] = sc.sc_pc; 125 ucp->uc_mcontext.gregs[REG_nPC] = sc.sc_npc; 126 ucp->uc_mcontext.gregs[REG_PSR] = sc.sc_psr; 127 ucp->uc_mcontext.gregs[REG_G1] = sc.sc_g1; 128 ucp->uc_mcontext.gregs[REG_O0] = sc.sc_o0; 129 if (gwinswitch == 1) { 130 ucp->uc_mcontext.gwins->wbcnt = sc.sc_wbcnt; 131 for (i = 0; i < MAXWINDOW; i++) { 132 for (j = 0; j < 16; j++) 133 ucp->uc_mcontext.gwins->spbuf[j] = (greg_t *)sc.sc_spbuf[i][j]; 134 for (j = 0; j < 8; j++) 135 ucp->uc_mcontext.gwins->wbuf[i].rw_local[j] = sc.sc_wbuf[i][j]; 136 for (j = 0; j < 8; j++) 137 ucp->uc_mcontext.gwins->wbuf[i].rw_in[j] = sc.sc_wbuf[i][j+8]; 138 } 139 } 140 /* 141 * Machine dependent code ends 142 */ 143 144 setcontext (ucp); 145 } 146 147 int 148 sigsetmask(int mask) 149 { 150 sigset_t oset; 151 sigset_t nset; 152 153 (void) sigprocmask(0, (sigset_t *)0, &nset); 154 mask2set(mask, &nset); 155 (void) sigprocmask(SIG_SETMASK, &nset, &oset); 156 return set2mask(&oset); 157 } 158 159 int 160 sigblock(int mask) 161 { 162 sigset_t oset; 163 sigset_t nset; 164 165 (void) sigprocmask(0, (sigset_t *)0, &nset); 166 mask2set(mask, &nset); 167 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 168 return set2mask(&oset); 169 } 170 171 int 172 sigpause(int mask) 173 { 174 sigset_t set; 175 176 (void) sigprocmask(0, (sigset_t *)0, &set); 177 mask2set(mask, &set); 178 return (sigsuspend(&set)); 179 } 180 181 int 182 sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec) 183 { 184 struct sigaction nact; 185 struct sigaction oact; 186 struct sigaction *nactp; 187 void (*ohandler)(), (*nhandler)(); 188 189 if (sig <= 0 || sig >= NSIG) { 190 errno = EINVAL; 191 return -1; 192 } 193 194 ohandler = _siguhandler[sig]; 195 196 if (nvec) { 197 _sigaction(sig, (struct sigaction *)0, &nact); 198 nhandler = nvec->sv_handler; 199 _siguhandler[sig] = nhandler; 200 if (nhandler != SIG_DFL && nhandler != SIG_IGN) 201 nact.sa_handler = (void (*)())sigvechandler; 202 else 203 nact.sa_handler = nhandler; 204 mask2set(nvec->sv_mask, &nact.sa_mask); 205 /* 206 if ( sig == SIGTSTP || sig == SIGSTOP ) 207 nact.sa_handler = SIG_DFL; */ 208 nact.sa_flags = SA_SIGINFO; 209 if (!(nvec->sv_flags & SV_INTERRUPT)) 210 nact.sa_flags |= SA_RESTART; 211 if (nvec->sv_flags & SV_RESETHAND) 212 nact.sa_flags |= SA_RESETHAND; 213 if (nvec->sv_flags & SV_ONSTACK) 214 nact.sa_flags |= SA_ONSTACK; 215 nactp = &nact; 216 } else 217 nactp = (struct sigaction *)0; 218 219 if (_sigaction(sig, nactp, &oact) < 0) { 220 _siguhandler[sig] = ohandler; 221 return -1; 222 } 223 224 if (ovec) { 225 if (oact.sa_handler == SIG_DFL || oact.sa_handler == SIG_IGN) 226 ovec->sv_handler = oact.sa_handler; 227 else 228 ovec->sv_handler = ohandler; 229 ovec->sv_mask = set2mask(&oact.sa_mask); 230 ovec->sv_flags = 0; 231 if (oact.sa_flags & SA_ONSTACK) 232 ovec->sv_flags |= SV_ONSTACK; 233 if (oact.sa_flags & SA_RESETHAND) 234 ovec->sv_flags |= SV_RESETHAND; 235 if (!(oact.sa_flags & SA_RESTART)) 236 ovec->sv_flags |= SV_INTERRUPT; 237 } 238 239 return 0; 240 } 241 242 243 void (* 244 signal(int s, void (*a)()))() 245 { 246 struct sigvec osv; 247 struct sigvec nsv; 248 static int mask[NSIG]; 249 static int flags[NSIG]; 250 251 nsv.sv_handler = a; 252 nsv.sv_mask = mask[s]; 253 nsv.sv_flags = flags[s]; 254 if (sigvec(s, &nsv, &osv) < 0) 255 return (SIG_ERR); 256 if (nsv.sv_mask != osv.sv_mask || nsv.sv_flags != osv.sv_flags) { 257 mask[s] = nsv.sv_mask = osv.sv_mask; 258 flags[s] = nsv.sv_flags = osv.sv_flags & ~SV_RESETHAND; 259 if (sigvec(s, &nsv, (struct sigvec *)0) < 0) 260 return (SIG_ERR); 261 } 262 return (osv.sv_handler); 263 } 264