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$");
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	int issetugid;
248
249	KASSERT(curthread->td_proc == imgp->proc,
250	    ("unsafe elf_linux_fixup(), should be curproc"));
251
252	p = imgp->proc;
253	issetugid = imgp->proc->p_flag & P_SUGID ? 1 : 0;
254	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
255	uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);
256	args = (Elf32_Auxargs *)imgp->auxargs;
257	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
258
259	AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
260
261	/*
262	 * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0,
263	 * as it has appeared in the 2.4.0-rc7 first time.
264	 * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK),
265	 * glibc falls back to the hard-coded CLK_TCK value when aux entry
266	 * is not present.
267	 * Also see linux_times() implementation.
268	 */
269	if (linux_kernver(curthread) >= LINUX_KERNVER_2004000)
270		AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
271	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
272	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
273	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
274	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
275	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
276	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
277	AUXARGS_ENTRY(pos, AT_BASE, args->base);
278	AUXARGS_ENTRY(pos, LINUX_AT_SECURE, issetugid);
279	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
280	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
281	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
282	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
283	AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
284	if (args->execfd != -1)
285		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
286	AUXARGS_ENTRY(pos, AT_NULL, 0);
287
288	free(imgp->auxargs, M_TEMP);
289	imgp->auxargs = NULL;
290
291	(*stack_base)--;
292	suword(*stack_base, (register_t)imgp->args->argc);
293	return (0);
294}
295
296/*
297 * Copied from kern/kern_exec.c
298 */
299static register_t *
300linux_copyout_strings(struct image_params *imgp)
301{
302	int argc, envc;
303	char **vectp;
304	char *stringp, *destp;
305	register_t *stack_base;
306	struct ps_strings *arginfo;
307	struct proc *p;
308
309	/*
310	 * Calculate string base and vector table pointers.
311	 * Also deal with signal trampoline code for this exec type.
312	 */
313	p = imgp->proc;
314	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
315	destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
316	    roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
317
318	/*
319	 * install LINUX_PLATFORM
320	 */
321	copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform),
322	    linux_szplatform);
323
324	/*
325	 * If we have a valid auxargs ptr, prepare some room
326	 * on the stack.
327	 */
328	if (imgp->auxargs) {
329		/*
330		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
331		 * lower compatibility.
332		 */
333		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size :
334		    (LINUX_AT_COUNT * 2);
335		/*
336		 * The '+ 2' is for the null pointers at the end of each of
337		 * the arg and env vector sets,and imgp->auxarg_size is room
338		 * for argument of Runtime loader.
339		 */
340		vectp = (char **)(destp - (imgp->args->argc +
341		    imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *));
342	} else {
343		/*
344		 * The '+ 2' is for the null pointers at the end of each of
345		 * the arg and env vector sets
346		 */
347		vectp = (char **)(destp - (imgp->args->argc + imgp->args->envc + 2) *
348		    sizeof(char *));
349	}
350
351	/*
352	 * vectp also becomes our initial stack base
353	 */
354	stack_base = (register_t *)vectp;
355
356	stringp = imgp->args->begin_argv;
357	argc = imgp->args->argc;
358	envc = imgp->args->envc;
359
360	/*
361	 * Copy out strings - arguments and environment.
362	 */
363	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
364
365	/*
366	 * Fill in "ps_strings" struct for ps, w, etc.
367	 */
368	suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
369	suword(&arginfo->ps_nargvstr, argc);
370
371	/*
372	 * Fill in argument portion of vector table.
373	 */
374	for (; argc > 0; --argc) {
375		suword(vectp++, (long)(intptr_t)destp);
376		while (*stringp++ != 0)
377			destp++;
378		destp++;
379	}
380
381	/* a null vector table pointer separates the argp's from the envp's */
382	suword(vectp++, 0);
383
384	suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
385	suword(&arginfo->ps_nenvstr, envc);
386
387	/*
388	 * Fill in environment portion of vector table.
389	 */
390	for (; envc > 0; --envc) {
391		suword(vectp++, (long)(intptr_t)destp);
392		while (*stringp++ != 0)
393			destp++;
394		destp++;
395	}
396
397	/* end of vector table is a null pointer */
398	suword(vectp, 0);
399
400	return (stack_base);
401}
402
403
404
405extern int _ucodesel, _udatasel;
406extern unsigned long linux_sznonrtsigcode;
407
408static void
409linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
410{
411	struct thread *td = curthread;
412	struct proc *p = td->td_proc;
413	struct sigacts *psp;
414	struct trapframe *regs;
415	struct l_rt_sigframe *fp, frame;
416	int sig, code;
417	int oonstack;
418
419	sig = ksi->ksi_signo;
420	code = ksi->ksi_code;
421	PROC_LOCK_ASSERT(p, MA_OWNED);
422	psp = p->p_sigacts;
423	mtx_assert(&psp->ps_mtx, MA_OWNED);
424	regs = td->td_frame;
425	oonstack = sigonstack(regs->tf_esp);
426
427#ifdef DEBUG
428	if (ldebug(rt_sendsig))
429		printf(ARGS(rt_sendsig, "%p, %d, %p, %u"),
430		    catcher, sig, (void*)mask, code);
431#endif
432	/*
433	 * Allocate space for the signal handler context.
434	 */
435	if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
436	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
437		fp = (struct l_rt_sigframe *)(td->td_sigstk.ss_sp +
438		    td->td_sigstk.ss_size - sizeof(struct l_rt_sigframe));
439	} else
440		fp = (struct l_rt_sigframe *)regs->tf_esp - 1;
441	mtx_unlock(&psp->ps_mtx);
442
443	/*
444	 * Build the argument list for the signal handler.
445	 */
446	if (p->p_sysent->sv_sigtbl)
447		if (sig <= p->p_sysent->sv_sigsize)
448			sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
449
450	bzero(&frame, sizeof(frame));
451
452	frame.sf_handler = catcher;
453	frame.sf_sig = sig;
454	frame.sf_siginfo = &fp->sf_si;
455	frame.sf_ucontext = &fp->sf_sc;
456
457	/* Fill in POSIX parts */
458	ksiginfo_to_lsiginfo(ksi, &frame.sf_si, sig);
459
460	/*
461	 * Build the signal context to be used by sigreturn.
462	 */
463	frame.sf_sc.uc_flags = 0;		/* XXX ??? */
464	frame.sf_sc.uc_link = NULL;		/* XXX ??? */
465
466	frame.sf_sc.uc_stack.ss_sp = td->td_sigstk.ss_sp;
467	frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
468	frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
469	    ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
470	PROC_UNLOCK(p);
471
472	bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
473
474	frame.sf_sc.uc_mcontext.sc_mask   = frame.sf_sc.uc_sigmask.__bits[0];
475	frame.sf_sc.uc_mcontext.sc_gs     = rgs();
476	frame.sf_sc.uc_mcontext.sc_fs     = regs->tf_fs;
477	frame.sf_sc.uc_mcontext.sc_es     = regs->tf_es;
478	frame.sf_sc.uc_mcontext.sc_ds     = regs->tf_ds;
479	frame.sf_sc.uc_mcontext.sc_edi    = regs->tf_edi;
480	frame.sf_sc.uc_mcontext.sc_esi    = regs->tf_esi;
481	frame.sf_sc.uc_mcontext.sc_ebp    = regs->tf_ebp;
482	frame.sf_sc.uc_mcontext.sc_ebx    = regs->tf_ebx;
483	frame.sf_sc.uc_mcontext.sc_edx    = regs->tf_edx;
484	frame.sf_sc.uc_mcontext.sc_ecx    = regs->tf_ecx;
485	frame.sf_sc.uc_mcontext.sc_eax    = regs->tf_eax;
486	frame.sf_sc.uc_mcontext.sc_eip    = regs->tf_eip;
487	frame.sf_sc.uc_mcontext.sc_cs     = regs->tf_cs;
488	frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags;
489	frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp;
490	frame.sf_sc.uc_mcontext.sc_ss     = regs->tf_ss;
491	frame.sf_sc.uc_mcontext.sc_err    = regs->tf_err;
492	frame.sf_sc.uc_mcontext.sc_cr2    = (register_t)ksi->ksi_addr;
493	frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
494
495#ifdef DEBUG
496	if (ldebug(rt_sendsig))
497		printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
498		    frame.sf_sc.uc_stack.ss_flags, td->td_sigstk.ss_sp,
499		    td->td_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
500#endif
501
502	if (copyout(&frame, fp, sizeof(frame)) != 0) {
503		/*
504		 * Process has trashed its stack; give it an illegal
505		 * instruction to halt it in its tracks.
506		 */
507#ifdef DEBUG
508		if (ldebug(rt_sendsig))
509			printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"),
510			    fp, oonstack);
511#endif
512		PROC_LOCK(p);
513		sigexit(td, SIGILL);
514	}
515
516	/*
517	 * Build context to run handler in.
518	 */
519	regs->tf_esp = (int)fp;
520	regs->tf_eip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode;
521	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
522	regs->tf_cs = _ucodesel;
523	regs->tf_ds = _udatasel;
524	regs->tf_es = _udatasel;
525	regs->tf_fs = _udatasel;
526	regs->tf_ss = _udatasel;
527	PROC_LOCK(p);
528	mtx_lock(&psp->ps_mtx);
529}
530
531
532/*
533 * Send an interrupt to process.
534 *
535 * Stack is set up to allow sigcode stored
536 * in u. to call routine, followed by kcall
537 * to sigreturn routine below.  After sigreturn
538 * resets the signal mask, the stack, and the
539 * frame pointer, it returns to the user
540 * specified pc, psl.
541 */
542static void
543linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
544{
545	struct thread *td = curthread;
546	struct proc *p = td->td_proc;
547	struct sigacts *psp;
548	struct trapframe *regs;
549	struct l_sigframe *fp, frame;
550	l_sigset_t lmask;
551	int sig, code;
552	int oonstack, i;
553
554	PROC_LOCK_ASSERT(p, MA_OWNED);
555	psp = p->p_sigacts;
556	sig = ksi->ksi_signo;
557	code = ksi->ksi_code;
558	mtx_assert(&psp->ps_mtx, MA_OWNED);
559	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
560		/* Signal handler installed with SA_SIGINFO. */
561		linux_rt_sendsig(catcher, ksi, mask);
562		return;
563	}
564	regs = td->td_frame;
565	oonstack = sigonstack(regs->tf_esp);
566
567#ifdef DEBUG
568	if (ldebug(sendsig))
569		printf(ARGS(sendsig, "%p, %d, %p, %u"),
570		    catcher, sig, (void*)mask, code);
571#endif
572
573	/*
574	 * Allocate space for the signal handler context.
575	 */
576	if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
577	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
578		fp = (struct l_sigframe *)(td->td_sigstk.ss_sp +
579		    td->td_sigstk.ss_size - sizeof(struct l_sigframe));
580	} else
581		fp = (struct l_sigframe *)regs->tf_esp - 1;
582	mtx_unlock(&psp->ps_mtx);
583	PROC_UNLOCK(p);
584
585	/*
586	 * Build the argument list for the signal handler.
587	 */
588	if (p->p_sysent->sv_sigtbl)
589		if (sig <= p->p_sysent->sv_sigsize)
590			sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
591
592	bzero(&frame, sizeof(frame));
593
594	frame.sf_handler = catcher;
595	frame.sf_sig = sig;
596
597	bsd_to_linux_sigset(mask, &lmask);
598
599	/*
600	 * Build the signal context to be used by sigreturn.
601	 */
602	frame.sf_sc.sc_mask   = lmask.__bits[0];
603	frame.sf_sc.sc_gs     = rgs();
604	frame.sf_sc.sc_fs     = regs->tf_fs;
605	frame.sf_sc.sc_es     = regs->tf_es;
606	frame.sf_sc.sc_ds     = regs->tf_ds;
607	frame.sf_sc.sc_edi    = regs->tf_edi;
608	frame.sf_sc.sc_esi    = regs->tf_esi;
609	frame.sf_sc.sc_ebp    = regs->tf_ebp;
610	frame.sf_sc.sc_ebx    = regs->tf_ebx;
611	frame.sf_sc.sc_edx    = regs->tf_edx;
612	frame.sf_sc.sc_ecx    = regs->tf_ecx;
613	frame.sf_sc.sc_eax    = regs->tf_eax;
614	frame.sf_sc.sc_eip    = regs->tf_eip;
615	frame.sf_sc.sc_cs     = regs->tf_cs;
616	frame.sf_sc.sc_eflags = regs->tf_eflags;
617	frame.sf_sc.sc_esp_at_signal = regs->tf_esp;
618	frame.sf_sc.sc_ss     = regs->tf_ss;
619	frame.sf_sc.sc_err    = regs->tf_err;
620	frame.sf_sc.sc_cr2    = (register_t)ksi->ksi_addr;
621	frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno);
622
623	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
624		frame.sf_extramask[i] = lmask.__bits[i+1];
625
626	if (copyout(&frame, fp, sizeof(frame)) != 0) {
627		/*
628		 * Process has trashed its stack; give it an illegal
629		 * instruction to halt it in its tracks.
630		 */
631		PROC_LOCK(p);
632		sigexit(td, SIGILL);
633	}
634
635	/*
636	 * Build context to run handler in.
637	 */
638	regs->tf_esp = (int)fp;
639	regs->tf_eip = p->p_sysent->sv_sigcode_base;
640	regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
641	regs->tf_cs = _ucodesel;
642	regs->tf_ds = _udatasel;
643	regs->tf_es = _udatasel;
644	regs->tf_fs = _udatasel;
645	regs->tf_ss = _udatasel;
646	PROC_LOCK(p);
647	mtx_lock(&psp->ps_mtx);
648}
649
650/*
651 * System call to cleanup state after a signal
652 * has been taken.  Reset signal mask and
653 * stack state from context left by sendsig (above).
654 * Return to previous pc and psl as specified by
655 * context left by sendsig. Check carefully to
656 * make sure that the user has not modified the
657 * psl to gain improper privileges or to cause
658 * a machine fault.
659 */
660int
661linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
662{
663	struct l_sigframe frame;
664	struct trapframe *regs;
665	l_sigset_t lmask;
666	sigset_t bmask;
667	int eflags, i;
668	ksiginfo_t ksi;
669
670	regs = td->td_frame;
671
672#ifdef DEBUG
673	if (ldebug(sigreturn))
674		printf(ARGS(sigreturn, "%p"), (void *)args->sfp);
675#endif
676	/*
677	 * The trampoline code hands us the sigframe.
678	 * It is unsafe to keep track of it ourselves, in the event that a
679	 * program jumps out of a signal handler.
680	 */
681	if (copyin(args->sfp, &frame, sizeof(frame)) != 0)
682		return (EFAULT);
683
684	/*
685	 * Check for security violations.
686	 */
687#define	EFLAGS_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
688	eflags = frame.sf_sc.sc_eflags;
689	if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
690		return(EINVAL);
691
692	/*
693	 * Don't allow users to load a valid privileged %cs.  Let the
694	 * hardware check for invalid selectors, excess privilege in
695	 * other selectors, invalid %eip's and invalid %esp's.
696	 */
697#define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
698	if (!CS_SECURE(frame.sf_sc.sc_cs)) {
699		ksiginfo_init_trap(&ksi);
700		ksi.ksi_signo = SIGBUS;
701		ksi.ksi_code = BUS_OBJERR;
702		ksi.ksi_trapno = T_PROTFLT;
703		ksi.ksi_addr = (void *)regs->tf_eip;
704		trapsignal(td, &ksi);
705		return(EINVAL);
706	}
707
708	lmask.__bits[0] = frame.sf_sc.sc_mask;
709	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
710		lmask.__bits[i+1] = frame.sf_extramask[i];
711	linux_to_bsd_sigset(&lmask, &bmask);
712	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
713
714	/*
715	 * Restore signal context.
716	 */
717	/* %gs was restored by the trampoline. */
718	regs->tf_fs     = frame.sf_sc.sc_fs;
719	regs->tf_es     = frame.sf_sc.sc_es;
720	regs->tf_ds     = frame.sf_sc.sc_ds;
721	regs->tf_edi    = frame.sf_sc.sc_edi;
722	regs->tf_esi    = frame.sf_sc.sc_esi;
723	regs->tf_ebp    = frame.sf_sc.sc_ebp;
724	regs->tf_ebx    = frame.sf_sc.sc_ebx;
725	regs->tf_edx    = frame.sf_sc.sc_edx;
726	regs->tf_ecx    = frame.sf_sc.sc_ecx;
727	regs->tf_eax    = frame.sf_sc.sc_eax;
728	regs->tf_eip    = frame.sf_sc.sc_eip;
729	regs->tf_cs     = frame.sf_sc.sc_cs;
730	regs->tf_eflags = eflags;
731	regs->tf_esp    = frame.sf_sc.sc_esp_at_signal;
732	regs->tf_ss     = frame.sf_sc.sc_ss;
733
734	return (EJUSTRETURN);
735}
736
737/*
738 * System call to cleanup state after a signal
739 * has been taken.  Reset signal mask and
740 * stack state from context left by rt_sendsig (above).
741 * Return to previous pc and psl as specified by
742 * context left by sendsig. Check carefully to
743 * make sure that the user has not modified the
744 * psl to gain improper privileges or to cause
745 * a machine fault.
746 */
747int
748linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
749{
750	struct l_ucontext uc;
751	struct l_sigcontext *context;
752	sigset_t bmask;
753	l_stack_t *lss;
754	stack_t ss;
755	struct trapframe *regs;
756	int eflags;
757	ksiginfo_t ksi;
758
759	regs = td->td_frame;
760
761#ifdef DEBUG
762	if (ldebug(rt_sigreturn))
763		printf(ARGS(rt_sigreturn, "%p"), (void *)args->ucp);
764#endif
765	/*
766	 * The trampoline code hands us the ucontext.
767	 * It is unsafe to keep track of it ourselves, in the event that a
768	 * program jumps out of a signal handler.
769	 */
770	if (copyin(args->ucp, &uc, sizeof(uc)) != 0)
771		return (EFAULT);
772
773	context = &uc.uc_mcontext;
774
775	/*
776	 * Check for security violations.
777	 */
778#define	EFLAGS_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
779	eflags = context->sc_eflags;
780	if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
781		return(EINVAL);
782
783	/*
784	 * Don't allow users to load a valid privileged %cs.  Let the
785	 * hardware check for invalid selectors, excess privilege in
786	 * other selectors, invalid %eip's and invalid %esp's.
787	 */
788#define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
789	if (!CS_SECURE(context->sc_cs)) {
790		ksiginfo_init_trap(&ksi);
791		ksi.ksi_signo = SIGBUS;
792		ksi.ksi_code = BUS_OBJERR;
793		ksi.ksi_trapno = T_PROTFLT;
794		ksi.ksi_addr = (void *)regs->tf_eip;
795		trapsignal(td, &ksi);
796		return(EINVAL);
797	}
798
799	linux_to_bsd_sigset(&uc.uc_sigmask, &bmask);
800	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
801
802	/*
803	 * Restore signal context
804	 */
805	/* %gs was restored by the trampoline. */
806	regs->tf_fs     = context->sc_fs;
807	regs->tf_es     = context->sc_es;
808	regs->tf_ds     = context->sc_ds;
809	regs->tf_edi    = context->sc_edi;
810	regs->tf_esi    = context->sc_esi;
811	regs->tf_ebp    = context->sc_ebp;
812	regs->tf_ebx    = context->sc_ebx;
813	regs->tf_edx    = context->sc_edx;
814	regs->tf_ecx    = context->sc_ecx;
815	regs->tf_eax    = context->sc_eax;
816	regs->tf_eip    = context->sc_eip;
817	regs->tf_cs     = context->sc_cs;
818	regs->tf_eflags = eflags;
819	regs->tf_esp    = context->sc_esp_at_signal;
820	regs->tf_ss     = context->sc_ss;
821
822	/*
823	 * call sigaltstack & ignore results..
824	 */
825	lss = &uc.uc_stack;
826	ss.ss_sp = lss->ss_sp;
827	ss.ss_size = lss->ss_size;
828	ss.ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags);
829
830#ifdef DEBUG
831	if (ldebug(rt_sigreturn))
832		printf(LMSG("rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
833		    ss.ss_flags, ss.ss_sp, ss.ss_size, context->sc_mask);
834#endif
835	(void)kern_sigaltstack(td, &ss, NULL);
836
837	return (EJUSTRETURN);
838}
839
840static int
841linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
842{
843	struct proc *p;
844	struct trapframe *frame;
845
846	p = td->td_proc;
847	frame = td->td_frame;
848
849	sa->code = frame->tf_eax;
850	sa->args[0] = frame->tf_ebx;
851	sa->args[1] = frame->tf_ecx;
852	sa->args[2] = frame->tf_edx;
853	sa->args[3] = frame->tf_esi;
854	sa->args[4] = frame->tf_edi;
855	sa->args[5] = frame->tf_ebp;	/* Unconfirmed */
856
857	if (sa->code >= p->p_sysent->sv_size)
858		sa->callp = &p->p_sysent->sv_table[0];
859 	else
860 		sa->callp = &p->p_sysent->sv_table[sa->code];
861	sa->narg = sa->callp->sy_narg;
862
863	td->td_retval[0] = 0;
864	td->td_retval[1] = frame->tf_edx;
865
866	return (0);
867}
868
869/*
870 * If a linux binary is exec'ing something, try this image activator
871 * first.  We override standard shell script execution in order to
872 * be able to modify the interpreter path.  We only do this if a linux
873 * binary is doing the exec, so we do not create an EXEC module for it.
874 */
875static int	exec_linux_imgact_try(struct image_params *iparams);
876
877static int
878exec_linux_imgact_try(struct image_params *imgp)
879{
880    const char *head = (const char *)imgp->image_header;
881    char *rpath;
882    int error = -1;
883
884    /*
885     * The interpreter for shell scripts run from a linux binary needs
886     * to be located in /compat/linux if possible in order to recursively
887     * maintain linux path emulation.
888     */
889    if (((const short *)head)[0] == SHELLMAGIC) {
890	    /*
891	     * Run our normal shell image activator.  If it succeeds attempt
892	     * to use the alternate path for the interpreter.  If an alternate
893	     * path is found, use our stringspace to store it.
894	     */
895	    if ((error = exec_shell_imgact(imgp)) == 0) {
896		    linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
897			imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD);
898		    if (rpath != NULL)
899			    imgp->args->fname_buf =
900				imgp->interpreter_name = rpath;
901	    }
902    }
903    return (error);
904}
905
906/*
907 * exec_setregs may initialize some registers differently than Linux
908 * does, thus potentially confusing Linux binaries. If necessary, we
909 * override the exec_setregs default(s) here.
910 */
911static void
912exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack)
913{
914	struct pcb *pcb = td->td_pcb;
915
916	exec_setregs(td, imgp, stack);
917
918	/* Linux sets %gs to 0, we default to _udatasel */
919	pcb->pcb_gs = 0;
920	load_gs(0);
921
922	pcb->pcb_initial_npxcw = __LINUX_NPXCW__;
923}
924
925static void
926linux_get_machine(const char **dst)
927{
928
929	switch (cpu_class) {
930	case CPUCLASS_686:
931		*dst = "i686";
932		break;
933	case CPUCLASS_586:
934		*dst = "i586";
935		break;
936	case CPUCLASS_486:
937		*dst = "i486";
938		break;
939	default:
940		*dst = "i386";
941	}
942}
943
944struct sysentvec linux_sysvec = {
945	.sv_size	= LINUX_SYS_MAXSYSCALL,
946	.sv_table	= linux_sysent,
947	.sv_mask	= 0,
948	.sv_sigsize	= LINUX_SIGTBLSZ,
949	.sv_sigtbl	= bsd_to_linux_signal,
950	.sv_errsize	= ELAST + 1,
951	.sv_errtbl	= bsd_to_linux_errno,
952	.sv_transtrap	= translate_traps,
953	.sv_fixup	= linux_fixup,
954	.sv_sendsig	= linux_sendsig,
955	.sv_sigcode	= linux_sigcode,
956	.sv_szsigcode	= &linux_szsigcode,
957	.sv_prepsyscall	= NULL,
958	.sv_name	= "Linux a.out",
959	.sv_coredump	= NULL,
960	.sv_imgact_try	= exec_linux_imgact_try,
961	.sv_minsigstksz	= LINUX_MINSIGSTKSZ,
962	.sv_pagesize	= PAGE_SIZE,
963	.sv_minuser	= VM_MIN_ADDRESS,
964	.sv_maxuser	= VM_MAXUSER_ADDRESS,
965	.sv_usrstack	= LINUX_USRSTACK,
966	.sv_psstrings	= PS_STRINGS,
967	.sv_stackprot	= VM_PROT_ALL,
968	.sv_copyout_strings = exec_copyout_strings,
969	.sv_setregs	= exec_linux_setregs,
970	.sv_fixlimit	= NULL,
971	.sv_maxssiz	= NULL,
972	.sv_flags	= SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32,
973	.sv_set_syscall_retval = cpu_set_syscall_retval,
974	.sv_fetch_syscall_args = linux_fetch_syscall_args,
975	.sv_syscallnames = NULL,
976	.sv_shared_page_base = LINUX_SHAREDPAGE,
977	.sv_shared_page_len = PAGE_SIZE,
978	.sv_schedtail	= linux_schedtail,
979};
980INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
981
982struct sysentvec elf_linux_sysvec = {
983	.sv_size	= LINUX_SYS_MAXSYSCALL,
984	.sv_table	= linux_sysent,
985	.sv_mask	= 0,
986	.sv_sigsize	= LINUX_SIGTBLSZ,
987	.sv_sigtbl	= bsd_to_linux_signal,
988	.sv_errsize	= ELAST + 1,
989	.sv_errtbl	= bsd_to_linux_errno,
990	.sv_transtrap	= translate_traps,
991	.sv_fixup	= elf_linux_fixup,
992	.sv_sendsig	= linux_sendsig,
993	.sv_sigcode	= linux_sigcode,
994	.sv_szsigcode	= &linux_szsigcode,
995	.sv_prepsyscall	= NULL,
996	.sv_name	= "Linux ELF",
997	.sv_coredump	= elf32_coredump,
998	.sv_imgact_try	= exec_linux_imgact_try,
999	.sv_minsigstksz	= LINUX_MINSIGSTKSZ,
1000	.sv_pagesize	= PAGE_SIZE,
1001	.sv_minuser	= VM_MIN_ADDRESS,
1002	.sv_maxuser	= VM_MAXUSER_ADDRESS,
1003	.sv_usrstack	= LINUX_USRSTACK,
1004	.sv_psstrings	= LINUX_PS_STRINGS,
1005	.sv_stackprot	= VM_PROT_ALL,
1006	.sv_copyout_strings = linux_copyout_strings,
1007	.sv_setregs	= exec_linux_setregs,
1008	.sv_fixlimit	= NULL,
1009	.sv_maxssiz	= NULL,
1010	.sv_flags	= SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP,
1011	.sv_set_syscall_retval = cpu_set_syscall_retval,
1012	.sv_fetch_syscall_args = linux_fetch_syscall_args,
1013	.sv_syscallnames = NULL,
1014	.sv_shared_page_base = LINUX_SHAREDPAGE,
1015	.sv_shared_page_len = PAGE_SIZE,
1016	.sv_schedtail	= linux_schedtail,
1017};
1018INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
1019
1020static char GNU_ABI_VENDOR[] = "GNU";
1021static int GNULINUX_ABI_DESC = 0;
1022
1023static boolean_t
1024linux_trans_osrel(const Elf_Note *note, int32_t *osrel)
1025{
1026	const Elf32_Word *desc;
1027	uintptr_t p;
1028
1029	p = (uintptr_t)(note + 1);
1030	p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
1031
1032	desc = (const Elf32_Word *)p;
1033	if (desc[0] != GNULINUX_ABI_DESC)
1034		return (FALSE);
1035
1036	/*
1037	 * For linux we encode osrel as follows (see linux_mib.c):
1038	 * VVVMMMIII (version, major, minor), see linux_mib.c.
1039	 */
1040	*osrel = desc[1] * 1000000 + desc[2] * 1000 + desc[3];
1041
1042	return (TRUE);
1043}
1044
1045static Elf_Brandnote linux_brandnote = {
1046	.hdr.n_namesz	= sizeof(GNU_ABI_VENDOR),
1047	.hdr.n_descsz	= 16,	/* XXX at least 16 */
1048	.hdr.n_type	= 1,
1049	.vendor		= GNU_ABI_VENDOR,
1050	.flags		= BN_TRANSLATE_OSREL,
1051	.trans_osrel	= linux_trans_osrel
1052};
1053
1054static Elf32_Brandinfo linux_brand = {
1055	.brand		= ELFOSABI_LINUX,
1056	.machine	= EM_386,
1057	.compat_3_brand	= "Linux",
1058	.emul_path	= "/compat/linux",
1059	.interp_path	= "/lib/ld-linux.so.1",
1060	.sysvec		= &elf_linux_sysvec,
1061	.interp_newpath	= NULL,
1062	.brand_note	= &linux_brandnote,
1063	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
1064};
1065
1066static Elf32_Brandinfo linux_glibc2brand = {
1067	.brand		= ELFOSABI_LINUX,
1068	.machine	= EM_386,
1069	.compat_3_brand	= "Linux",
1070	.emul_path	= "/compat/linux",
1071	.interp_path	= "/lib/ld-linux.so.2",
1072	.sysvec		= &elf_linux_sysvec,
1073	.interp_newpath	= NULL,
1074	.brand_note	= &linux_brandnote,
1075	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
1076};
1077
1078Elf32_Brandinfo *linux_brandlist[] = {
1079	&linux_brand,
1080	&linux_glibc2brand,
1081	NULL
1082};
1083
1084static int
1085linux_elf_modevent(module_t mod, int type, void *data)
1086{
1087	Elf32_Brandinfo **brandinfo;
1088	int error;
1089	struct linux_ioctl_handler **lihp;
1090	struct linux_device_handler **ldhp;
1091
1092	error = 0;
1093
1094	switch(type) {
1095	case MOD_LOAD:
1096		for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
1097		     ++brandinfo)
1098			if (elf32_insert_brand_entry(*brandinfo) < 0)
1099				error = EINVAL;
1100		if (error == 0) {
1101			SET_FOREACH(lihp, linux_ioctl_handler_set)
1102				linux_ioctl_register_handler(*lihp);
1103			SET_FOREACH(ldhp, linux_device_handler_set)
1104				linux_device_register_handler(*ldhp);
1105			mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
1106			sx_init(&emul_shared_lock, "emuldata->shared lock");
1107			LIST_INIT(&futex_list);
1108			mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
1109			linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
1110			      NULL, 1000);
1111			linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
1112			      NULL, 1000);
1113			linux_get_machine(&linux_platform);
1114			linux_szplatform = roundup(strlen(linux_platform) + 1,
1115			    sizeof(char *));
1116			linux_osd_jail_register();
1117			stclohz = (stathz ? stathz : hz);
1118			if (bootverbose)
1119				printf("Linux ELF exec handler installed\n");
1120		} else
1121			printf("cannot insert Linux ELF brand handler\n");
1122		break;
1123	case MOD_UNLOAD:
1124		for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
1125		     ++brandinfo)
1126			if (elf32_brand_inuse(*brandinfo))
1127				error = EBUSY;
1128		if (error == 0) {
1129			for (brandinfo = &linux_brandlist[0];
1130			     *brandinfo != NULL; ++brandinfo)
1131				if (elf32_remove_brand_entry(*brandinfo) < 0)
1132					error = EINVAL;
1133		}
1134		if (error == 0) {
1135			SET_FOREACH(lihp, linux_ioctl_handler_set)
1136				linux_ioctl_unregister_handler(*lihp);
1137			SET_FOREACH(ldhp, linux_device_handler_set)
1138				linux_device_unregister_handler(*ldhp);
1139			mtx_destroy(&emul_lock);
1140			sx_destroy(&emul_shared_lock);
1141			mtx_destroy(&futex_mtx);
1142			EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
1143			EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
1144			linux_osd_jail_deregister();
1145			if (bootverbose)
1146				printf("Linux ELF exec handler removed\n");
1147		} else
1148			printf("Could not deinstall ELF interpreter entry\n");
1149		break;
1150	default:
1151		return EOPNOTSUPP;
1152	}
1153	return error;
1154}
1155
1156static moduledata_t linux_elf_mod = {
1157	"linuxelf",
1158	linux_elf_modevent,
1159	0
1160};
1161
1162DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
1163