Rework signal code to allow using it by other modules, like linprocfs:
1. Linux sigset always 64 bit on all platforms. In order to move Linux sigset code to the linux_common module define it as 64 bit int. Move Linux sigset manipulation routines to the MI path. 2. Move Linux signal number definitions to the MI path. In general, they are the same on all platforms except for a few signals. 3. Map Linux RT signals to the FreeBSD RT signals and hide signal conversion tables to avoid conversion errors. 4. Emulate Linux SIGPWR signal via FreeBSD SIGRTMIN signal which is outside of allowed on Linux signal numbers. PR: 197216
This commit is contained in:
parent
04d6782581
commit
fc55d94b46
@ -32,6 +32,7 @@
|
||||
#ifndef _AMD64_LINUX_H_
|
||||
#define _AMD64_LINUX_H_
|
||||
|
||||
#include <compat/linux/linux.h>
|
||||
#include <amd64/linux/linux_syscall.h>
|
||||
|
||||
/*
|
||||
@ -173,49 +174,6 @@ struct l_newstat {
|
||||
l_long __unused3;
|
||||
};
|
||||
|
||||
/*
|
||||
* Signalling
|
||||
*/
|
||||
#define LINUX_SIGHUP 1
|
||||
#define LINUX_SIGINT 2
|
||||
#define LINUX_SIGQUIT 3
|
||||
#define LINUX_SIGILL 4
|
||||
#define LINUX_SIGTRAP 5
|
||||
#define LINUX_SIGABRT 6
|
||||
#define LINUX_SIGIOT LINUX_SIGABRT
|
||||
#define LINUX_SIGBUS 7
|
||||
#define LINUX_SIGFPE 8
|
||||
#define LINUX_SIGKILL 9
|
||||
#define LINUX_SIGUSR1 10
|
||||
#define LINUX_SIGSEGV 11
|
||||
#define LINUX_SIGUSR2 12
|
||||
#define LINUX_SIGPIPE 13
|
||||
#define LINUX_SIGALRM 14
|
||||
#define LINUX_SIGTERM 15
|
||||
#define LINUX_SIGSTKFLT 16
|
||||
#define LINUX_SIGCHLD 17
|
||||
#define LINUX_SIGCONT 18
|
||||
#define LINUX_SIGSTOP 19
|
||||
#define LINUX_SIGTSTP 20
|
||||
#define LINUX_SIGTTIN 21
|
||||
#define LINUX_SIGTTOU 22
|
||||
#define LINUX_SIGURG 23
|
||||
#define LINUX_SIGXCPU 24
|
||||
#define LINUX_SIGXFSZ 25
|
||||
#define LINUX_SIGVTALRM 26
|
||||
#define LINUX_SIGPROF 27
|
||||
#define LINUX_SIGWINCH 28
|
||||
#define LINUX_SIGIO 29
|
||||
#define LINUX_SIGPOLL LINUX_SIGIO
|
||||
#define LINUX_SIGPWR 30
|
||||
#define LINUX_SIGSYS 31
|
||||
#define LINUX_SIGRTMIN 32
|
||||
|
||||
#define LINUX_SIGTBLSZ 31
|
||||
#define LINUX_NSIG 64
|
||||
#define LINUX_NBPW 64
|
||||
#define LINUX_NSIG_WORDS (LINUX_NSIG / LINUX_NBPW)
|
||||
|
||||
/* sigaction flags */
|
||||
#define LINUX_SA_NOCLDSTOP 0x00000001
|
||||
#define LINUX_SA_NOCLDWAIT 0x00000002
|
||||
@ -232,30 +190,11 @@ struct l_newstat {
|
||||
#define LINUX_SIG_UNBLOCK 1
|
||||
#define LINUX_SIG_SETMASK 2
|
||||
|
||||
/* primitives to manipulate sigset_t */
|
||||
|
||||
#define LINUX_SIGEMPTYSET(set) \
|
||||
do { \
|
||||
(set).__bits[0] = 0; \
|
||||
} while(0)
|
||||
|
||||
#define LINUX_SIGISMEMBER(set, sig) \
|
||||
(1UL & ((set).__bits[0] >> _SIG_IDX(sig)))
|
||||
|
||||
#define LINUX_SIGADDSET(set, sig) \
|
||||
(set).__bits[0] |= 1UL << _SIG_IDX(sig)
|
||||
|
||||
/* sigaltstack */
|
||||
#define LINUX_MINSIGSTKSZ 2048
|
||||
#define LINUX_SS_ONSTACK 1
|
||||
#define LINUX_SS_DISABLE 2
|
||||
|
||||
typedef void (*l_handler_t)(l_int);
|
||||
|
||||
typedef struct {
|
||||
l_ulong __bits[LINUX_NSIG_WORDS];
|
||||
} l_sigset_t;
|
||||
|
||||
typedef struct {
|
||||
l_handler_t lsa_handler;
|
||||
l_ulong lsa_flags;
|
||||
|
@ -431,39 +431,3 @@ linux_set_cloned_tls(struct thread *td, void *desc)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
|
||||
{
|
||||
int b, l;
|
||||
|
||||
SIGEMPTYSET(*bss);
|
||||
for (l = 1; l <= LINUX_NSIG; l++) {
|
||||
if (LINUX_SIGISMEMBER(*lss, l)) {
|
||||
if (l <= LINUX_SIGTBLSZ)
|
||||
b = linux_to_bsd_signal[_SIG_IDX(l)];
|
||||
else
|
||||
b = l;
|
||||
if (b)
|
||||
SIGADDSET(*bss, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
|
||||
{
|
||||
int b, l;
|
||||
|
||||
LINUX_SIGEMPTYSET(*lss);
|
||||
for (b = 1; b <= LINUX_NSIG; b++) {
|
||||
if (SIGISMEMBER(*bss, b)) {
|
||||
if (b <= LINUX_SIGTBLSZ)
|
||||
l = bsd_to_linux_signal[_SIG_IDX(b)];
|
||||
else
|
||||
l = b;
|
||||
if (l)
|
||||
LINUX_SIGADDSET(*lss, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,28 +150,6 @@ static int bsd_to_linux_errno[ELAST + 1] = {
|
||||
-72, -67, -71
|
||||
};
|
||||
|
||||
int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
|
||||
LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
|
||||
LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
|
||||
LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
|
||||
LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
|
||||
LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
|
||||
LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
|
||||
LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
|
||||
0, LINUX_SIGUSR1, LINUX_SIGUSR2
|
||||
};
|
||||
|
||||
int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGILL,
|
||||
SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
|
||||
SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||
SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
|
||||
SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
|
||||
SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
|
||||
SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
|
||||
SIGIO, SIGURG, SIGSYS
|
||||
};
|
||||
|
||||
#define LINUX_T_UNKNOWN 255
|
||||
static int _bsd_to_linux_trapcode[] = {
|
||||
LINUX_T_UNKNOWN, /* 0 */
|
||||
@ -657,8 +635,8 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul);
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
|
||||
/* Translate the signal if appropriate. */
|
||||
sig = BSD_TO_LINUX_SIGNAL(sig);
|
||||
/* Translate the signal. */
|
||||
sig = bsd_to_linux_signal(sig);
|
||||
|
||||
/* Save user context. */
|
||||
bzero(&sf, sizeof(sf));
|
||||
@ -772,8 +750,8 @@ struct sysentvec elf_linux_sysvec = {
|
||||
.sv_size = LINUX_SYS_MAXSYSCALL,
|
||||
.sv_table = linux_sysent,
|
||||
.sv_mask = 0,
|
||||
.sv_sigsize = LINUX_SIGTBLSZ,
|
||||
.sv_sigtbl = bsd_to_linux_signal,
|
||||
.sv_sigsize = 0,
|
||||
.sv_sigtbl = NULL,
|
||||
.sv_errsize = ELAST + 1,
|
||||
.sv_errtbl = bsd_to_linux_errno,
|
||||
.sv_transtrap = translate_traps,
|
||||
|
@ -33,6 +33,7 @@
|
||||
#ifndef _AMD64_LINUX_H_
|
||||
#define _AMD64_LINUX_H_
|
||||
|
||||
#include <compat/linux/linux.h>
|
||||
#include <amd64/linux32/linux32_syscall.h>
|
||||
|
||||
/*
|
||||
@ -259,49 +260,6 @@ struct l_statfs64 {
|
||||
l_int f_spare[6];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Signalling
|
||||
*/
|
||||
#define LINUX_SIGHUP 1
|
||||
#define LINUX_SIGINT 2
|
||||
#define LINUX_SIGQUIT 3
|
||||
#define LINUX_SIGILL 4
|
||||
#define LINUX_SIGTRAP 5
|
||||
#define LINUX_SIGABRT 6
|
||||
#define LINUX_SIGIOT LINUX_SIGABRT
|
||||
#define LINUX_SIGBUS 7
|
||||
#define LINUX_SIGFPE 8
|
||||
#define LINUX_SIGKILL 9
|
||||
#define LINUX_SIGUSR1 10
|
||||
#define LINUX_SIGSEGV 11
|
||||
#define LINUX_SIGUSR2 12
|
||||
#define LINUX_SIGPIPE 13
|
||||
#define LINUX_SIGALRM 14
|
||||
#define LINUX_SIGTERM 15
|
||||
#define LINUX_SIGSTKFLT 16
|
||||
#define LINUX_SIGCHLD 17
|
||||
#define LINUX_SIGCONT 18
|
||||
#define LINUX_SIGSTOP 19
|
||||
#define LINUX_SIGTSTP 20
|
||||
#define LINUX_SIGTTIN 21
|
||||
#define LINUX_SIGTTOU 22
|
||||
#define LINUX_SIGURG 23
|
||||
#define LINUX_SIGXCPU 24
|
||||
#define LINUX_SIGXFSZ 25
|
||||
#define LINUX_SIGVTALRM 26
|
||||
#define LINUX_SIGPROF 27
|
||||
#define LINUX_SIGWINCH 28
|
||||
#define LINUX_SIGIO 29
|
||||
#define LINUX_SIGPOLL LINUX_SIGIO
|
||||
#define LINUX_SIGPWR 30
|
||||
#define LINUX_SIGSYS 31
|
||||
#define LINUX_SIGRTMIN 32
|
||||
|
||||
#define LINUX_SIGTBLSZ 31
|
||||
#define LINUX_NSIG_WORDS 2
|
||||
#define LINUX_NBPW 32
|
||||
#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS)
|
||||
|
||||
/* sigaction flags */
|
||||
#define LINUX_SA_NOCLDSTOP 0x00000001
|
||||
#define LINUX_SA_NOCLDWAIT 0x00000002
|
||||
@ -318,23 +276,12 @@ struct l_statfs64 {
|
||||
#define LINUX_SIG_UNBLOCK 1
|
||||
#define LINUX_SIG_SETMASK 2
|
||||
|
||||
/* sigset_t macros */
|
||||
#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0
|
||||
#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig)
|
||||
#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig)
|
||||
|
||||
/* sigaltstack */
|
||||
#define LINUX_MINSIGSTKSZ 2048
|
||||
#define LINUX_SS_ONSTACK 1
|
||||
#define LINUX_SS_DISABLE 2
|
||||
|
||||
typedef l_uintptr_t l_handler_t;
|
||||
typedef l_ulong l_osigset_t;
|
||||
|
||||
typedef struct {
|
||||
l_uint __bits[LINUX_NSIG_WORDS];
|
||||
} __packed l_sigset_t;
|
||||
|
||||
typedef struct {
|
||||
l_handler_t lsa_handler;
|
||||
l_osigset_t lsa_mask;
|
||||
@ -504,7 +451,7 @@ struct l_sigframe {
|
||||
l_int sf_sig;
|
||||
struct l_sigcontext sf_sc;
|
||||
struct l_fpstate sf_fpstate;
|
||||
l_uint sf_extramask[LINUX_NSIG_WORDS-1];
|
||||
l_uint sf_extramask[1];
|
||||
l_handler_t sf_handler;
|
||||
} __packed;
|
||||
|
||||
|
@ -717,7 +717,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
|
||||
act.lsa_flags = osa.lsa_flags;
|
||||
act.lsa_restorer = osa.lsa_restorer;
|
||||
LINUX_SIGEMPTYSET(act.lsa_mask);
|
||||
act.lsa_mask.__bits[0] = osa.lsa_mask;
|
||||
act.lsa_mask.__mask = osa.lsa_mask;
|
||||
}
|
||||
|
||||
error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL,
|
||||
@ -727,7 +727,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
|
||||
osa.lsa_handler = oact.lsa_handler;
|
||||
osa.lsa_flags = oact.lsa_flags;
|
||||
osa.lsa_restorer = oact.lsa_restorer;
|
||||
osa.lsa_mask = oact.lsa_mask.__bits[0];
|
||||
osa.lsa_mask = oact.lsa_mask.__mask;
|
||||
error = copyout(&osa, args->osa, sizeof(l_osigaction_t));
|
||||
}
|
||||
|
||||
@ -751,7 +751,7 @@ linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args)
|
||||
#endif
|
||||
|
||||
LINUX_SIGEMPTYSET(mask);
|
||||
mask.__bits[0] = args->mask;
|
||||
mask.__mask = args->mask;
|
||||
linux_to_bsd_sigset(&mask, &sigmask);
|
||||
return (kern_sigsuspend(td, sigmask));
|
||||
}
|
||||
|
@ -150,28 +150,6 @@ static int bsd_to_linux_errno[ELAST + 1] = {
|
||||
-72, -67, -71
|
||||
};
|
||||
|
||||
int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
|
||||
LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
|
||||
LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
|
||||
LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
|
||||
LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
|
||||
LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
|
||||
LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
|
||||
LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
|
||||
0, LINUX_SIGUSR1, LINUX_SIGUSR2
|
||||
};
|
||||
|
||||
int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGILL,
|
||||
SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
|
||||
SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||
SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
|
||||
SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
|
||||
SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
|
||||
SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
|
||||
SIGIO, SIGURG, SIGSYS
|
||||
};
|
||||
|
||||
#define LINUX_T_UNKNOWN 255
|
||||
static int _bsd_to_linux_trapcode[] = {
|
||||
LINUX_T_UNKNOWN, /* 0 */
|
||||
@ -344,7 +322,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/*
|
||||
* Build the argument list for the signal handler.
|
||||
*/
|
||||
sig = BSD_TO_LINUX_SIGNAL(sig);
|
||||
sig = bsd_to_linux_signal(sig);
|
||||
|
||||
bzero(&frame, sizeof(frame));
|
||||
|
||||
@ -371,7 +349,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
|
||||
bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
|
||||
|
||||
frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
|
||||
frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask;
|
||||
frame.sf_sc.uc_mcontext.sc_edi = regs->tf_rdi;
|
||||
frame.sf_sc.uc_mcontext.sc_esi = regs->tf_rsi;
|
||||
frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_rbp;
|
||||
@ -452,7 +430,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
struct trapframe *regs;
|
||||
struct l_sigframe *fp, frame;
|
||||
l_sigset_t lmask;
|
||||
int oonstack, i;
|
||||
int oonstack;
|
||||
int sig, code;
|
||||
|
||||
sig = ksi->ksi_signo;
|
||||
@ -490,7 +468,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/*
|
||||
* Build the argument list for the signal handler.
|
||||
*/
|
||||
sig = BSD_TO_LINUX_SIGNAL(sig);
|
||||
sig = bsd_to_linux_signal(sig);
|
||||
|
||||
bzero(&frame, sizeof(frame));
|
||||
|
||||
@ -502,7 +480,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/*
|
||||
* Build the signal context to be used by sigreturn.
|
||||
*/
|
||||
frame.sf_sc.sc_mask = lmask.__bits[0];
|
||||
frame.sf_sc.sc_mask = lmask.__mask;
|
||||
frame.sf_sc.sc_gs = regs->tf_gs;
|
||||
frame.sf_sc.sc_fs = regs->tf_fs;
|
||||
frame.sf_sc.sc_es = regs->tf_es;
|
||||
@ -524,8 +502,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
frame.sf_sc.sc_cr2 = (u_int32_t)(uintptr_t)ksi->ksi_addr;
|
||||
frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
|
||||
|
||||
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
|
||||
frame.sf_extramask[i] = lmask.__bits[i+1];
|
||||
frame.sf_extramask[0] = lmask.__mask;
|
||||
|
||||
if (copyout(&frame, fp, sizeof(frame)) != 0) {
|
||||
/*
|
||||
@ -571,7 +548,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
struct trapframe *regs;
|
||||
sigset_t bmask;
|
||||
l_sigset_t lmask;
|
||||
int eflags, i;
|
||||
int eflags;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
@ -612,9 +589,8 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
lmask.__bits[0] = frame.sf_sc.sc_mask;
|
||||
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
|
||||
lmask.__bits[i+1] = frame.sf_extramask[i];
|
||||
lmask.__mask = frame.sf_sc.sc_mask;
|
||||
lmask.__mask = frame.sf_extramask[0];
|
||||
linux_to_bsd_sigset(&lmask, &bmask);
|
||||
kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
|
||||
|
||||
@ -1035,8 +1011,8 @@ struct sysentvec elf_linux_sysvec = {
|
||||
.sv_size = LINUX_SYS_MAXSYSCALL,
|
||||
.sv_table = linux_sysent,
|
||||
.sv_mask = 0,
|
||||
.sv_sigsize = LINUX_SIGTBLSZ,
|
||||
.sv_sigtbl = bsd_to_linux_signal,
|
||||
.sv_sigsize = 0,
|
||||
.sv_sigtbl = NULL,
|
||||
.sv_errsize = ELAST + 1,
|
||||
.sv_errtbl = bsd_to_linux_errno,
|
||||
.sv_transtrap = translate_traps,
|
||||
|
205
sys/compat/linux/linux.c
Normal file
205
sys/compat/linux/linux.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Dmitry Chagin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/signalvar.h>
|
||||
|
||||
#include <compat/linux/linux.h>
|
||||
|
||||
|
||||
static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = {
|
||||
LINUX_SIGHUP, /* SIGHUP */
|
||||
LINUX_SIGINT, /* SIGINT */
|
||||
LINUX_SIGQUIT, /* SIGQUIT */
|
||||
LINUX_SIGILL, /* SIGILL */
|
||||
LINUX_SIGTRAP, /* SIGTRAP */
|
||||
LINUX_SIGABRT, /* SIGABRT */
|
||||
0, /* SIGEMT */
|
||||
LINUX_SIGFPE, /* SIGFPE */
|
||||
LINUX_SIGKILL, /* SIGKILL */
|
||||
LINUX_SIGBUS, /* SIGBUS */
|
||||
LINUX_SIGSEGV, /* SIGSEGV */
|
||||
LINUX_SIGSYS, /* SIGSYS */
|
||||
LINUX_SIGPIPE, /* SIGPIPE */
|
||||
LINUX_SIGALRM, /* SIGALRM */
|
||||
LINUX_SIGTERM, /* SIGTERM */
|
||||
LINUX_SIGURG, /* SIGURG */
|
||||
LINUX_SIGSTOP, /* SIGSTOP */
|
||||
LINUX_SIGTSTP, /* SIGTSTP */
|
||||
LINUX_SIGCONT, /* SIGCONT */
|
||||
LINUX_SIGCHLD, /* SIGCHLD */
|
||||
LINUX_SIGTTIN, /* SIGTTIN */
|
||||
LINUX_SIGTTOU, /* SIGTTOU */
|
||||
LINUX_SIGIO, /* SIGIO */
|
||||
LINUX_SIGXCPU, /* SIGXCPU */
|
||||
LINUX_SIGXFSZ, /* SIGXFSZ */
|
||||
LINUX_SIGVTALRM,/* SIGVTALRM */
|
||||
LINUX_SIGPROF, /* SIGPROF */
|
||||
LINUX_SIGWINCH, /* SIGWINCH */
|
||||
0, /* SIGINFO */
|
||||
LINUX_SIGUSR1, /* SIGUSR1 */
|
||||
LINUX_SIGUSR2 /* SIGUSR2 */
|
||||
};
|
||||
|
||||
static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = {
|
||||
SIGHUP, /* LINUX_SIGHUP */
|
||||
SIGINT, /* LINUX_SIGINT */
|
||||
SIGQUIT, /* LINUX_SIGQUIT */
|
||||
SIGILL, /* LINUX_SIGILL */
|
||||
SIGTRAP, /* LINUX_SIGTRAP */
|
||||
SIGABRT, /* LINUX_SIGABRT */
|
||||
SIGBUS, /* LINUX_SIGBUS */
|
||||
SIGFPE, /* LINUX_SIGFPE */
|
||||
SIGKILL, /* LINUX_SIGKILL */
|
||||
SIGUSR1, /* LINUX_SIGUSR1 */
|
||||
SIGSEGV, /* LINUX_SIGSEGV */
|
||||
SIGUSR2, /* LINUX_SIGUSR2 */
|
||||
SIGPIPE, /* LINUX_SIGPIPE */
|
||||
SIGALRM, /* LINUX_SIGALRM */
|
||||
SIGTERM, /* LINUX_SIGTERM */
|
||||
SIGBUS, /* LINUX_SIGSTKFLT */
|
||||
SIGCHLD, /* LINUX_SIGCHLD */
|
||||
SIGCONT, /* LINUX_SIGCONT */
|
||||
SIGSTOP, /* LINUX_SIGSTOP */
|
||||
SIGTSTP, /* LINUX_SIGTSTP */
|
||||
SIGTTIN, /* LINUX_SIGTTIN */
|
||||
SIGTTOU, /* LINUX_SIGTTOU */
|
||||
SIGURG, /* LINUX_SIGURG */
|
||||
SIGXCPU, /* LINUX_SIGXCPU */
|
||||
SIGXFSZ, /* LINUX_SIGXFSZ */
|
||||
SIGVTALRM, /* LINUX_SIGVTALARM */
|
||||
SIGPROF, /* LINUX_SIGPROF */
|
||||
SIGWINCH, /* LINUX_SIGWINCH */
|
||||
SIGIO, /* LINUX_SIGIO */
|
||||
/*
|
||||
* FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal
|
||||
* to the first unused FreeBSD signal number. Since Linux supports
|
||||
* signals from 1 to 64 we are ok here as our SIGRTMIN = 65.
|
||||
*/
|
||||
SIGRTMIN, /* LINUX_SIGPWR */
|
||||
SIGSYS /* LINUX_SIGSYS */
|
||||
};
|
||||
|
||||
/*
|
||||
* Map Linux RT signals to the FreeBSD RT signals.
|
||||
*/
|
||||
static inline int
|
||||
linux_to_bsd_rt_signal(int sig)
|
||||
{
|
||||
|
||||
return (SIGRTMIN + 1 + sig - LINUX_SIGRTMIN);
|
||||
}
|
||||
|
||||
static inline int
|
||||
bsd_to_linux_rt_signal(int sig)
|
||||
{
|
||||
|
||||
return (sig - SIGRTMIN - 1 + LINUX_SIGRTMIN);
|
||||
}
|
||||
|
||||
int
|
||||
linux_to_bsd_signal(int sig)
|
||||
{
|
||||
|
||||
KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("Invalid Linux signal\n"));
|
||||
|
||||
if (sig < LINUX_SIGRTMIN)
|
||||
return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]);
|
||||
|
||||
return (linux_to_bsd_rt_signal(sig));
|
||||
}
|
||||
|
||||
int
|
||||
bsd_to_linux_signal(int sig)
|
||||
{
|
||||
|
||||
if (sig <= LINUX_SIGTBLSZ)
|
||||
return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]);
|
||||
if (sig == SIGRTMIN)
|
||||
return (LINUX_SIGPWR);
|
||||
|
||||
return (bsd_to_linux_rt_signal(sig));
|
||||
}
|
||||
|
||||
int
|
||||
linux_to_bsd_sigaltstack(int lsa)
|
||||
{
|
||||
int bsa = 0;
|
||||
|
||||
if (lsa & LINUX_SS_DISABLE)
|
||||
bsa |= SS_DISABLE;
|
||||
/*
|
||||
* Linux ignores SS_ONSTACK flag for ss
|
||||
* parameter while FreeBSD prohibits it.
|
||||
*/
|
||||
return (bsa);
|
||||
}
|
||||
|
||||
int
|
||||
bsd_to_linux_sigaltstack(int bsa)
|
||||
{
|
||||
int lsa = 0;
|
||||
|
||||
if (bsa & SS_DISABLE)
|
||||
lsa |= LINUX_SS_DISABLE;
|
||||
if (bsa & SS_ONSTACK)
|
||||
lsa |= LINUX_SS_ONSTACK;
|
||||
return (lsa);
|
||||
}
|
||||
|
||||
void
|
||||
linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
|
||||
{
|
||||
int b, l;
|
||||
|
||||
SIGEMPTYSET(*bss);
|
||||
for (l = 1; l <= LINUX_SIGRTMAX; l++) {
|
||||
if (LINUX_SIGISMEMBER(*lss, l)) {
|
||||
b = linux_to_bsd_signal(l);
|
||||
if (b)
|
||||
SIGADDSET(*bss, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
|
||||
{
|
||||
int b, l;
|
||||
|
||||
LINUX_SIGEMPTYSET(*lss);
|
||||
for (b = 1; b <= SIGRTMAX; b++) {
|
||||
if (SIGISMEMBER(*bss, b)) {
|
||||
l = bsd_to_linux_signal(b);
|
||||
if (l)
|
||||
LINUX_SIGADDSET(*lss, l);
|
||||
}
|
||||
}
|
||||
}
|
95
sys/compat/linux/linux.h
Normal file
95
sys/compat/linux/linux.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Dmitry Chagin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MI_H_
|
||||
#define _LINUX_MI_H_
|
||||
|
||||
/* sigaltstack */
|
||||
#define LINUX_SS_ONSTACK 1
|
||||
#define LINUX_SS_DISABLE 2
|
||||
|
||||
int linux_to_bsd_sigaltstack(int lsa);
|
||||
int bsd_to_linux_sigaltstack(int bsa);
|
||||
|
||||
/* sigset */
|
||||
typedef struct {
|
||||
uint64_t __mask;
|
||||
} l_sigset_t;
|
||||
|
||||
/* primitives to manipulate sigset_t */
|
||||
#define LINUX_SIGEMPTYSET(set) (set).__mask = 0
|
||||
#define LINUX_SIGISMEMBER(set, sig) (1UL & ((set).__mask >> _SIG_IDX(sig)))
|
||||
#define LINUX_SIGADDSET(set, sig) (set).__mask |= 1UL << _SIG_IDX(sig)
|
||||
|
||||
void linux_to_bsd_sigset(l_sigset_t *, sigset_t *);
|
||||
void bsd_to_linux_sigset(sigset_t *, l_sigset_t *);
|
||||
|
||||
/* signaling */
|
||||
#define LINUX_SIGHUP 1
|
||||
#define LINUX_SIGINT 2
|
||||
#define LINUX_SIGQUIT 3
|
||||
#define LINUX_SIGILL 4
|
||||
#define LINUX_SIGTRAP 5
|
||||
#define LINUX_SIGABRT 6
|
||||
#define LINUX_SIGIOT LINUX_SIGABRT
|
||||
#define LINUX_SIGBUS 7
|
||||
#define LINUX_SIGFPE 8
|
||||
#define LINUX_SIGKILL 9
|
||||
#define LINUX_SIGUSR1 10
|
||||
#define LINUX_SIGSEGV 11
|
||||
#define LINUX_SIGUSR2 12
|
||||
#define LINUX_SIGPIPE 13
|
||||
#define LINUX_SIGALRM 14
|
||||
#define LINUX_SIGTERM 15
|
||||
#define LINUX_SIGSTKFLT 16
|
||||
#define LINUX_SIGCHLD 17
|
||||
#define LINUX_SIGCONT 18
|
||||
#define LINUX_SIGSTOP 19
|
||||
#define LINUX_SIGTSTP 20
|
||||
#define LINUX_SIGTTIN 21
|
||||
#define LINUX_SIGTTOU 22
|
||||
#define LINUX_SIGURG 23
|
||||
#define LINUX_SIGXCPU 24
|
||||
#define LINUX_SIGXFSZ 25
|
||||
#define LINUX_SIGVTALRM 26
|
||||
#define LINUX_SIGPROF 27
|
||||
#define LINUX_SIGWINCH 28
|
||||
#define LINUX_SIGIO 29
|
||||
#define LINUX_SIGPOLL LINUX_SIGIO
|
||||
#define LINUX_SIGPWR 30
|
||||
#define LINUX_SIGSYS 31
|
||||
#define LINUX_SIGTBLSZ 31
|
||||
#define LINUX_SIGRTMIN 32
|
||||
#define LINUX_SIGRTMAX 64
|
||||
|
||||
#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_SIGRTMAX && (sig) > 0)
|
||||
|
||||
int linux_to_bsd_signal(int sig);
|
||||
int bsd_to_linux_signal(int sig);
|
||||
|
||||
#endif /* _LINUX_MI_H_ */
|
@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/../linux/linux.h>
|
||||
#include <machine/../linux/linux_proto.h>
|
||||
#endif
|
||||
#include <compat/linux/linux_signal.h>
|
||||
#include <compat/linux/linux_emul.h>
|
||||
#include <compat/linux/linux_futex.h>
|
||||
#include <compat/linux/linux_misc.h>
|
||||
@ -159,9 +158,7 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
|
||||
|
||||
exit_signal = args->flags & 0x000000ff;
|
||||
if (LINUX_SIG_VALID(exit_signal)) {
|
||||
if (exit_signal <= LINUX_SIGTBLSZ)
|
||||
exit_signal =
|
||||
linux_to_bsd_signal[_SIG_IDX(exit_signal)];
|
||||
exit_signal = linux_to_bsd_signal(exit_signal);
|
||||
} else if (exit_signal != 0)
|
||||
return (EINVAL);
|
||||
|
||||
|
@ -871,10 +871,10 @@ linux_common_wait(struct thread *td, int pid, int *status,
|
||||
tmpstat &= 0xffff;
|
||||
if (WIFSIGNALED(tmpstat))
|
||||
tmpstat = (tmpstat & 0xffffff80) |
|
||||
BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
|
||||
bsd_to_linux_signal(WTERMSIG(tmpstat));
|
||||
else if (WIFSTOPPED(tmpstat))
|
||||
tmpstat = (tmpstat & 0xffff00ff) |
|
||||
(BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8);
|
||||
(bsd_to_linux_signal(WSTOPSIG(tmpstat)) << 8);
|
||||
else if (WIFCONTINUED(tmpstat))
|
||||
tmpstat = 0xffff;
|
||||
error = copyout(&tmpstat, status, sizeof(int));
|
||||
@ -987,7 +987,7 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
|
||||
if (td->td_retval[0] == 0)
|
||||
bzero(&lsi, sizeof(lsi));
|
||||
else {
|
||||
sig = BSD_TO_LINUX_SIGNAL(siginfo.si_signo);
|
||||
sig = bsd_to_linux_signal(siginfo.si_signo);
|
||||
siginfo_to_lsiginfo(&siginfo, &lsi, sig);
|
||||
}
|
||||
error = copyout(&lsi, args->info, sizeof(lsi));
|
||||
|
@ -60,42 +60,6 @@ static int linux_do_tkill(struct thread *td, struct thread *tdt,
|
||||
static void sicode_to_lsicode(int si_code, int *lsi_code);
|
||||
|
||||
|
||||
#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
|
||||
void
|
||||
linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
|
||||
{
|
||||
int b, l;
|
||||
|
||||
SIGEMPTYSET(*bss);
|
||||
bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
|
||||
bss->__bits[1] = lss->__bits[1];
|
||||
for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
|
||||
if (LINUX_SIGISMEMBER(*lss, l)) {
|
||||
b = linux_to_bsd_signal[_SIG_IDX(l)];
|
||||
if (b)
|
||||
SIGADDSET(*bss, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
|
||||
{
|
||||
int b, l;
|
||||
|
||||
LINUX_SIGEMPTYSET(*lss);
|
||||
lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
|
||||
lss->__bits[1] = bss->__bits[1];
|
||||
for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
|
||||
if (SIGISMEMBER(*bss, b)) {
|
||||
l = bsd_to_linux_signal[_SIG_IDX(b)];
|
||||
if (l)
|
||||
LINUX_SIGADDSET(*lss, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
|
||||
|
||||
static void
|
||||
linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
|
||||
{
|
||||
@ -163,11 +127,7 @@ linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
|
||||
linux_to_bsd_sigaction(linux_nsa, nsa);
|
||||
} else
|
||||
nsa = NULL;
|
||||
|
||||
if (linux_sig <= LINUX_SIGTBLSZ)
|
||||
sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
|
||||
else
|
||||
sig = linux_sig;
|
||||
sig = linux_to_bsd_signal(linux_sig);
|
||||
|
||||
error = kern_sigaction(td, sig, nsa, osa, 0);
|
||||
if (error)
|
||||
@ -289,7 +249,7 @@ linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
|
||||
if (error)
|
||||
return (error);
|
||||
LINUX_SIGEMPTYSET(set);
|
||||
set.__bits[0] = mask;
|
||||
set.__mask = mask;
|
||||
}
|
||||
|
||||
error = linux_do_sigprocmask(td, args->how,
|
||||
@ -297,7 +257,7 @@ linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
|
||||
args->omask ? &oset : NULL);
|
||||
|
||||
if (args->omask != NULL && !error) {
|
||||
mask = oset.__bits[0];
|
||||
mask = oset.__mask;
|
||||
error = copyout(&mask, args->omask, sizeof(l_osigset_t));
|
||||
}
|
||||
|
||||
@ -353,7 +313,7 @@ linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
|
||||
PROC_LOCK(p);
|
||||
bsd_to_linux_sigset(&td->td_sigmask, &mask);
|
||||
PROC_UNLOCK(p);
|
||||
td->td_retval[0] = mask.__bits[0];
|
||||
td->td_retval[0] = mask.__mask;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -371,9 +331,9 @@ linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
|
||||
|
||||
PROC_LOCK(p);
|
||||
bsd_to_linux_sigset(&td->td_sigmask, &lset);
|
||||
td->td_retval[0] = lset.__bits[0];
|
||||
td->td_retval[0] = lset.__mask;
|
||||
LINUX_SIGEMPTYSET(lset);
|
||||
lset.__bits[0] = args->mask;
|
||||
lset.__mask = args->mask;
|
||||
linux_to_bsd_sigset(&lset, &bset);
|
||||
td->td_sigmask = bset;
|
||||
SIG_CANTMASK(td->td_sigmask);
|
||||
@ -401,7 +361,7 @@ linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
|
||||
SIGSETAND(bset, td->td_sigmask);
|
||||
PROC_UNLOCK(p);
|
||||
bsd_to_linux_sigset(&bset, &lset);
|
||||
mask = lset.__bits[0];
|
||||
mask = lset.__mask;
|
||||
return (copyout(&mask, args->mask, sizeof(mask)));
|
||||
}
|
||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
|
||||
@ -505,7 +465,7 @@ linux_rt_sigtimedwait(struct thread *td,
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo);
|
||||
sig = bsd_to_linux_signal(info.ksi_signo);
|
||||
|
||||
if (args->ptr) {
|
||||
memset(&linfo, 0, sizeof(linfo));
|
||||
@ -537,10 +497,10 @@ linux_kill(struct thread *td, struct linux_kill_args *args)
|
||||
if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
|
||||
return (EINVAL);
|
||||
|
||||
if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
|
||||
tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
|
||||
if (args->signum > 0)
|
||||
tmp.signum = linux_to_bsd_signal(args->signum);
|
||||
else
|
||||
tmp.signum = args->signum;
|
||||
tmp.signum = 0;
|
||||
|
||||
tmp.pid = args->pid;
|
||||
return (sys_kill(td, &tmp));
|
||||
@ -590,10 +550,10 @@ linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
|
||||
if (!LINUX_SIG_VALID(args->sig) && args->sig != 0)
|
||||
return (EINVAL);
|
||||
|
||||
if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ)
|
||||
sig = linux_to_bsd_signal[_SIG_IDX(args->sig)];
|
||||
if (args->sig > 0)
|
||||
sig = linux_to_bsd_signal(args->sig);
|
||||
else
|
||||
sig = args->sig;
|
||||
sig = 0;
|
||||
|
||||
tdt = linux_tdfind(td, args->pid, args->tgid);
|
||||
if (tdt == NULL)
|
||||
@ -628,8 +588,7 @@ linux_tkill(struct thread *td, struct linux_tkill_args *args)
|
||||
if (!LINUX_SIG_VALID(args->sig))
|
||||
return (EINVAL);
|
||||
|
||||
|
||||
sig = BSD_TO_LINUX_SIGNAL(args->sig);
|
||||
sig = linux_to_bsd_signal(args->sig);
|
||||
|
||||
tdt = linux_tdfind(td, args->tid, -1);
|
||||
if (tdt == NULL)
|
||||
@ -727,9 +686,9 @@ siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig)
|
||||
lsi->lsi_uid = si->si_uid;
|
||||
|
||||
if (si->si_code == CLD_STOPPED)
|
||||
lsi->lsi_status = BSD_TO_LINUX_SIGNAL(si->si_status);
|
||||
lsi->lsi_status = bsd_to_linux_signal(si->si_status);
|
||||
else if (si->si_code == CLD_CONTINUED)
|
||||
lsi->lsi_status = BSD_TO_LINUX_SIGNAL(SIGCONT);
|
||||
lsi->lsi_status = bsd_to_linux_signal(SIGCONT);
|
||||
else
|
||||
lsi->lsi_status = si->si_status;
|
||||
break;
|
||||
@ -754,32 +713,6 @@ siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
linux_to_bsd_sigaltstack(int lsa)
|
||||
{
|
||||
int bsa = 0;
|
||||
|
||||
if (lsa & LINUX_SS_DISABLE)
|
||||
bsa |= SS_DISABLE;
|
||||
/*
|
||||
* Linux ignores SS_ONSTACK flag for ss
|
||||
* parameter while FreeBSD prohibits it.
|
||||
*/
|
||||
return (bsa);
|
||||
}
|
||||
|
||||
int
|
||||
bsd_to_linux_sigaltstack(int bsa)
|
||||
{
|
||||
int lsa = 0;
|
||||
|
||||
if (bsa & SS_DISABLE)
|
||||
lsa |= LINUX_SS_DISABLE;
|
||||
if (bsa & SS_ONSTACK)
|
||||
lsa |= LINUX_SS_ONSTACK;
|
||||
return (lsa);
|
||||
}
|
||||
|
||||
void
|
||||
lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig)
|
||||
{
|
||||
@ -812,7 +745,7 @@ linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args
|
||||
if (linfo.lsi_code >= 0)
|
||||
return (EPERM);
|
||||
|
||||
sig = BSD_TO_LINUX_SIGNAL(args->sig);
|
||||
sig = linux_to_bsd_signal(args->sig);
|
||||
|
||||
error = ESRCH;
|
||||
if ((p = pfind(args->pid)) != NULL ||
|
||||
|
@ -43,21 +43,9 @@
|
||||
#define LINUX_SI_SIGIO -5 /* sent by queued SIGIO */
|
||||
#define LINUX_SI_TKILL -6 /* sent by tkill system call */
|
||||
|
||||
extern int bsd_to_linux_signal[];
|
||||
extern int linux_to_bsd_signal[];
|
||||
|
||||
int linux_to_bsd_sigaltstack(int lsa);
|
||||
int bsd_to_linux_sigaltstack(int bsa);
|
||||
void linux_to_bsd_sigset(l_sigset_t *, sigset_t *);
|
||||
void bsd_to_linux_sigset(sigset_t *, l_sigset_t *);
|
||||
int linux_do_sigaction(struct thread *, int, l_sigaction_t *, l_sigaction_t *);
|
||||
void ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig);
|
||||
void siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig);
|
||||
void lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig);
|
||||
|
||||
#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_NSIG && (sig) > 0)
|
||||
|
||||
#define BSD_TO_LINUX_SIGNAL(sig) \
|
||||
(((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig)
|
||||
|
||||
#endif /* _LINUX_SIGNAL_H_ */
|
||||
|
@ -510,6 +510,7 @@ compat/linux/linux_util.c optional compat_linux32
|
||||
compat/linux/linux_vdso.c optional compat_linux32
|
||||
compat/linux/linux_common.c optional compat_linux32
|
||||
compat/linux/linux_event.c optional compat_linux32
|
||||
compat/linux/linux.c optional compat_linux32
|
||||
dev/amr/amr_linux.c optional compat_linux32 amr
|
||||
dev/mfi/mfi_linux.c optional compat_linux32 mfi
|
||||
#
|
||||
|
@ -100,6 +100,7 @@ compat/linux/linux_timer.c optional compat_linux
|
||||
compat/linux/linux_uid16.c optional compat_linux
|
||||
compat/linux/linux_util.c optional compat_linux
|
||||
compat/linux/linux_vdso.c optional compat_linux
|
||||
compat/linux/linux.c optional compat_linux
|
||||
compat/ndis/kern_ndis.c optional ndisapi pci
|
||||
compat/ndis/kern_windrv.c optional ndisapi pci
|
||||
compat/ndis/subr_hal.c optional ndisapi pci
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <sys/signal.h> /* for sigval union */
|
||||
|
||||
#include <compat/linux/linux.h>
|
||||
#include <i386/linux/linux_syscall.h>
|
||||
|
||||
/*
|
||||
@ -234,48 +235,7 @@ struct l_statfs64 {
|
||||
l_int f_spare[6];
|
||||
};
|
||||
|
||||
/*
|
||||
* Signalling
|
||||
*/
|
||||
#define LINUX_SIGHUP 1
|
||||
#define LINUX_SIGINT 2
|
||||
#define LINUX_SIGQUIT 3
|
||||
#define LINUX_SIGILL 4
|
||||
#define LINUX_SIGTRAP 5
|
||||
#define LINUX_SIGABRT 6
|
||||
#define LINUX_SIGIOT LINUX_SIGABRT
|
||||
#define LINUX_SIGBUS 7
|
||||
#define LINUX_SIGFPE 8
|
||||
#define LINUX_SIGKILL 9
|
||||
#define LINUX_SIGUSR1 10
|
||||
#define LINUX_SIGSEGV 11
|
||||
#define LINUX_SIGUSR2 12
|
||||
#define LINUX_SIGPIPE 13
|
||||
#define LINUX_SIGALRM 14
|
||||
#define LINUX_SIGTERM 15
|
||||
#define LINUX_SIGSTKFLT 16
|
||||
#define LINUX_SIGCHLD 17
|
||||
#define LINUX_SIGCONT 18
|
||||
#define LINUX_SIGSTOP 19
|
||||
#define LINUX_SIGTSTP 20
|
||||
#define LINUX_SIGTTIN 21
|
||||
#define LINUX_SIGTTOU 22
|
||||
#define LINUX_SIGURG 23
|
||||
#define LINUX_SIGXCPU 24
|
||||
#define LINUX_SIGXFSZ 25
|
||||
#define LINUX_SIGVTALRM 26
|
||||
#define LINUX_SIGPROF 27
|
||||
#define LINUX_SIGWINCH 28
|
||||
#define LINUX_SIGIO 29
|
||||
#define LINUX_SIGPOLL LINUX_SIGIO
|
||||
#define LINUX_SIGPWR 30
|
||||
#define LINUX_SIGSYS 31
|
||||
#define LINUX_SIGRTMIN 32
|
||||
|
||||
#define LINUX_SIGTBLSZ 31
|
||||
#define LINUX_NSIG_WORDS 2
|
||||
#define LINUX_NBPW 32
|
||||
#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS)
|
||||
|
||||
/* sigaction flags */
|
||||
#define LINUX_SA_NOCLDSTOP 0x00000001
|
||||
@ -293,23 +253,12 @@ struct l_statfs64 {
|
||||
#define LINUX_SIG_UNBLOCK 1
|
||||
#define LINUX_SIG_SETMASK 2
|
||||
|
||||
/* sigset_t macros */
|
||||
#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0
|
||||
#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig)
|
||||
#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig)
|
||||
|
||||
/* sigaltstack */
|
||||
#define LINUX_MINSIGSTKSZ 2048
|
||||
#define LINUX_SS_ONSTACK 1
|
||||
#define LINUX_SS_DISABLE 2
|
||||
|
||||
typedef void (*l_handler_t)(l_int);
|
||||
typedef l_ulong l_osigset_t;
|
||||
|
||||
typedef struct {
|
||||
l_uint __bits[LINUX_NSIG_WORDS];
|
||||
} l_sigset_t;
|
||||
|
||||
typedef struct {
|
||||
l_handler_t lsa_handler;
|
||||
l_osigset_t lsa_mask;
|
||||
|
@ -686,7 +686,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
|
||||
act.lsa_flags = osa.lsa_flags;
|
||||
act.lsa_restorer = osa.lsa_restorer;
|
||||
LINUX_SIGEMPTYSET(act.lsa_mask);
|
||||
act.lsa_mask.__bits[0] = osa.lsa_mask;
|
||||
act.lsa_mask.__mask = osa.lsa_mask;
|
||||
}
|
||||
|
||||
error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL,
|
||||
@ -696,7 +696,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
|
||||
osa.lsa_handler = oact.lsa_handler;
|
||||
osa.lsa_flags = oact.lsa_flags;
|
||||
osa.lsa_restorer = oact.lsa_restorer;
|
||||
osa.lsa_mask = oact.lsa_mask.__bits[0];
|
||||
osa.lsa_mask = oact.lsa_mask.__mask;
|
||||
error = copyout(&osa, args->osa, sizeof(l_osigaction_t));
|
||||
}
|
||||
|
||||
@ -720,7 +720,7 @@ linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args)
|
||||
#endif
|
||||
|
||||
LINUX_SIGEMPTYSET(mask);
|
||||
mask.__bits[0] = args->mask;
|
||||
mask.__mask = args->mask;
|
||||
linux_to_bsd_sigset(&mask, &sigmask);
|
||||
return (kern_sigsuspend(td, sigmask));
|
||||
}
|
||||
|
@ -91,8 +91,7 @@ static __inline int
|
||||
map_signum(int signum)
|
||||
{
|
||||
|
||||
if (signum > 0 && signum <= LINUX_SIGTBLSZ)
|
||||
signum = linux_to_bsd_signal[_SIG_IDX(signum)];
|
||||
signum = linux_to_bsd_signal(signum);
|
||||
return ((signum == SIGSTOP)? 0 : signum);
|
||||
}
|
||||
|
||||
|
@ -149,28 +149,6 @@ static int bsd_to_linux_errno[ELAST + 1] = {
|
||||
-72, -67, -71
|
||||
};
|
||||
|
||||
int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
|
||||
LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
|
||||
LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
|
||||
LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
|
||||
LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
|
||||
LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
|
||||
LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
|
||||
LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
|
||||
0, LINUX_SIGUSR1, LINUX_SIGUSR2
|
||||
};
|
||||
|
||||
int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGILL,
|
||||
SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
|
||||
SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||
SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
|
||||
SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
|
||||
SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
|
||||
SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
|
||||
SIGIO, SIGURG, SIGSYS
|
||||
};
|
||||
|
||||
#define LINUX_T_UNKNOWN 255
|
||||
static int _bsd_to_linux_trapcode[] = {
|
||||
LINUX_T_UNKNOWN, /* 0 */
|
||||
@ -480,7 +458,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/*
|
||||
* Build the argument list for the signal handler.
|
||||
*/
|
||||
sig = BSD_TO_LINUX_SIGNAL(sig);
|
||||
sig = bsd_to_linux_signal(sig);
|
||||
|
||||
bzero(&frame, sizeof(frame));
|
||||
|
||||
@ -506,7 +484,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
|
||||
bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
|
||||
|
||||
frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
|
||||
frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask;
|
||||
frame.sf_sc.uc_mcontext.sc_gs = rgs();
|
||||
frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs;
|
||||
frame.sf_sc.uc_mcontext.sc_es = regs->tf_es;
|
||||
@ -585,7 +563,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
struct l_sigframe *fp, frame;
|
||||
l_sigset_t lmask;
|
||||
int sig, code;
|
||||
int oonstack, i;
|
||||
int oonstack;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
psp = p->p_sigacts;
|
||||
@ -621,7 +599,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/*
|
||||
* Build the argument list for the signal handler.
|
||||
*/
|
||||
sig = BSD_TO_LINUX_SIGNAL(sig);
|
||||
sig = bsd_to_linux_signal(sig);
|
||||
|
||||
bzero(&frame, sizeof(frame));
|
||||
|
||||
@ -633,7 +611,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
/*
|
||||
* Build the signal context to be used by sigreturn.
|
||||
*/
|
||||
frame.sf_sc.sc_mask = lmask.__bits[0];
|
||||
frame.sf_sc.sc_mask = lmask.__mask;
|
||||
frame.sf_sc.sc_gs = rgs();
|
||||
frame.sf_sc.sc_fs = regs->tf_fs;
|
||||
frame.sf_sc.sc_es = regs->tf_es;
|
||||
@ -655,8 +633,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
frame.sf_sc.sc_cr2 = (register_t)ksi->ksi_addr;
|
||||
frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno);
|
||||
|
||||
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
|
||||
frame.sf_extramask[i] = lmask.__bits[i+1];
|
||||
frame.sf_extramask[0] = lmask.__mask;
|
||||
|
||||
if (copyout(&frame, fp, sizeof(frame)) != 0) {
|
||||
/*
|
||||
@ -699,7 +676,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
struct trapframe *regs;
|
||||
l_sigset_t lmask;
|
||||
sigset_t bmask;
|
||||
int eflags, i;
|
||||
int eflags;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
@ -740,9 +717,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
lmask.__bits[0] = frame.sf_sc.sc_mask;
|
||||
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
|
||||
lmask.__bits[i+1] = frame.sf_extramask[i];
|
||||
lmask.__mask = frame.sf_sc.sc_mask;
|
||||
linux_to_bsd_sigset(&lmask, &bmask);
|
||||
kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
|
||||
|
||||
@ -981,8 +956,8 @@ struct sysentvec linux_sysvec = {
|
||||
.sv_size = LINUX_SYS_MAXSYSCALL,
|
||||
.sv_table = linux_sysent,
|
||||
.sv_mask = 0,
|
||||
.sv_sigsize = LINUX_SIGTBLSZ,
|
||||
.sv_sigtbl = bsd_to_linux_signal,
|
||||
.sv_sigsize = 0,
|
||||
.sv_sigtbl = NULL,
|
||||
.sv_errsize = ELAST + 1,
|
||||
.sv_errtbl = bsd_to_linux_errno,
|
||||
.sv_transtrap = translate_traps,
|
||||
@ -1020,8 +995,8 @@ struct sysentvec elf_linux_sysvec = {
|
||||
.sv_size = LINUX_SYS_MAXSYSCALL,
|
||||
.sv_table = linux_sysent,
|
||||
.sv_mask = 0,
|
||||
.sv_sigsize = LINUX_SIGTBLSZ,
|
||||
.sv_sigtbl = bsd_to_linux_signal,
|
||||
.sv_sigsize = 0,
|
||||
.sv_sigtbl = NULL,
|
||||
.sv_errsize = ELAST + 1,
|
||||
.sv_errtbl = bsd_to_linux_errno,
|
||||
.sv_transtrap = translate_traps,
|
||||
|
@ -31,7 +31,7 @@ OBJS= ${VDSO}.so
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "i386"
|
||||
SRCS+= linux_ptrace.c imgact_linux.c linux_util.c linux_mib.c \
|
||||
linux_emul.c opt_cpu.h
|
||||
linux_emul.c opt_cpu.h linux.c
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "i386"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
KMOD= linux_common
|
||||
SRCS= linux_common.c linux_mib.c linux_util.c linux_emul.c \
|
||||
opt_compat.h device_if.h vnode_if.h bus_if.h
|
||||
linux.c opt_compat.h device_if.h vnode_if.h bus_if.h
|
||||
|
||||
EXPORT_SYMS=
|
||||
EXPORT_SYMS+= linux_emul_path
|
||||
|
Loading…
Reference in New Issue
Block a user