linux_sysvec.c revision 258559
1/*-
2 * Copyright (c) 1994-1996 S��ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer
10 *    in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/10/sys/i386/linux/linux_sysvec.c 258559 2013-11-25 15:58:48Z emaste $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/exec.h>
35#include <sys/fcntl.h>
36#include <sys/imgact.h>
37#include <sys/imgact_aout.h>
38#include <sys/imgact_elf.h>
39#include <sys/kernel.h>
40#include <sys/lock.h>
41#include <sys/malloc.h>
42#include <sys/module.h>
43#include <sys/mutex.h>
44#include <sys/proc.h>
45#include <sys/signalvar.h>
46#include <sys/syscallsubr.h>
47#include <sys/sysent.h>
48#include <sys/sysproto.h>
49#include <sys/vnode.h>
50#include <sys/eventhandler.h>
51
52#include <vm/vm.h>
53#include <vm/pmap.h>
54#include <vm/vm_extern.h>
55#include <vm/vm_map.h>
56#include <vm/vm_object.h>
57#include <vm/vm_page.h>
58#include <vm/vm_param.h>
59
60#include <machine/cpu.h>
61#include <machine/cputypes.h>
62#include <machine/md_var.h>
63#include <machine/pcb.h>
64
65#include <i386/linux/linux.h>
66#include <i386/linux/linux_proto.h>
67#include <compat/linux/linux_emul.h>
68#include <compat/linux/linux_futex.h>
69#include <compat/linux/linux_ioctl.h>
70#include <compat/linux/linux_mib.h>
71#include <compat/linux/linux_misc.h>
72#include <compat/linux/linux_signal.h>
73#include <compat/linux/linux_util.h>
74
75MODULE_VERSION(linux, 1);
76
77MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
78
79#if BYTE_ORDER == LITTLE_ENDIAN
80#define SHELLMAGIC      0x2123 /* #! */
81#else
82#define SHELLMAGIC      0x2321
83#endif
84
85/*
86 * Allow the sendsig functions to use the ldebug() facility
87 * even though they are not syscalls themselves. Map them
88 * to syscall 0. This is slightly less bogus than using
89 * ldebug(sigreturn).
90 */
91#define	LINUX_SYS_linux_rt_sendsig	0
92#define	LINUX_SYS_linux_sendsig		0
93
94#define	LINUX_PS_STRINGS	(LINUX_USRSTACK - sizeof(struct ps_strings))
95
96extern char linux_sigcode[];
97extern int linux_szsigcode;
98
99extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
100
101SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
102SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
103
104static int	linux_fixup(register_t **stack_base,
105		    struct image_params *iparams);
106static int	elf_linux_fixup(register_t **stack_base,
107		    struct image_params *iparams);
108static void     linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
109static void	exec_linux_setregs(struct thread *td,
110		    struct image_params *imgp, u_long stack);
111static register_t *linux_copyout_strings(struct image_params *imgp);
112static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel);
113
114static int linux_szplatform;
115const char *linux_platform;
116
117static eventhandler_tag linux_exit_tag;
118static eventhandler_tag linux_exec_tag;
119
120/*
121 * Linux syscalls return negative errno's, we do positive and map them
122 * Reference:
123 *   FreeBSD: src/sys/sys/errno.h
124 *   Linux:   linux-2.6.17.8/include/asm-generic/errno-base.h
125 *            linux-2.6.17.8/include/asm-generic/errno.h
126 */
127static int bsd_to_linux_errno[ELAST + 1] = {
128	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
129	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
130	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
131	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
132	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
133	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
134	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
135	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
136	  -6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
137	 -72, -67, -71
138};
139
140int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
141	LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
142	LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
143	LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
144	LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
145	LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
146	LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
147	LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
148	0, LINUX_SIGUSR1, LINUX_SIGUSR2
149};
150
151int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
152	SIGHUP, SIGINT, SIGQUIT, SIGILL,
153	SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
154	SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
155	SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
156	SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
157	SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
158	SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
159	SIGIO, SIGURG, SIGSYS
160};
161
162#define LINUX_T_UNKNOWN  255
163static int _bsd_to_linux_trapcode[] = {
164	LINUX_T_UNKNOWN,	/* 0 */
165	6,			/* 1  T_PRIVINFLT */
166	LINUX_T_UNKNOWN,	/* 2 */
167	3,			/* 3  T_BPTFLT */
168	LINUX_T_UNKNOWN,	/* 4 */
169	LINUX_T_UNKNOWN,	/* 5 */
170	16,			/* 6  T_ARITHTRAP */
171	254,			/* 7  T_ASTFLT */
172	LINUX_T_UNKNOWN,	/* 8 */
173	13,			/* 9  T_PROTFLT */
174	1,			/* 10 T_TRCTRAP */
175	LINUX_T_UNKNOWN,	/* 11 */
176	14,			/* 12 T_PAGEFLT */
177	LINUX_T_UNKNOWN,	/* 13 */
178	17,			/* 14 T_ALIGNFLT */
179	LINUX_T_UNKNOWN,	/* 15 */
180	LINUX_T_UNKNOWN,	/* 16 */
181	LINUX_T_UNKNOWN,	/* 17 */
182	0,			/* 18 T_DIVIDE */
183	2,			/* 19 T_NMI */
184	4,			/* 20 T_OFLOW */
185	5,			/* 21 T_BOUND */
186	7,			/* 22 T_DNA */
187	8,			/* 23 T_DOUBLEFLT */
188	9,			/* 24 T_FPOPFLT */
189	10,			/* 25 T_TSSFLT */
190	11,			/* 26 T_SEGNPFLT */
191	12,			/* 27 T_STKFLT */
192	18,			/* 28 T_MCHK */
193	19,			/* 29 T_XMMFLT */
194	15			/* 30 T_RESERVED */
195};
196#define bsd_to_linux_trapcode(code) \
197    ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \
198     _bsd_to_linux_trapcode[(code)]: \
199     LINUX_T_UNKNOWN)
200
201/*
202 * If FreeBSD & Linux have a difference of opinion about what a trap
203 * means, deal with it here.
204 *
205 * MPSAFE
206 */
207static int
208translate_traps(int signal, int trap_code)
209{
210	if (signal != SIGBUS)
211		return signal;
212	switch (trap_code) {
213	case T_PROTFLT:
214	case T_TSSFLT:
215	case T_DOUBLEFLT:
216	case T_PAGEFLT:
217		return SIGSEGV;
218	default:
219		return signal;
220	}
221}
222
223static int
224linux_fixup(register_t **stack_base, struct image_params *imgp)
225{
226	register_t *argv, *envp;
227
228	argv = *stack_base;
229	envp = *stack_base + (imgp->args->argc + 1);
230	(*stack_base)--;
231	suword(*stack_base, (intptr_t)(void *)envp);
232	(*stack_base)--;
233	suword(*stack_base, (intptr_t)(void *)argv);
234	(*stack_base)--;
235	suword(*stack_base, imgp->args->argc);
236	return (0);
237}
238
239static int
240elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
241{
242	struct proc *p;
243	Elf32_Auxargs *args;
244	Elf32_Addr *uplatform;
245	struct ps_strings *arginfo;
246	register_t *pos;
247
248	KASSERT(curthread->td_proc == imgp->proc,
249	    ("unsafe elf_linux_fixup(), should be curproc"));
250
251	p = imgp->proc;
252	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
253	uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);
254	args = (Elf32_Auxargs *)imgp->auxargs;
255	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
256
257	AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
258
259	/*
260	 * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0,
261	 * as it has appeared in the 2.4.0-rc7 first time.
262	 * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK),
263	 * glibc falls back to the hard-coded CLK_TCK value when aux entry
264	 * is not present.
265	 * Also see linux_times() implementation.
266	 */
267	if (linux_kernver(curthread) >= LINUX_KERNVER_2004000)
268		AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
269	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
270	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
271	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
272	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
273	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
274	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
275	AUXARGS_ENTRY(pos, AT_BASE, args->base);
276	AUXARGS_ENTRY(pos, LINUX_AT_SECURE, 0);
277	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
278	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
279	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
280	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
281	AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
282	if (args->execfd != -1)
283		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
284	AUXARGS_ENTRY(pos, AT_NULL, 0);
285
286	free(imgp->auxargs, M_TEMP);
287	imgp->auxargs = NULL;
288
289	(*stack_base)--;
290	suword(*stack_base, (register_t)imgp->args->argc);
291	return (0);
292}
293
294/*
295 * Copied from kern/kern_exec.c
296 */
297static register_t *
298linux_copyout_strings(struct image_params *imgp)
299{
300	int argc, envc;
301	char **vectp;
302	char *stringp, *destp;
303	register_t *stack_base;
304	struct ps_strings *arginfo;
305	struct proc *p;
306
307	/*
308	 * Calculate string base and vector table pointers.
309	 * Also deal with signal trampoline code for this exec type.
310	 */
311	p = imgp->proc;
312	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
313	destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
314	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
315
316	/*
317	 * install LINUX_PLATFORM
318	 */
319	copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform),
320	    linux_szplatform);
321
322	/*
323	 * If we have a valid auxargs ptr, prepare some room
324	 * on the stack.
325	 */
326	if (imgp->auxargs) {
327		/*
328		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
329		 * lower compatibility.
330		 */
331		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size :
332		    (LINUX_AT_COUNT * 2);
333		/*
334		 * The '+ 2' is for the null pointers at the end of each of
335		 * the arg and env vector sets,and imgp->auxarg_size is room
336		 * for argument of Runtime loader.
337		 */
338		vectp = (char **)(destp - (imgp->args->argc +
339		    imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *));
340	} else {
341		/*
342		 * The '+ 2' is for the null pointers at the end of each of
343		 * the arg and env vector sets
344		 */
345		vectp = (char **)(destp - (imgp->args->argc + imgp->args->envc + 2) *
346		    sizeof(char *));
347	}
348
349	/*
350	 * vectp also becomes our initial stack base
351	 */
352	stack_base = (register_t *)vectp;
353
354	stringp = imgp->args->begin_argv;
355	argc = imgp->args->argc;
356	envc = imgp->args->envc;
357
358	/*
359	 * Copy out strings - arguments and environment.
360	 */
361	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
362
363	/*
364	 * Fill in "ps_strings" struct for ps, w, etc.
365	 */
366	suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
367	suword(&arginfo->ps_nargvstr, argc);
368
369	/*
370	 * Fill in argument portion of vector table.
371	 */
372	for (; argc > 0; --argc) {
373		suword(vectp++, (long)(intptr_t)destp);
374		while (*stringp++ != 0)
375			destp++;
376		destp++;
377	}
378
379	/* a null vector table pointer separates the argp's from the envp's */
380	suword(vectp++, 0);
381
382	suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
383	suword(&arginfo->ps_nenvstr, envc);
384
385	/*
386	 * Fill in environment portion of vector table.
387	 */
388	for (; envc > 0; --envc) {
389		suword(vectp++, (long)(intptr_t)destp);
390		while (*stringp++ != 0)
391			destp++;
392		destp++;
393	}
394
395	/* end of vector table is a null pointer */
396	suword(vectp, 0);
397
398	return (stack_base);
399}
400
401
402
403extern int _ucodesel, _udatasel;
404extern unsigned long linux_sznonrtsigcode;
405
406static void
407linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
408{
409	struct thread *td = curthread;
410	struct proc *p = td->td_proc;
411	struct sigacts *psp;
412	struct trapframe *regs;
413	struct l_rt_sigframe *fp, frame;
414	int sig, code;
415	int oonstack;
416
417	sig = ksi->ksi_signo;
418	code = ksi->ksi_code;
419	PROC_LOCK_ASSERT(p, MA_OWNED);
420	psp = p->p_sigacts;
421	mtx_assert(&psp->ps_mtx, MA_OWNED);
422	regs = td->td_frame;
423	oonstack = sigonstack(regs->tf_esp);
424
425#ifdef DEBUG
426	if (ldebug(rt_sendsig))
427		printf(ARGS(rt_sendsig, "%p, %d, %p, %u"),
428		    catcher, sig, (void*)mask, code);
429#endif
430	/*
431	 * Allocate space for the signal handler context.
432	 */
433	if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
434	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
435		fp = (struct l_rt_sigframe *)(td->td_sigstk.ss_sp +
436		    td->td_sigstk.ss_size - sizeof(struct l_rt_sigframe));
437	} else
438		fp = (struct l_rt_sigframe *)regs->tf_esp - 1;
439	mtx_unlock(&psp->ps_mtx);
440
441	/*
442	 * Build the argument list for the signal handler.
443	 */
444	if (p->p_sysent->sv_sigtbl)
445		if (sig <= p->p_sysent->sv_sigsize)
446			sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
447
448	bzero(&frame, sizeof(frame));
449
450	frame.sf_handler = catcher;
451	frame.sf_sig = sig;
452	frame.sf_siginfo = &fp->sf_si;
453	frame.sf_ucontext = &fp->sf_sc;
454
455	/* Fill in POSIX parts */
456	ksiginfo_to_lsiginfo(ksi, &frame.sf_si, sig);
457
458	/*
459	 * Build the signal context to be used by sigreturn.
460	 */
461	frame.sf_sc.uc_flags = 0;		/* XXX ??? */
462	frame.sf_sc.uc_link = NULL;		/* XXX ??? */
463
464	frame.sf_sc.uc_stack.ss_sp = td->td_sigstk.ss_sp;
465	frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
466	frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
467	    ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
468	PROC_UNLOCK(p);
469
470	bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
471
472	frame.sf_sc.uc_mcontext.sc_mask   = frame.sf_sc.uc_sigmask.__bits[0];
473	frame.sf_sc.uc_mcontext.sc_gs     = rgs();
474	frame.sf_sc.uc_mcontext.sc_fs     = regs->tf_fs;
475	frame.sf_sc.uc_mcontext.sc_es     = regs->tf_es;
476	frame.sf_sc.uc_mcontext.sc_ds     = regs->tf_ds;
477	frame.sf_sc.uc_mcontext.sc_edi    = regs->tf_edi;
478	frame.sf_sc.uc_mcontext.sc_esi    = regs->tf_esi;
479	frame.sf_sc.uc_mcontext.sc_ebp    = regs->tf_ebp;
480	frame.sf_sc.uc_mcontext.sc_ebx    = regs->tf_ebx;
481	frame.sf_sc.uc_mcontext.sc_edx    = regs->tf_edx;
482	frame.sf_sc.uc_mcontext.sc_ecx    = regs->tf_ecx;
483	frame.sf_sc.uc_mcontext.sc_eax    = regs->tf_eax;
484	frame.sf_sc.uc_mcontext.sc_eip    = regs->tf_eip;
485	frame.sf_sc.uc_mcontext.sc_cs     = regs->tf_cs;
486	frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags;
487	frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp;
488	frame.sf_sc.uc_mcontext.sc_ss     = regs->tf_ss;
489	frame.sf_sc.uc_mcontext.sc_err    = regs->tf_err;
490	frame.sf_sc.uc_mcontext.sc_cr2    = (register_t)ksi->ksi_addr;
491	frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
492
493#ifdef DEBUG
494	if (ldebug(rt_sendsig))
495		printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
496		    frame.sf_sc.uc_stack.ss_flags, td->td_sigstk.ss_sp,
497		    td->td_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
498#endif
499
500	if (copyout(&frame, fp, sizeof(frame)) != 0) {
501		/*
502		 * Process has trashed its stack; give it an illegal
503		 * instruction to halt it in its tracks.
504		 */
505#ifdef DEBUG
506		if (ldebug(rt_sendsig))
507			printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"),
508			    fp, oonstack);
509#endif
510		PROC_LOCK(p);
511		sigexit(td, SIGILL);
512	}
513
514	/*
515	 * Build context to run handler in.
516	 */
517	regs->tf_esp = (int)fp;
518	regs->tf_eip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode;
519	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
520	regs->tf_cs = _ucodesel;
521	regs->tf_ds = _udatasel;
522	regs->tf_es = _udatasel;
523	regs->tf_fs = _udatasel;
524	regs->tf_ss = _udatasel;
525	PROC_LOCK(p);
526	mtx_lock(&psp->ps_mtx);
527}
528
529
530/*
531 * Send an interrupt to process.
532 *
533 * Stack is set up to allow sigcode stored
534 * in u. to call routine, followed by kcall
535 * to sigreturn routine below.  After sigreturn
536 * resets the signal mask, the stack, and the
537 * frame pointer, it returns to the user
538 * specified pc, psl.
539 */
540static void
541linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
542{
543	struct thread *td = curthread;
544	struct proc *p = td->td_proc;
545	struct sigacts *psp;
546	struct trapframe *regs;
547	struct l_sigframe *fp, frame;
548	l_sigset_t lmask;
549	int sig, code;
550	int oonstack, i;
551
552	PROC_LOCK_ASSERT(p, MA_OWNED);
553	psp = p->p_sigacts;
554	sig = ksi->ksi_signo;
555	code = ksi->ksi_code;
556	mtx_assert(&psp->ps_mtx, MA_OWNED);
557	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
558		/* Signal handler installed with SA_SIGINFO. */
559		linux_rt_sendsig(catcher, ksi, mask);
560		return;
561	}
562	regs = td->td_frame;
563	oonstack = sigonstack(regs->tf_esp);
564
565#ifdef DEBUG
566	if (ldebug(sendsig))
567		printf(ARGS(sendsig, "%p, %d, %p, %u"),
568		    catcher, sig, (void*)mask, code);
569#endif
570
571	/*
572	 * Allocate space for the signal handler context.
573	 */
574	if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
575	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
576		fp = (struct l_sigframe *)(td->td_sigstk.ss_sp +
577		    td->td_sigstk.ss_size - sizeof(struct l_sigframe));
578	} else
579		fp = (struct l_sigframe *)regs->tf_esp - 1;
580	mtx_unlock(&psp->ps_mtx);
581	PROC_UNLOCK(p);
582
583	/*
584	 * Build the argument list for the signal handler.
585	 */
586	if (p->p_sysent->sv_sigtbl)
587		if (sig <= p->p_sysent->sv_sigsize)
588			sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
589
590	bzero(&frame, sizeof(frame));
591
592	frame.sf_handler = catcher;
593	frame.sf_sig = sig;
594
595	bsd_to_linux_sigset(mask, &lmask);
596
597	/*
598	 * Build the signal context to be used by sigreturn.
599	 */
600	frame.sf_sc.sc_mask   = lmask.__bits[0];
601	frame.sf_sc.sc_gs     = rgs();
602	frame.sf_sc.sc_fs     = regs->tf_fs;
603	frame.sf_sc.sc_es     = regs->tf_es;
604	frame.sf_sc.sc_ds     = regs->tf_ds;
605	frame.sf_sc.sc_edi    = regs->tf_edi;
606	frame.sf_sc.sc_esi    = regs->tf_esi;
607	frame.sf_sc.sc_ebp    = regs->tf_ebp;
608	frame.sf_sc.sc_ebx    = regs->tf_ebx;
609	frame.sf_sc.sc_edx    = regs->tf_edx;
610	frame.sf_sc.sc_ecx    = regs->tf_ecx;
611	frame.sf_sc.sc_eax    = regs->tf_eax;
612	frame.sf_sc.sc_eip    = regs->tf_eip;
613	frame.sf_sc.sc_cs     = regs->tf_cs;
614	frame.sf_sc.sc_eflags = regs->tf_eflags;
615	frame.sf_sc.sc_esp_at_signal = regs->tf_esp;
616	frame.sf_sc.sc_ss     = regs->tf_ss;
617	frame.sf_sc.sc_err    = regs->tf_err;
618	frame.sf_sc.sc_cr2    = (register_t)ksi->ksi_addr;
619	frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno);
620
621	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
622		frame.sf_extramask[i] = lmask.__bits[i+1];
623
624	if (copyout(&frame, fp, sizeof(frame)) != 0) {
625		/*
626		 * Process has trashed its stack; give it an illegal
627		 * instruction to halt it in its tracks.
628		 */
629		PROC_LOCK(p);
630		sigexit(td, SIGILL);
631	}
632
633	/*
634	 * Build context to run handler in.
635	 */
636	regs->tf_esp = (int)fp;
637	regs->tf_eip = p->p_sysent->sv_sigcode_base;
638	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
639	regs->tf_cs = _ucodesel;
640	regs->tf_ds = _udatasel;
641	regs->tf_es = _udatasel;
642	regs->tf_fs = _udatasel;
643	regs->tf_ss = _udatasel;
644	PROC_LOCK(p);
645	mtx_lock(&psp->ps_mtx);
646}
647
648/*
649 * System call to cleanup state after a signal
650 * has been taken.  Reset signal mask and
651 * stack state from context left by sendsig (above).
652 * Return to previous pc and psl as specified by
653 * context left by sendsig. Check carefully to
654 * make sure that the user has not modified the
655 * psl to gain improper privileges or to cause
656 * a machine fault.
657 */
658int
659linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
660{
661	struct l_sigframe frame;
662	struct trapframe *regs;
663	l_sigset_t lmask;
664	sigset_t bmask;
665	int eflags, i;
666	ksiginfo_t ksi;
667
668	regs = td->td_frame;
669
670#ifdef DEBUG
671	if (ldebug(sigreturn))
672		printf(ARGS(sigreturn, "%p"), (void *)args->sfp);
673#endif
674	/*
675	 * The trampoline code hands us the sigframe.
676	 * It is unsafe to keep track of it ourselves, in the event that a
677	 * program jumps out of a signal handler.
678	 */
679	if (copyin(args->sfp, &frame, sizeof(frame)) != 0)
680		return (EFAULT);
681
682	/*
683	 * Check for security violations.
684	 */
685#define	EFLAGS_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
686	eflags = frame.sf_sc.sc_eflags;
687	if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
688		return(EINVAL);
689
690	/*
691	 * Don't allow users to load a valid privileged %cs.  Let the
692	 * hardware check for invalid selectors, excess privilege in
693	 * other selectors, invalid %eip's and invalid %esp's.
694	 */
695#define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
696	if (!CS_SECURE(frame.sf_sc.sc_cs)) {
697		ksiginfo_init_trap(&ksi);
698		ksi.ksi_signo = SIGBUS;
699		ksi.ksi_code = BUS_OBJERR;
700		ksi.ksi_trapno = T_PROTFLT;
701		ksi.ksi_addr = (void *)regs->tf_eip;
702		trapsignal(td, &ksi);
703		return(EINVAL);
704	}
705
706	lmask.__bits[0] = frame.sf_sc.sc_mask;
707	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
708		lmask.__bits[i+1] = frame.sf_extramask[i];
709	linux_to_bsd_sigset(&lmask, &bmask);
710	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
711
712	/*
713	 * Restore signal context.
714	 */
715	/* %gs was restored by the trampoline. */
716	regs->tf_fs     = frame.sf_sc.sc_fs;
717	regs->tf_es     = frame.sf_sc.sc_es;
718	regs->tf_ds     = frame.sf_sc.sc_ds;
719	regs->tf_edi    = frame.sf_sc.sc_edi;
720	regs->tf_esi    = frame.sf_sc.sc_esi;
721	regs->tf_ebp    = frame.sf_sc.sc_ebp;
722	regs->tf_ebx    = frame.sf_sc.sc_ebx;
723	regs->tf_edx    = frame.sf_sc.sc_edx;
724	regs->tf_ecx    = frame.sf_sc.sc_ecx;
725	regs->tf_eax    = frame.sf_sc.sc_eax;
726	regs->tf_eip    = frame.sf_sc.sc_eip;
727	regs->tf_cs     = frame.sf_sc.sc_cs;
728	regs->tf_eflags = eflags;
729	regs->tf_esp    = frame.sf_sc.sc_esp_at_signal;
730	regs->tf_ss     = frame.sf_sc.sc_ss;
731
732	return (EJUSTRETURN);
733}
734
735/*
736 * System call to cleanup state after a signal
737 * has been taken.  Reset signal mask and
738 * stack state from context left by rt_sendsig (above).
739 * Return to previous pc and psl as specified by
740 * context left by sendsig. Check carefully to
741 * make sure that the user has not modified the
742 * psl to gain improper privileges or to cause
743 * a machine fault.
744 */
745int
746linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
747{
748	struct l_ucontext uc;
749	struct l_sigcontext *context;
750	sigset_t bmask;
751	l_stack_t *lss;
752	stack_t ss;
753	struct trapframe *regs;
754	int eflags;
755	ksiginfo_t ksi;
756
757	regs = td->td_frame;
758
759#ifdef DEBUG
760	if (ldebug(rt_sigreturn))
761		printf(ARGS(rt_sigreturn, "%p"), (void *)args->ucp);
762#endif
763	/*
764	 * The trampoline code hands us the ucontext.
765	 * It is unsafe to keep track of it ourselves, in the event that a
766	 * program jumps out of a signal handler.
767	 */
768	if (copyin(args->ucp, &uc, sizeof(uc)) != 0)
769		return (EFAULT);
770
771	context = &uc.uc_mcontext;
772
773	/*
774	 * Check for security violations.
775	 */
776#define	EFLAGS_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
777	eflags = context->sc_eflags;
778	if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
779		return(EINVAL);
780
781	/*
782	 * Don't allow users to load a valid privileged %cs.  Let the
783	 * hardware check for invalid selectors, excess privilege in
784	 * other selectors, invalid %eip's and invalid %esp's.
785	 */
786#define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
787	if (!CS_SECURE(context->sc_cs)) {
788		ksiginfo_init_trap(&ksi);
789		ksi.ksi_signo = SIGBUS;
790		ksi.ksi_code = BUS_OBJERR;
791		ksi.ksi_trapno = T_PROTFLT;
792		ksi.ksi_addr = (void *)regs->tf_eip;
793		trapsignal(td, &ksi);
794		return(EINVAL);
795	}
796
797	linux_to_bsd_sigset(&uc.uc_sigmask, &bmask);
798	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
799
800	/*
801	 * Restore signal context
802	 */
803	/* %gs was restored by the trampoline. */
804	regs->tf_fs     = context->sc_fs;
805	regs->tf_es     = context->sc_es;
806	regs->tf_ds     = context->sc_ds;
807	regs->tf_edi    = context->sc_edi;
808	regs->tf_esi    = context->sc_esi;
809	regs->tf_ebp    = context->sc_ebp;
810	regs->tf_ebx    = context->sc_ebx;
811	regs->tf_edx    = context->sc_edx;
812	regs->tf_ecx    = context->sc_ecx;
813	regs->tf_eax    = context->sc_eax;
814	regs->tf_eip    = context->sc_eip;
815	regs->tf_cs     = context->sc_cs;
816	regs->tf_eflags = eflags;
817	regs->tf_esp    = context->sc_esp_at_signal;
818	regs->tf_ss     = context->sc_ss;
819
820	/*
821	 * call sigaltstack & ignore results..
822	 */
823	lss = &uc.uc_stack;
824	ss.ss_sp = lss->ss_sp;
825	ss.ss_size = lss->ss_size;
826	ss.ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags);
827
828#ifdef DEBUG
829	if (ldebug(rt_sigreturn))
830		printf(LMSG("rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
831		    ss.ss_flags, ss.ss_sp, ss.ss_size, context->sc_mask);
832#endif
833	(void)kern_sigaltstack(td, &ss, NULL);
834
835	return (EJUSTRETURN);
836}
837
838static int
839linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
840{
841	struct proc *p;
842	struct trapframe *frame;
843
844	p = td->td_proc;
845	frame = td->td_frame;
846
847	sa->code = frame->tf_eax;
848	sa->args[0] = frame->tf_ebx;
849	sa->args[1] = frame->tf_ecx;
850	sa->args[2] = frame->tf_edx;
851	sa->args[3] = frame->tf_esi;
852	sa->args[4] = frame->tf_edi;
853	sa->args[5] = frame->tf_ebp;	/* Unconfirmed */
854
855	if (sa->code >= p->p_sysent->sv_size)
856		sa->callp = &p->p_sysent->sv_table[0];
857 	else
858 		sa->callp = &p->p_sysent->sv_table[sa->code];
859	sa->narg = sa->callp->sy_narg;
860
861	td->td_retval[0] = 0;
862	td->td_retval[1] = frame->tf_edx;
863
864	return (0);
865}
866
867/*
868 * If a linux binary is exec'ing something, try this image activator
869 * first.  We override standard shell script execution in order to
870 * be able to modify the interpreter path.  We only do this if a linux
871 * binary is doing the exec, so we do not create an EXEC module for it.
872 */
873static int	exec_linux_imgact_try(struct image_params *iparams);
874
875static int
876exec_linux_imgact_try(struct image_params *imgp)
877{
878    const char *head = (const char *)imgp->image_header;
879    char *rpath;
880    int error = -1;
881
882    /*
883     * The interpreter for shell scripts run from a linux binary needs
884     * to be located in /compat/linux if possible in order to recursively
885     * maintain linux path emulation.
886     */
887    if (((const short *)head)[0] == SHELLMAGIC) {
888	    /*
889	     * Run our normal shell image activator.  If it succeeds attempt
890	     * to use the alternate path for the interpreter.  If an alternate
891	     * path is found, use our stringspace to store it.
892	     */
893	    if ((error = exec_shell_imgact(imgp)) == 0) {
894		    linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
895			imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD);
896		    if (rpath != NULL)
897			    imgp->args->fname_buf =
898				imgp->interpreter_name = rpath;
899	    }
900    }
901    return (error);
902}
903
904/*
905 * exec_setregs may initialize some registers differently than Linux
906 * does, thus potentially confusing Linux binaries. If necessary, we
907 * override the exec_setregs default(s) here.
908 */
909static void
910exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack)
911{
912	struct pcb *pcb = td->td_pcb;
913
914	exec_setregs(td, imgp, stack);
915
916	/* Linux sets %gs to 0, we default to _udatasel */
917	pcb->pcb_gs = 0;
918	load_gs(0);
919
920	pcb->pcb_initial_npxcw = __LINUX_NPXCW__;
921}
922
923static void
924linux_get_machine(const char **dst)
925{
926
927	switch (cpu_class) {
928	case CPUCLASS_686:
929		*dst = "i686";
930		break;
931	case CPUCLASS_586:
932		*dst = "i586";
933		break;
934	case CPUCLASS_486:
935		*dst = "i486";
936		break;
937	default:
938		*dst = "i386";
939	}
940}
941
942struct sysentvec linux_sysvec = {
943	.sv_size	= LINUX_SYS_MAXSYSCALL,
944	.sv_table	= linux_sysent,
945	.sv_mask	= 0,
946	.sv_sigsize	= LINUX_SIGTBLSZ,
947	.sv_sigtbl	= bsd_to_linux_signal,
948	.sv_errsize	= ELAST + 1,
949	.sv_errtbl	= bsd_to_linux_errno,
950	.sv_transtrap	= translate_traps,
951	.sv_fixup	= linux_fixup,
952	.sv_sendsig	= linux_sendsig,
953	.sv_sigcode	= linux_sigcode,
954	.sv_szsigcode	= &linux_szsigcode,
955	.sv_prepsyscall	= NULL,
956	.sv_name	= "Linux a.out",
957	.sv_coredump	= NULL,
958	.sv_imgact_try	= exec_linux_imgact_try,
959	.sv_minsigstksz	= LINUX_MINSIGSTKSZ,
960	.sv_pagesize	= PAGE_SIZE,
961	.sv_minuser	= VM_MIN_ADDRESS,
962	.sv_maxuser	= VM_MAXUSER_ADDRESS,
963	.sv_usrstack	= LINUX_USRSTACK,
964	.sv_psstrings	= PS_STRINGS,
965	.sv_stackprot	= VM_PROT_ALL,
966	.sv_copyout_strings = exec_copyout_strings,
967	.sv_setregs	= exec_linux_setregs,
968	.sv_fixlimit	= NULL,
969	.sv_maxssiz	= NULL,
970	.sv_flags	= SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32,
971	.sv_set_syscall_retval = cpu_set_syscall_retval,
972	.sv_fetch_syscall_args = linux_fetch_syscall_args,
973	.sv_syscallnames = NULL,
974	.sv_shared_page_base = LINUX_SHAREDPAGE,
975	.sv_shared_page_len = PAGE_SIZE,
976	.sv_schedtail	= linux_schedtail,
977};
978INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
979
980struct sysentvec elf_linux_sysvec = {
981	.sv_size	= LINUX_SYS_MAXSYSCALL,
982	.sv_table	= linux_sysent,
983	.sv_mask	= 0,
984	.sv_sigsize	= LINUX_SIGTBLSZ,
985	.sv_sigtbl	= bsd_to_linux_signal,
986	.sv_errsize	= ELAST + 1,
987	.sv_errtbl	= bsd_to_linux_errno,
988	.sv_transtrap	= translate_traps,
989	.sv_fixup	= elf_linux_fixup,
990	.sv_sendsig	= linux_sendsig,
991	.sv_sigcode	= linux_sigcode,
992	.sv_szsigcode	= &linux_szsigcode,
993	.sv_prepsyscall	= NULL,
994	.sv_name	= "Linux ELF",
995	.sv_coredump	= elf32_coredump,
996	.sv_imgact_try	= exec_linux_imgact_try,
997	.sv_minsigstksz	= LINUX_MINSIGSTKSZ,
998	.sv_pagesize	= PAGE_SIZE,
999	.sv_minuser	= VM_MIN_ADDRESS,
1000	.sv_maxuser	= VM_MAXUSER_ADDRESS,
1001	.sv_usrstack	= LINUX_USRSTACK,
1002	.sv_psstrings	= LINUX_PS_STRINGS,
1003	.sv_stackprot	= VM_PROT_ALL,
1004	.sv_copyout_strings = linux_copyout_strings,
1005	.sv_setregs	= exec_linux_setregs,
1006	.sv_fixlimit	= NULL,
1007	.sv_maxssiz	= NULL,
1008	.sv_flags	= SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP,
1009	.sv_set_syscall_retval = cpu_set_syscall_retval,
1010	.sv_fetch_syscall_args = linux_fetch_syscall_args,
1011	.sv_syscallnames = NULL,
1012	.sv_shared_page_base = LINUX_SHAREDPAGE,
1013	.sv_shared_page_len = PAGE_SIZE,
1014	.sv_schedtail	= linux_schedtail,
1015};
1016INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
1017
1018static char GNU_ABI_VENDOR[] = "GNU";
1019static int GNULINUX_ABI_DESC = 0;
1020
1021static boolean_t
1022linux_trans_osrel(const Elf_Note *note, int32_t *osrel)
1023{
1024	const Elf32_Word *desc;
1025	uintptr_t p;
1026
1027	p = (uintptr_t)(note + 1);
1028	p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
1029
1030	desc = (const Elf32_Word *)p;
1031	if (desc[0] != GNULINUX_ABI_DESC)
1032		return (FALSE);
1033
1034	/*
1035	 * For linux we encode osrel as follows (see linux_mib.c):
1036	 * VVVMMMIII (version, major, minor), see linux_mib.c.
1037	 */
1038	*osrel = desc[1] * 1000000 + desc[2] * 1000 + desc[3];
1039
1040	return (TRUE);
1041}
1042
1043static Elf_Brandnote linux_brandnote = {
1044	.hdr.n_namesz	= sizeof(GNU_ABI_VENDOR),
1045	.hdr.n_descsz	= 16,	/* XXX at least 16 */
1046	.hdr.n_type	= 1,
1047	.vendor		= GNU_ABI_VENDOR,
1048	.flags		= BN_TRANSLATE_OSREL,
1049	.trans_osrel	= linux_trans_osrel
1050};
1051
1052static Elf32_Brandinfo linux_brand = {
1053	.brand		= ELFOSABI_LINUX,
1054	.machine	= EM_386,
1055	.compat_3_brand	= "Linux",
1056	.emul_path	= "/compat/linux",
1057	.interp_path	= "/lib/ld-linux.so.1",
1058	.sysvec		= &elf_linux_sysvec,
1059	.interp_newpath	= NULL,
1060	.brand_note	= &linux_brandnote,
1061	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
1062};
1063
1064static Elf32_Brandinfo linux_glibc2brand = {
1065	.brand		= ELFOSABI_LINUX,
1066	.machine	= EM_386,
1067	.compat_3_brand	= "Linux",
1068	.emul_path	= "/compat/linux",
1069	.interp_path	= "/lib/ld-linux.so.2",
1070	.sysvec		= &elf_linux_sysvec,
1071	.interp_newpath	= NULL,
1072	.brand_note	= &linux_brandnote,
1073	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
1074};
1075
1076Elf32_Brandinfo *linux_brandlist[] = {
1077	&linux_brand,
1078	&linux_glibc2brand,
1079	NULL
1080};
1081
1082static int
1083linux_elf_modevent(module_t mod, int type, void *data)
1084{
1085	Elf32_Brandinfo **brandinfo;
1086	int error;
1087	struct linux_ioctl_handler **lihp;
1088	struct linux_device_handler **ldhp;
1089
1090	error = 0;
1091
1092	switch(type) {
1093	case MOD_LOAD:
1094		for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
1095		     ++brandinfo)
1096			if (elf32_insert_brand_entry(*brandinfo) < 0)
1097				error = EINVAL;
1098		if (error == 0) {
1099			SET_FOREACH(lihp, linux_ioctl_handler_set)
1100				linux_ioctl_register_handler(*lihp);
1101			SET_FOREACH(ldhp, linux_device_handler_set)
1102				linux_device_register_handler(*ldhp);
1103			mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
1104			sx_init(&emul_shared_lock, "emuldata->shared lock");
1105			LIST_INIT(&futex_list);
1106			mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
1107			linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
1108			      NULL, 1000);
1109			linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
1110			      NULL, 1000);
1111			linux_get_machine(&linux_platform);
1112			linux_szplatform = roundup(strlen(linux_platform) + 1,
1113			    sizeof(char *));
1114			linux_osd_jail_register();
1115			stclohz = (stathz ? stathz : hz);
1116			if (bootverbose)
1117				printf("Linux ELF exec handler installed\n");
1118		} else
1119			printf("cannot insert Linux ELF brand handler\n");
1120		break;
1121	case MOD_UNLOAD:
1122		for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
1123		     ++brandinfo)
1124			if (elf32_brand_inuse(*brandinfo))
1125				error = EBUSY;
1126		if (error == 0) {
1127			for (brandinfo = &linux_brandlist[0];
1128			     *brandinfo != NULL; ++brandinfo)
1129				if (elf32_remove_brand_entry(*brandinfo) < 0)
1130					error = EINVAL;
1131		}
1132		if (error == 0) {
1133			SET_FOREACH(lihp, linux_ioctl_handler_set)
1134				linux_ioctl_unregister_handler(*lihp);
1135			SET_FOREACH(ldhp, linux_device_handler_set)
1136				linux_device_unregister_handler(*ldhp);
1137			mtx_destroy(&emul_lock);
1138			sx_destroy(&emul_shared_lock);
1139			mtx_destroy(&futex_mtx);
1140			EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
1141			EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
1142			linux_osd_jail_deregister();
1143			if (bootverbose)
1144				printf("Linux ELF exec handler removed\n");
1145		} else
1146			printf("Could not deinstall ELF interpreter entry\n");
1147		break;
1148	default:
1149		return EOPNOTSUPP;
1150	}
1151	return error;
1152}
1153
1154static moduledata_t linux_elf_mod = {
1155	"linuxelf",
1156	linux_elf_modevent,
1157	0
1158};
1159
1160DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
1161