1*4ab7403bSDmitry Chagin /*- 2*4ab7403bSDmitry Chagin * Copyright (c) 2015 Dmitry Chagin 3*4ab7403bSDmitry Chagin * All rights reserved. 4*4ab7403bSDmitry Chagin * 5*4ab7403bSDmitry Chagin * Redistribution and use in source and binary forms, with or without 6*4ab7403bSDmitry Chagin * modification, are permitted provided that the following conditions 7*4ab7403bSDmitry Chagin * are met: 8*4ab7403bSDmitry Chagin * 1. Redistributions of source code must retain the above copyright 9*4ab7403bSDmitry Chagin * notice, this list of conditions and the following disclaimer. 10*4ab7403bSDmitry Chagin * 2. Redistributions in binary form must reproduce the above copyright 11*4ab7403bSDmitry Chagin * notice, this list of conditions and the following disclaimer in the 12*4ab7403bSDmitry Chagin * documentation and/or other materials provided with the distribution. 13*4ab7403bSDmitry Chagin * 14*4ab7403bSDmitry Chagin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*4ab7403bSDmitry Chagin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*4ab7403bSDmitry Chagin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*4ab7403bSDmitry Chagin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*4ab7403bSDmitry Chagin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*4ab7403bSDmitry Chagin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*4ab7403bSDmitry Chagin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*4ab7403bSDmitry Chagin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*4ab7403bSDmitry Chagin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*4ab7403bSDmitry Chagin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*4ab7403bSDmitry Chagin * SUCH DAMAGE. 25*4ab7403bSDmitry Chagin */ 26*4ab7403bSDmitry Chagin 27*4ab7403bSDmitry Chagin #include <sys/cdefs.h> 28*4ab7403bSDmitry Chagin __FBSDID("$FreeBSD$"); 29*4ab7403bSDmitry Chagin 30*4ab7403bSDmitry Chagin #include <sys/param.h> 31*4ab7403bSDmitry Chagin #include <sys/systm.h> 32*4ab7403bSDmitry Chagin #include <sys/signalvar.h> 33*4ab7403bSDmitry Chagin 34*4ab7403bSDmitry Chagin #include <compat/linux/linux.h> 35*4ab7403bSDmitry Chagin 36*4ab7403bSDmitry Chagin 37*4ab7403bSDmitry Chagin static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = { 38*4ab7403bSDmitry Chagin LINUX_SIGHUP, /* SIGHUP */ 39*4ab7403bSDmitry Chagin LINUX_SIGINT, /* SIGINT */ 40*4ab7403bSDmitry Chagin LINUX_SIGQUIT, /* SIGQUIT */ 41*4ab7403bSDmitry Chagin LINUX_SIGILL, /* SIGILL */ 42*4ab7403bSDmitry Chagin LINUX_SIGTRAP, /* SIGTRAP */ 43*4ab7403bSDmitry Chagin LINUX_SIGABRT, /* SIGABRT */ 44*4ab7403bSDmitry Chagin 0, /* SIGEMT */ 45*4ab7403bSDmitry Chagin LINUX_SIGFPE, /* SIGFPE */ 46*4ab7403bSDmitry Chagin LINUX_SIGKILL, /* SIGKILL */ 47*4ab7403bSDmitry Chagin LINUX_SIGBUS, /* SIGBUS */ 48*4ab7403bSDmitry Chagin LINUX_SIGSEGV, /* SIGSEGV */ 49*4ab7403bSDmitry Chagin LINUX_SIGSYS, /* SIGSYS */ 50*4ab7403bSDmitry Chagin LINUX_SIGPIPE, /* SIGPIPE */ 51*4ab7403bSDmitry Chagin LINUX_SIGALRM, /* SIGALRM */ 52*4ab7403bSDmitry Chagin LINUX_SIGTERM, /* SIGTERM */ 53*4ab7403bSDmitry Chagin LINUX_SIGURG, /* SIGURG */ 54*4ab7403bSDmitry Chagin LINUX_SIGSTOP, /* SIGSTOP */ 55*4ab7403bSDmitry Chagin LINUX_SIGTSTP, /* SIGTSTP */ 56*4ab7403bSDmitry Chagin LINUX_SIGCONT, /* SIGCONT */ 57*4ab7403bSDmitry Chagin LINUX_SIGCHLD, /* SIGCHLD */ 58*4ab7403bSDmitry Chagin LINUX_SIGTTIN, /* SIGTTIN */ 59*4ab7403bSDmitry Chagin LINUX_SIGTTOU, /* SIGTTOU */ 60*4ab7403bSDmitry Chagin LINUX_SIGIO, /* SIGIO */ 61*4ab7403bSDmitry Chagin LINUX_SIGXCPU, /* SIGXCPU */ 62*4ab7403bSDmitry Chagin LINUX_SIGXFSZ, /* SIGXFSZ */ 63*4ab7403bSDmitry Chagin LINUX_SIGVTALRM,/* SIGVTALRM */ 64*4ab7403bSDmitry Chagin LINUX_SIGPROF, /* SIGPROF */ 65*4ab7403bSDmitry Chagin LINUX_SIGWINCH, /* SIGWINCH */ 66*4ab7403bSDmitry Chagin 0, /* SIGINFO */ 67*4ab7403bSDmitry Chagin LINUX_SIGUSR1, /* SIGUSR1 */ 68*4ab7403bSDmitry Chagin LINUX_SIGUSR2 /* SIGUSR2 */ 69*4ab7403bSDmitry Chagin }; 70*4ab7403bSDmitry Chagin 71*4ab7403bSDmitry Chagin static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = { 72*4ab7403bSDmitry Chagin SIGHUP, /* LINUX_SIGHUP */ 73*4ab7403bSDmitry Chagin SIGINT, /* LINUX_SIGINT */ 74*4ab7403bSDmitry Chagin SIGQUIT, /* LINUX_SIGQUIT */ 75*4ab7403bSDmitry Chagin SIGILL, /* LINUX_SIGILL */ 76*4ab7403bSDmitry Chagin SIGTRAP, /* LINUX_SIGTRAP */ 77*4ab7403bSDmitry Chagin SIGABRT, /* LINUX_SIGABRT */ 78*4ab7403bSDmitry Chagin SIGBUS, /* LINUX_SIGBUS */ 79*4ab7403bSDmitry Chagin SIGFPE, /* LINUX_SIGFPE */ 80*4ab7403bSDmitry Chagin SIGKILL, /* LINUX_SIGKILL */ 81*4ab7403bSDmitry Chagin SIGUSR1, /* LINUX_SIGUSR1 */ 82*4ab7403bSDmitry Chagin SIGSEGV, /* LINUX_SIGSEGV */ 83*4ab7403bSDmitry Chagin SIGUSR2, /* LINUX_SIGUSR2 */ 84*4ab7403bSDmitry Chagin SIGPIPE, /* LINUX_SIGPIPE */ 85*4ab7403bSDmitry Chagin SIGALRM, /* LINUX_SIGALRM */ 86*4ab7403bSDmitry Chagin SIGTERM, /* LINUX_SIGTERM */ 87*4ab7403bSDmitry Chagin SIGBUS, /* LINUX_SIGSTKFLT */ 88*4ab7403bSDmitry Chagin SIGCHLD, /* LINUX_SIGCHLD */ 89*4ab7403bSDmitry Chagin SIGCONT, /* LINUX_SIGCONT */ 90*4ab7403bSDmitry Chagin SIGSTOP, /* LINUX_SIGSTOP */ 91*4ab7403bSDmitry Chagin SIGTSTP, /* LINUX_SIGTSTP */ 92*4ab7403bSDmitry Chagin SIGTTIN, /* LINUX_SIGTTIN */ 93*4ab7403bSDmitry Chagin SIGTTOU, /* LINUX_SIGTTOU */ 94*4ab7403bSDmitry Chagin SIGURG, /* LINUX_SIGURG */ 95*4ab7403bSDmitry Chagin SIGXCPU, /* LINUX_SIGXCPU */ 96*4ab7403bSDmitry Chagin SIGXFSZ, /* LINUX_SIGXFSZ */ 97*4ab7403bSDmitry Chagin SIGVTALRM, /* LINUX_SIGVTALARM */ 98*4ab7403bSDmitry Chagin SIGPROF, /* LINUX_SIGPROF */ 99*4ab7403bSDmitry Chagin SIGWINCH, /* LINUX_SIGWINCH */ 100*4ab7403bSDmitry Chagin SIGIO, /* LINUX_SIGIO */ 101*4ab7403bSDmitry Chagin /* 102*4ab7403bSDmitry Chagin * FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal 103*4ab7403bSDmitry Chagin * to the first unused FreeBSD signal number. Since Linux supports 104*4ab7403bSDmitry Chagin * signals from 1 to 64 we are ok here as our SIGRTMIN = 65. 105*4ab7403bSDmitry Chagin */ 106*4ab7403bSDmitry Chagin SIGRTMIN, /* LINUX_SIGPWR */ 107*4ab7403bSDmitry Chagin SIGSYS /* LINUX_SIGSYS */ 108*4ab7403bSDmitry Chagin }; 109*4ab7403bSDmitry Chagin 110*4ab7403bSDmitry Chagin /* 111*4ab7403bSDmitry Chagin * Map Linux RT signals to the FreeBSD RT signals. 112*4ab7403bSDmitry Chagin */ 113*4ab7403bSDmitry Chagin static inline int 114*4ab7403bSDmitry Chagin linux_to_bsd_rt_signal(int sig) 115*4ab7403bSDmitry Chagin { 116*4ab7403bSDmitry Chagin 117*4ab7403bSDmitry Chagin return (SIGRTMIN + 1 + sig - LINUX_SIGRTMIN); 118*4ab7403bSDmitry Chagin } 119*4ab7403bSDmitry Chagin 120*4ab7403bSDmitry Chagin static inline int 121*4ab7403bSDmitry Chagin bsd_to_linux_rt_signal(int sig) 122*4ab7403bSDmitry Chagin { 123*4ab7403bSDmitry Chagin 124*4ab7403bSDmitry Chagin return (sig - SIGRTMIN - 1 + LINUX_SIGRTMIN); 125*4ab7403bSDmitry Chagin } 126*4ab7403bSDmitry Chagin 127*4ab7403bSDmitry Chagin int 128*4ab7403bSDmitry Chagin linux_to_bsd_signal(int sig) 129*4ab7403bSDmitry Chagin { 130*4ab7403bSDmitry Chagin 131*4ab7403bSDmitry Chagin KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("Invalid Linux signal\n")); 132*4ab7403bSDmitry Chagin 133*4ab7403bSDmitry Chagin if (sig < LINUX_SIGRTMIN) 134*4ab7403bSDmitry Chagin return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]); 135*4ab7403bSDmitry Chagin 136*4ab7403bSDmitry Chagin return (linux_to_bsd_rt_signal(sig)); 137*4ab7403bSDmitry Chagin } 138*4ab7403bSDmitry Chagin 139*4ab7403bSDmitry Chagin int 140*4ab7403bSDmitry Chagin bsd_to_linux_signal(int sig) 141*4ab7403bSDmitry Chagin { 142*4ab7403bSDmitry Chagin 143*4ab7403bSDmitry Chagin if (sig <= LINUX_SIGTBLSZ) 144*4ab7403bSDmitry Chagin return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]); 145*4ab7403bSDmitry Chagin if (sig == SIGRTMIN) 146*4ab7403bSDmitry Chagin return (LINUX_SIGPWR); 147*4ab7403bSDmitry Chagin 148*4ab7403bSDmitry Chagin return (bsd_to_linux_rt_signal(sig)); 149*4ab7403bSDmitry Chagin } 150*4ab7403bSDmitry Chagin 151*4ab7403bSDmitry Chagin int 152*4ab7403bSDmitry Chagin linux_to_bsd_sigaltstack(int lsa) 153*4ab7403bSDmitry Chagin { 154*4ab7403bSDmitry Chagin int bsa = 0; 155*4ab7403bSDmitry Chagin 156*4ab7403bSDmitry Chagin if (lsa & LINUX_SS_DISABLE) 157*4ab7403bSDmitry Chagin bsa |= SS_DISABLE; 158*4ab7403bSDmitry Chagin /* 159*4ab7403bSDmitry Chagin * Linux ignores SS_ONSTACK flag for ss 160*4ab7403bSDmitry Chagin * parameter while FreeBSD prohibits it. 161*4ab7403bSDmitry Chagin */ 162*4ab7403bSDmitry Chagin return (bsa); 163*4ab7403bSDmitry Chagin } 164*4ab7403bSDmitry Chagin 165*4ab7403bSDmitry Chagin int 166*4ab7403bSDmitry Chagin bsd_to_linux_sigaltstack(int bsa) 167*4ab7403bSDmitry Chagin { 168*4ab7403bSDmitry Chagin int lsa = 0; 169*4ab7403bSDmitry Chagin 170*4ab7403bSDmitry Chagin if (bsa & SS_DISABLE) 171*4ab7403bSDmitry Chagin lsa |= LINUX_SS_DISABLE; 172*4ab7403bSDmitry Chagin if (bsa & SS_ONSTACK) 173*4ab7403bSDmitry Chagin lsa |= LINUX_SS_ONSTACK; 174*4ab7403bSDmitry Chagin return (lsa); 175*4ab7403bSDmitry Chagin } 176*4ab7403bSDmitry Chagin 177*4ab7403bSDmitry Chagin void 178*4ab7403bSDmitry Chagin linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 179*4ab7403bSDmitry Chagin { 180*4ab7403bSDmitry Chagin int b, l; 181*4ab7403bSDmitry Chagin 182*4ab7403bSDmitry Chagin SIGEMPTYSET(*bss); 183*4ab7403bSDmitry Chagin for (l = 1; l <= LINUX_SIGRTMAX; l++) { 184*4ab7403bSDmitry Chagin if (LINUX_SIGISMEMBER(*lss, l)) { 185*4ab7403bSDmitry Chagin b = linux_to_bsd_signal(l); 186*4ab7403bSDmitry Chagin if (b) 187*4ab7403bSDmitry Chagin SIGADDSET(*bss, b); 188*4ab7403bSDmitry Chagin } 189*4ab7403bSDmitry Chagin } 190*4ab7403bSDmitry Chagin } 191*4ab7403bSDmitry Chagin 192*4ab7403bSDmitry Chagin void 193*4ab7403bSDmitry Chagin bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 194*4ab7403bSDmitry Chagin { 195*4ab7403bSDmitry Chagin int b, l; 196*4ab7403bSDmitry Chagin 197*4ab7403bSDmitry Chagin LINUX_SIGEMPTYSET(*lss); 198*4ab7403bSDmitry Chagin for (b = 1; b <= SIGRTMAX; b++) { 199*4ab7403bSDmitry Chagin if (SIGISMEMBER(*bss, b)) { 200*4ab7403bSDmitry Chagin l = bsd_to_linux_signal(b); 201*4ab7403bSDmitry Chagin if (l) 202*4ab7403bSDmitry Chagin LINUX_SIGADDSET(*lss, l); 203*4ab7403bSDmitry Chagin } 204*4ab7403bSDmitry Chagin } 205*4ab7403bSDmitry Chagin } 206