The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/amd64/linux32/linux32_sysvec.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2004 Tim J. Robbins
    3  * Copyright (c) 2003 Peter Wemm
    4  * Copyright (c) 2002 Doug Rabson
    5  * Copyright (c) 1998-1999 Andrew Gallatin
    6  * Copyright (c) 1994-1996 Søren Schmidt
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer
   14  *    in this position and unchanged.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 /* XXX we use functions that might not exist. */
   37 #include "opt_compat.h"
   38 
   39 #ifndef COMPAT_IA32
   40 #error "Unable to compile Linux-emulator due to missing COMPAT_IA32 option!"
   41 #endif
   42 
   43 #define __ELF_WORD_SIZE 32
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/exec.h>
   48 #include <sys/imgact.h>
   49 #include <sys/imgact_elf.h>
   50 #include <sys/kernel.h>
   51 #include <sys/lock.h>
   52 #include <sys/malloc.h>
   53 #include <sys/module.h>
   54 #include <sys/mutex.h>
   55 #include <sys/proc.h>
   56 #include <sys/resourcevar.h>
   57 #include <sys/signalvar.h>
   58 #include <sys/sysctl.h>
   59 #include <sys/syscallsubr.h>
   60 #include <sys/sysent.h>
   61 #include <sys/sysproto.h>
   62 #include <sys/vnode.h>
   63 
   64 #include <vm/vm.h>
   65 #include <vm/pmap.h>
   66 #include <vm/vm_extern.h>
   67 #include <vm/vm_map.h>
   68 #include <vm/vm_object.h>
   69 #include <vm/vm_page.h>
   70 #include <vm/vm_param.h>
   71 
   72 #include <machine/cpu.h>
   73 #include <machine/md_var.h>
   74 #include <machine/pcb.h>
   75 #include <machine/specialreg.h>
   76 
   77 #include <amd64/linux32/linux.h>
   78 #include <amd64/linux32/linux32_proto.h>
   79 #include <compat/linux/linux_mib.h>
   80 #include <compat/linux/linux_signal.h>
   81 #include <compat/linux/linux_util.h>
   82 
   83 MODULE_VERSION(linux, 1);
   84 MODULE_DEPEND(linux, sysvmsg, 1, 1, 1);
   85 MODULE_DEPEND(linux, sysvsem, 1, 1, 1);
   86 MODULE_DEPEND(linux, sysvshm, 1, 1, 1);
   87 
   88 MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
   89 
   90 #define AUXARGS_ENTRY_32(pos, id, val)  \
   91         do {                            \
   92                 suword32(pos++, id);    \
   93                 suword32(pos++, val);   \
   94         } while (0)
   95 
   96 #if BYTE_ORDER == LITTLE_ENDIAN
   97 #define SHELLMAGIC      0x2123 /* #! */
   98 #else
   99 #define SHELLMAGIC      0x2321
  100 #endif
  101 
  102 /*
  103  * Allow the sendsig functions to use the ldebug() facility
  104  * even though they are not syscalls themselves. Map them
  105  * to syscall 0. This is slightly less bogus than using
  106  * ldebug(sigreturn).
  107  */
  108 #define LINUX_SYS_linux_rt_sendsig      0
  109 #define LINUX_SYS_linux_sendsig         0
  110 
  111 extern char linux_sigcode[];
  112 extern int linux_szsigcode;
  113 
  114 extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
  115 
  116 SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
  117 SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
  118 
  119 static int      elf_linux_fixup(register_t **stack_base,
  120                     struct image_params *iparams);
  121 static register_t *linux_copyout_strings(struct image_params *imgp);
  122 static void     linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
  123                     caddr_t *params);
  124 static void     linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
  125                     u_long code);
  126 static void     exec_linux_setregs(struct thread *td, u_long entry,
  127                                    u_long stack, u_long ps_strings);
  128 static void     linux32_fixlimit(struct rlimit *rl, int which);
  129 
  130 /*
  131  * Linux syscalls return negative errno's, we do positive and map them
  132  */
  133 static int bsd_to_linux_errno[ELAST + 1] = {
  134         -0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
  135         -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
  136         -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
  137         -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
  138         -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
  139         -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
  140         -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
  141         -116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
  142           -6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
  143          -72, -67, -71
  144 };
  145 
  146 int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
  147         LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
  148         LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
  149         LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
  150         LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
  151         LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
  152         LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
  153         LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
  154         0, LINUX_SIGUSR1, LINUX_SIGUSR2
  155 };
  156 
  157 int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
  158         SIGHUP, SIGINT, SIGQUIT, SIGILL,
  159         SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
  160         SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
  161         SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
  162         SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
  163         SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
  164         SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
  165         SIGIO, SIGURG, SIGSYS
  166 };
  167 
  168 #define LINUX_T_UNKNOWN  255
  169 static int _bsd_to_linux_trapcode[] = {
  170         LINUX_T_UNKNOWN,        /* 0 */
  171         6,                      /* 1  T_PRIVINFLT */
  172         LINUX_T_UNKNOWN,        /* 2 */
  173         3,                      /* 3  T_BPTFLT */
  174         LINUX_T_UNKNOWN,        /* 4 */
  175         LINUX_T_UNKNOWN,        /* 5 */
  176         16,                     /* 6  T_ARITHTRAP */
  177         254,                    /* 7  T_ASTFLT */
  178         LINUX_T_UNKNOWN,        /* 8 */
  179         13,                     /* 9  T_PROTFLT */
  180         1,                      /* 10 T_TRCTRAP */
  181         LINUX_T_UNKNOWN,        /* 11 */
  182         14,                     /* 12 T_PAGEFLT */
  183         LINUX_T_UNKNOWN,        /* 13 */
  184         17,                     /* 14 T_ALIGNFLT */
  185         LINUX_T_UNKNOWN,        /* 15 */
  186         LINUX_T_UNKNOWN,        /* 16 */
  187         LINUX_T_UNKNOWN,        /* 17 */
  188         0,                      /* 18 T_DIVIDE */
  189         2,                      /* 19 T_NMI */
  190         4,                      /* 20 T_OFLOW */
  191         5,                      /* 21 T_BOUND */
  192         7,                      /* 22 T_DNA */
  193         8,                      /* 23 T_DOUBLEFLT */
  194         9,                      /* 24 T_FPOPFLT */
  195         10,                     /* 25 T_TSSFLT */
  196         11,                     /* 26 T_SEGNPFLT */
  197         12,                     /* 27 T_STKFLT */
  198         18,                     /* 28 T_MCHK */
  199         19,                     /* 29 T_XMMFLT */
  200         15                      /* 30 T_RESERVED */
  201 };
  202 #define bsd_to_linux_trapcode(code) \
  203     ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \
  204      _bsd_to_linux_trapcode[(code)]: \
  205      LINUX_T_UNKNOWN)
  206 
  207 struct linux32_ps_strings {
  208         u_int32_t ps_argvstr;   /* first of 0 or more argument strings */
  209         u_int ps_nargvstr;      /* the number of argument strings */
  210         u_int32_t ps_envstr;    /* first of 0 or more environment strings */
  211         u_int ps_nenvstr;       /* the number of environment strings */
  212 };
  213 
  214 /*
  215  * If FreeBSD & Linux have a difference of opinion about what a trap
  216  * means, deal with it here.
  217  *
  218  * MPSAFE
  219  */
  220 static int
  221 translate_traps(int signal, int trap_code)
  222 {
  223         if (signal != SIGBUS)
  224                 return signal;
  225         switch (trap_code) {
  226         case T_PROTFLT:
  227         case T_TSSFLT:
  228         case T_DOUBLEFLT:
  229         case T_PAGEFLT:
  230                 return SIGSEGV;
  231         default:
  232                 return signal;
  233         }
  234 }
  235 
  236 static int
  237 elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
  238 {
  239         Elf32_Auxargs *args;
  240         Elf32_Addr *base;
  241         Elf32_Addr *pos;
  242 
  243         KASSERT(curthread->td_proc == imgp->proc &&
  244             (curthread->td_proc->p_flag & P_SA) == 0,
  245             ("unsafe elf_linux_fixup(), should be curproc"));
  246         base = (Elf32_Addr *)*stack_base;
  247         args = (Elf32_Auxargs *)imgp->auxargs;
  248         pos = base + (imgp->args->argc + imgp->args->envc + 2);
  249 
  250         if (args->trace)
  251                 AUXARGS_ENTRY_32(pos, AT_DEBUG, 1);
  252         if (args->execfd != -1)
  253                 AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd);
  254         AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr);
  255         AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent);
  256         AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum);
  257         AUXARGS_ENTRY_32(pos, AT_PAGESZ, args->pagesz);
  258         AUXARGS_ENTRY_32(pos, AT_FLAGS, args->flags);
  259         AUXARGS_ENTRY_32(pos, AT_ENTRY, args->entry);
  260         AUXARGS_ENTRY_32(pos, AT_BASE, args->base);
  261         AUXARGS_ENTRY_32(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
  262         AUXARGS_ENTRY_32(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
  263         AUXARGS_ENTRY_32(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
  264         AUXARGS_ENTRY_32(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
  265         AUXARGS_ENTRY_32(pos, AT_NULL, 0);
  266 
  267         free(imgp->auxargs, M_TEMP);
  268         imgp->auxargs = NULL;
  269 
  270         base--;
  271         suword32(base, (uint32_t)imgp->args->argc);
  272         *stack_base = (register_t *)base;
  273         return 0;
  274 }
  275 
  276 extern int _ucodesel, _ucode32sel, _udatasel;
  277 extern unsigned long linux_sznonrtsigcode;
  278 
  279 static void
  280 linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
  281 {
  282         struct thread *td = curthread;
  283         struct proc *p = td->td_proc;
  284         struct sigacts *psp;
  285         struct trapframe *regs;
  286         struct l_rt_sigframe *fp, frame;
  287         int oonstack;
  288 
  289         PROC_LOCK_ASSERT(p, MA_OWNED);
  290         psp = p->p_sigacts;
  291         mtx_assert(&psp->ps_mtx, MA_OWNED);
  292         regs = td->td_frame;
  293         oonstack = sigonstack(regs->tf_rsp);
  294 
  295 #ifdef DEBUG
  296         if (ldebug(rt_sendsig))
  297                 printf(ARGS(rt_sendsig, "%p, %d, %p, %lu"),
  298                     catcher, sig, (void*)mask, code);
  299 #endif
  300         /*
  301          * Allocate space for the signal handler context.
  302          */
  303         if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
  304             SIGISMEMBER(psp->ps_sigonstack, sig)) {
  305                 fp = (struct l_rt_sigframe *)(td->td_sigstk.ss_sp +
  306                     td->td_sigstk.ss_size - sizeof(struct l_rt_sigframe));
  307         } else
  308                 fp = (struct l_rt_sigframe *)regs->tf_rsp - 1;
  309         mtx_unlock(&psp->ps_mtx);
  310 
  311         /*
  312          * Build the argument list for the signal handler.
  313          */
  314         if (p->p_sysent->sv_sigtbl)
  315                 if (sig <= p->p_sysent->sv_sigsize)
  316                         sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
  317 
  318         bzero(&frame, sizeof(frame));
  319 
  320         frame.sf_handler = PTROUT(catcher);
  321         frame.sf_sig = sig;
  322         frame.sf_siginfo = PTROUT(&fp->sf_si);
  323         frame.sf_ucontext = PTROUT(&fp->sf_sc);
  324 
  325         /* Fill in POSIX parts */
  326         frame.sf_si.lsi_signo = sig;
  327         frame.sf_si.lsi_code = code;
  328         frame.sf_si.lsi_addr = PTROUT(regs->tf_addr);
  329 
  330         /*
  331          * Build the signal context to be used by sigreturn.
  332          */
  333         frame.sf_sc.uc_flags = 0;               /* XXX ??? */
  334         frame.sf_sc.uc_link = 0;                /* XXX ??? */
  335 
  336         frame.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
  337         frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
  338         frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
  339             ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
  340         PROC_UNLOCK(p);
  341 
  342         bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
  343 
  344         frame.sf_sc.uc_mcontext.sc_mask   = frame.sf_sc.uc_sigmask.__bits[0];
  345         frame.sf_sc.uc_mcontext.sc_gs     = rgs();
  346         frame.sf_sc.uc_mcontext.sc_fs     = rfs();
  347         __asm __volatile("movl %%es,%0" :
  348             "=rm" (frame.sf_sc.uc_mcontext.sc_es));
  349         __asm __volatile("movl %%ds,%0" :
  350             "=rm" (frame.sf_sc.uc_mcontext.sc_ds));
  351         frame.sf_sc.uc_mcontext.sc_edi    = regs->tf_rdi;
  352         frame.sf_sc.uc_mcontext.sc_esi    = regs->tf_rsi;
  353         frame.sf_sc.uc_mcontext.sc_ebp    = regs->tf_rbp;
  354         frame.sf_sc.uc_mcontext.sc_ebx    = regs->tf_rbx;
  355         frame.sf_sc.uc_mcontext.sc_edx    = regs->tf_rdx;
  356         frame.sf_sc.uc_mcontext.sc_ecx    = regs->tf_rcx;
  357         frame.sf_sc.uc_mcontext.sc_eax    = regs->tf_rax;
  358         frame.sf_sc.uc_mcontext.sc_eip    = regs->tf_rip;
  359         frame.sf_sc.uc_mcontext.sc_cs     = regs->tf_cs;
  360         frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_rflags;
  361         frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_rsp;
  362         frame.sf_sc.uc_mcontext.sc_ss     = regs->tf_ss;
  363         frame.sf_sc.uc_mcontext.sc_err    = regs->tf_err;
  364         frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
  365 
  366 #ifdef DEBUG
  367         if (ldebug(rt_sendsig))
  368                 printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%lx, mask: 0x%x"),
  369                     frame.sf_sc.uc_stack.ss_flags, td->td_sigstk.ss_sp,
  370                     td->td_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
  371 #endif
  372 
  373         if (copyout(&frame, fp, sizeof(frame)) != 0) {
  374                 /*
  375                  * Process has trashed its stack; give it an illegal
  376                  * instruction to halt it in its tracks.
  377                  */
  378 #ifdef DEBUG
  379                 if (ldebug(rt_sendsig))
  380                         printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"),
  381                             fp, oonstack);
  382 #endif
  383                 PROC_LOCK(p);
  384                 sigexit(td, SIGILL);
  385         }
  386 
  387         /*
  388          * Build context to run handler in.
  389          */
  390         regs->tf_rsp = PTROUT(fp);
  391         regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode) +
  392             linux_sznonrtsigcode;
  393         regs->tf_rflags &= ~(PSL_T | PSL_D);
  394         regs->tf_cs = _ucode32sel;
  395         regs->tf_ss = _udatasel;
  396         load_ds(_udatasel);
  397         td->td_pcb->pcb_ds = _udatasel;
  398         load_es(_udatasel);
  399         td->td_pcb->pcb_es = _udatasel;
  400         /* leave user %fs and %gs untouched */
  401         PROC_LOCK(p);
  402         mtx_lock(&psp->ps_mtx);
  403 }
  404 
  405 
  406 /*
  407  * Send an interrupt to process.
  408  *
  409  * Stack is set up to allow sigcode stored
  410  * in u. to call routine, followed by kcall
  411  * to sigreturn routine below.  After sigreturn
  412  * resets the signal mask, the stack, and the
  413  * frame pointer, it returns to the user
  414  * specified pc, psl.
  415  */
  416 static void
  417 linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
  418 {
  419         struct thread *td = curthread;
  420         struct proc *p = td->td_proc;
  421         struct sigacts *psp;
  422         struct trapframe *regs;
  423         struct l_sigframe *fp, frame;
  424         l_sigset_t lmask;
  425         int oonstack, i;
  426 
  427         PROC_LOCK_ASSERT(p, MA_OWNED);
  428         psp = p->p_sigacts;
  429         mtx_assert(&psp->ps_mtx, MA_OWNED);
  430         if (SIGISMEMBER(psp->ps_siginfo, sig)) {
  431                 /* Signal handler installed with SA_SIGINFO. */
  432                 linux_rt_sendsig(catcher, sig, mask, code);
  433                 return;
  434         }
  435 
  436         regs = td->td_frame;
  437         oonstack = sigonstack(regs->tf_rsp);
  438 
  439 #ifdef DEBUG
  440         if (ldebug(sendsig))
  441                 printf(ARGS(sendsig, "%p, %d, %p, %lu"),
  442                     catcher, sig, (void*)mask, code);
  443 #endif
  444 
  445         /*
  446          * Allocate space for the signal handler context.
  447          */
  448         if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
  449             SIGISMEMBER(psp->ps_sigonstack, sig)) {
  450                 fp = (struct l_sigframe *)(td->td_sigstk.ss_sp +
  451                     td->td_sigstk.ss_size - sizeof(struct l_sigframe));
  452         } else
  453                 fp = (struct l_sigframe *)regs->tf_rsp - 1;
  454         mtx_unlock(&psp->ps_mtx);
  455         PROC_UNLOCK(p);
  456 
  457         /*
  458          * Build the argument list for the signal handler.
  459          */
  460         if (p->p_sysent->sv_sigtbl)
  461                 if (sig <= p->p_sysent->sv_sigsize)
  462                         sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
  463 
  464         bzero(&frame, sizeof(frame));
  465 
  466         frame.sf_handler = PTROUT(catcher);
  467         frame.sf_sig = sig;
  468 
  469         bsd_to_linux_sigset(mask, &lmask);
  470 
  471         /*
  472          * Build the signal context to be used by sigreturn.
  473          */
  474         frame.sf_sc.sc_mask   = lmask.__bits[0];
  475         frame.sf_sc.sc_gs     = rgs();
  476         frame.sf_sc.sc_fs     = rfs();
  477         __asm __volatile("movl %%es,%0" : "=rm" (frame.sf_sc.sc_es));
  478         __asm __volatile("movl %%ds,%0" : "=rm" (frame.sf_sc.sc_ds));
  479         frame.sf_sc.sc_edi    = regs->tf_rdi;
  480         frame.sf_sc.sc_esi    = regs->tf_rsi;
  481         frame.sf_sc.sc_ebp    = regs->tf_rbp;
  482         frame.sf_sc.sc_ebx    = regs->tf_rbx;
  483         frame.sf_sc.sc_edx    = regs->tf_rdx;
  484         frame.sf_sc.sc_ecx    = regs->tf_rcx;
  485         frame.sf_sc.sc_eax    = regs->tf_rax;
  486         frame.sf_sc.sc_eip    = regs->tf_rip;
  487         frame.sf_sc.sc_cs     = regs->tf_cs;
  488         frame.sf_sc.sc_eflags = regs->tf_rflags;
  489         frame.sf_sc.sc_esp_at_signal = regs->tf_rsp;
  490         frame.sf_sc.sc_ss     = regs->tf_ss;
  491         frame.sf_sc.sc_err    = regs->tf_err;
  492         frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
  493 
  494         for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
  495                 frame.sf_extramask[i] = lmask.__bits[i+1];
  496 
  497         if (copyout(&frame, fp, sizeof(frame)) != 0) {
  498                 /*
  499                  * Process has trashed its stack; give it an illegal
  500                  * instruction to halt it in its tracks.
  501                  */
  502                 PROC_LOCK(p);
  503                 sigexit(td, SIGILL);
  504         }
  505 
  506         /*
  507          * Build context to run handler in.
  508          */
  509         regs->tf_rsp = PTROUT(fp);
  510         regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
  511         regs->tf_rflags &= ~(PSL_T | PSL_D);
  512         regs->tf_cs = _ucode32sel;
  513         regs->tf_ss = _udatasel;
  514         load_ds(_udatasel);
  515         td->td_pcb->pcb_ds = _udatasel;
  516         load_es(_udatasel);
  517         td->td_pcb->pcb_es = _udatasel;
  518         /* leave user %fs and %gs untouched */
  519         PROC_LOCK(p);
  520         mtx_lock(&psp->ps_mtx);
  521 }
  522 
  523 /*
  524  * System call to cleanup state after a signal
  525  * has been taken.  Reset signal mask and
  526  * stack state from context left by sendsig (above).
  527  * Return to previous pc and psl as specified by
  528  * context left by sendsig. Check carefully to
  529  * make sure that the user has not modified the
  530  * psl to gain improper privileges or to cause
  531  * a machine fault.
  532  */
  533 int
  534 linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
  535 {
  536         struct proc *p = td->td_proc;
  537         struct l_sigframe frame;
  538         struct trapframe *regs;
  539         l_sigset_t lmask;
  540         int eflags, i;
  541 
  542         regs = td->td_frame;
  543 
  544 #ifdef DEBUG
  545         if (ldebug(sigreturn))
  546                 printf(ARGS(sigreturn, "%p"), (void *)args->sfp);
  547 #endif
  548         /*
  549          * The trampoline code hands us the sigframe.
  550          * It is unsafe to keep track of it ourselves, in the event that a
  551          * program jumps out of a signal handler.
  552          */
  553         if (copyin(args->sfp, &frame, sizeof(frame)) != 0)
  554                 return (EFAULT);
  555 
  556         /*
  557          * Check for security violations.
  558          */
  559 #define EFLAGS_SECURE(ef, oef)  ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
  560         eflags = frame.sf_sc.sc_eflags;
  561         /*
  562          * XXX do allow users to change the privileged flag PSL_RF.  The
  563          * cpu sets PSL_RF in tf_eflags for faults.  Debuggers should
  564          * sometimes set it there too.  tf_eflags is kept in the signal
  565          * context during signal handling and there is no other place
  566          * to remember it, so the PSL_RF bit may be corrupted by the
  567          * signal handler without us knowing.  Corruption of the PSL_RF
  568          * bit at worst causes one more or one less debugger trap, so
  569          * allowing it is fairly harmless.
  570          */
  571         if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF))
  572                 return(EINVAL);
  573 
  574         /*
  575          * Don't allow users to load a valid privileged %cs.  Let the
  576          * hardware check for invalid selectors, excess privilege in
  577          * other selectors, invalid %eip's and invalid %esp's.
  578          */
  579 #define CS_SECURE(cs)   (ISPL(cs) == SEL_UPL)
  580         if (!CS_SECURE(frame.sf_sc.sc_cs)) {
  581                 trapsignal(td, SIGBUS, T_PROTFLT);
  582                 return(EINVAL);
  583         }
  584 
  585         lmask.__bits[0] = frame.sf_sc.sc_mask;
  586         for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
  587                 lmask.__bits[i+1] = frame.sf_extramask[i];
  588         PROC_LOCK(p);
  589         linux_to_bsd_sigset(&lmask, &td->td_sigmask);
  590         SIG_CANTMASK(td->td_sigmask);
  591         signotify(td);
  592         PROC_UNLOCK(p);
  593 
  594         /*
  595          * Restore signal context.
  596          */
  597         /* Selectors were restored by the trampoline. */
  598         regs->tf_rdi    = frame.sf_sc.sc_edi;
  599         regs->tf_rsi    = frame.sf_sc.sc_esi;
  600         regs->tf_rbp    = frame.sf_sc.sc_ebp;
  601         regs->tf_rbx    = frame.sf_sc.sc_ebx;
  602         regs->tf_rdx    = frame.sf_sc.sc_edx;
  603         regs->tf_rcx    = frame.sf_sc.sc_ecx;
  604         regs->tf_rax    = frame.sf_sc.sc_eax;
  605         regs->tf_rip    = frame.sf_sc.sc_eip;
  606         regs->tf_cs     = frame.sf_sc.sc_cs;
  607         regs->tf_rflags = eflags;
  608         regs->tf_rsp    = frame.sf_sc.sc_esp_at_signal;
  609         regs->tf_ss     = frame.sf_sc.sc_ss;
  610 
  611         return (EJUSTRETURN);
  612 }
  613 
  614 /*
  615  * System call to cleanup state after a signal
  616  * has been taken.  Reset signal mask and
  617  * stack state from context left by rt_sendsig (above).
  618  * Return to previous pc and psl as specified by
  619  * context left by sendsig. Check carefully to
  620  * make sure that the user has not modified the
  621  * psl to gain improper privileges or to cause
  622  * a machine fault.
  623  */
  624 int
  625 linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
  626 {
  627         struct proc *p = td->td_proc;
  628         struct l_ucontext uc;
  629         struct l_sigcontext *context;
  630         l_stack_t *lss;
  631         stack_t ss;
  632         struct trapframe *regs;
  633         int eflags;
  634 
  635         regs = td->td_frame;
  636 
  637 #ifdef DEBUG
  638         if (ldebug(rt_sigreturn))
  639                 printf(ARGS(rt_sigreturn, "%p"), (void *)args->ucp);
  640 #endif
  641         /*
  642          * The trampoline code hands us the ucontext.
  643          * It is unsafe to keep track of it ourselves, in the event that a
  644          * program jumps out of a signal handler.
  645          */
  646         if (copyin(args->ucp, &uc, sizeof(uc)) != 0)
  647                 return (EFAULT);
  648 
  649         context = &uc.uc_mcontext;
  650 
  651         /*
  652          * Check for security violations.
  653          */
  654 #define EFLAGS_SECURE(ef, oef)  ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
  655         eflags = context->sc_eflags;
  656         /*
  657          * XXX do allow users to change the privileged flag PSL_RF.  The
  658          * cpu sets PSL_RF in tf_eflags for faults.  Debuggers should
  659          * sometimes set it there too.  tf_eflags is kept in the signal
  660          * context during signal handling and there is no other place
  661          * to remember it, so the PSL_RF bit may be corrupted by the
  662          * signal handler without us knowing.  Corruption of the PSL_RF
  663          * bit at worst causes one more or one less debugger trap, so
  664          * allowing it is fairly harmless.
  665          */
  666         if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF))
  667                 return(EINVAL);
  668 
  669         /*
  670          * Don't allow users to load a valid privileged %cs.  Let the
  671          * hardware check for invalid selectors, excess privilege in
  672          * other selectors, invalid %eip's and invalid %esp's.
  673          */
  674 #define CS_SECURE(cs)   (ISPL(cs) == SEL_UPL)
  675         if (!CS_SECURE(context->sc_cs)) {
  676                 trapsignal(td, SIGBUS, T_PROTFLT);
  677                 return(EINVAL);
  678         }
  679 
  680         PROC_LOCK(p);
  681         linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask);
  682         SIG_CANTMASK(td->td_sigmask);
  683         signotify(td);
  684         PROC_UNLOCK(p);
  685 
  686         /*
  687          * Restore signal context
  688          */
  689         /* Selectors were restored by the trampoline. */
  690         regs->tf_rdi    = context->sc_edi;
  691         regs->tf_rsi    = context->sc_esi;
  692         regs->tf_rbp    = context->sc_ebp;
  693         regs->tf_rbx    = context->sc_ebx;
  694         regs->tf_rdx    = context->sc_edx;
  695         regs->tf_rcx    = context->sc_ecx;
  696         regs->tf_rax    = context->sc_eax;
  697         regs->tf_rip    = context->sc_eip;
  698         regs->tf_cs     = context->sc_cs;
  699         regs->tf_rflags = eflags;
  700         regs->tf_rsp    = context->sc_esp_at_signal;
  701         regs->tf_ss     = context->sc_ss;
  702 
  703         /*
  704          * call sigaltstack & ignore results..
  705          */
  706         lss = &uc.uc_stack;
  707         ss.ss_sp = PTRIN(lss->ss_sp);
  708         ss.ss_size = lss->ss_size;
  709         ss.ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags);
  710 
  711 #ifdef DEBUG
  712         if (ldebug(rt_sigreturn))
  713                 printf(LMSG("rt_sigret flags: 0x%x, sp: %p, ss: 0x%lx, mask: 0x%x"),
  714                     ss.ss_flags, ss.ss_sp, ss.ss_size, context->sc_mask);
  715 #endif
  716         (void)kern_sigaltstack(td, &ss, NULL);
  717 
  718         return (EJUSTRETURN);
  719 }
  720 
  721 /*
  722  * MPSAFE
  723  */
  724 static void
  725 linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
  726 {
  727         args[0] = tf->tf_rbx;
  728         args[1] = tf->tf_rcx;
  729         args[2] = tf->tf_rdx;
  730         args[3] = tf->tf_rsi;
  731         args[4] = tf->tf_rdi;
  732         args[5] = tf->tf_rbp;   /* Unconfirmed */
  733         *params = NULL;         /* no copyin */
  734 }
  735 
  736 /*
  737  * If a linux binary is exec'ing something, try this image activator
  738  * first.  We override standard shell script execution in order to
  739  * be able to modify the interpreter path.  We only do this if a linux
  740  * binary is doing the exec, so we do not create an EXEC module for it.
  741  */
  742 static int      exec_linux_imgact_try(struct image_params *iparams);
  743 
  744 static int
  745 exec_linux_imgact_try(struct image_params *imgp)
  746 {
  747     const char *head = (const char *)imgp->image_header;
  748     char *rpath;
  749     int error = -1, len;
  750 
  751     /*
  752      * The interpreter for shell scripts run from a linux binary needs
  753      * to be located in /compat/linux if possible in order to recursively
  754      * maintain linux path emulation.
  755      */
  756     if (((const short *)head)[0] == SHELLMAGIC) {
  757             /*
  758              * Run our normal shell image activator.  If it succeeds attempt
  759              * to use the alternate path for the interpreter.  If an alternate
  760              * path is found, use our stringspace to store it.
  761              */
  762             if ((error = exec_shell_imgact(imgp)) == 0) {
  763                     linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
  764                         imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0);
  765                     if (rpath != NULL) {
  766                             len = strlen(rpath) + 1;
  767 
  768                             if (len <= MAXSHELLCMDLEN) {
  769                                     memcpy(imgp->interpreter_name, rpath, len);
  770                             }
  771                             free(rpath, M_TEMP);
  772                     }
  773             }
  774     }
  775     return(error);
  776 }
  777 
  778 /*
  779  * Clear registers on exec
  780  * XXX copied from ia32_signal.c.
  781  */
  782 static void
  783 exec_linux_setregs(td, entry, stack, ps_strings)
  784         struct thread *td;
  785         u_long entry;
  786         u_long stack;
  787         u_long ps_strings;
  788 {
  789         struct trapframe *regs = td->td_frame;
  790         struct pcb *pcb = td->td_pcb;
  791 
  792         wrmsr(MSR_FSBASE, 0);
  793         wrmsr(MSR_KGSBASE, 0);  /* User value while we're in the kernel */
  794         pcb->pcb_fsbase = 0;
  795         pcb->pcb_gsbase = 0;
  796         load_ds(_udatasel);
  797         load_es(_udatasel);
  798         load_fs(_udatasel);
  799         load_gs(0);
  800         pcb->pcb_ds = _udatasel;
  801         pcb->pcb_es = _udatasel;
  802         pcb->pcb_fs = _udatasel;
  803         pcb->pcb_gs = 0;
  804 
  805         bzero((char *)regs, sizeof(struct trapframe));
  806         regs->tf_rip = entry;
  807         regs->tf_rsp = stack;
  808         regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
  809         regs->tf_ss = _udatasel;
  810         regs->tf_cs = _ucode32sel;
  811         regs->tf_rbx = ps_strings;
  812         load_cr0(rcr0() | CR0_MP | CR0_TS);
  813         fpstate_drop(td);
  814 
  815         /* Return via doreti so that we can change to a different %cs */
  816         pcb->pcb_flags |= PCB_FULLCTX;
  817         td->td_retval[1] = 0;
  818 }
  819 
  820 /*
  821  * XXX copied from ia32_sysvec.c.
  822  */
  823 static register_t *
  824 linux_copyout_strings(struct image_params *imgp)
  825 {
  826         int argc, envc;
  827         u_int32_t *vectp;
  828         char *stringp, *destp;
  829         u_int32_t *stack_base;
  830         struct linux32_ps_strings *arginfo;
  831         int sigcodesz;
  832 
  833         /*
  834          * Calculate string base and vector table pointers.
  835          * Also deal with signal trampoline code for this exec type.
  836          */
  837         arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
  838         sigcodesz = *(imgp->proc->p_sysent->sv_szsigcode);
  839         destp = (caddr_t)arginfo - sigcodesz - SPARE_USRSPACE -
  840                 roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
  841 
  842         /*
  843          * install sigcode
  844          */
  845         if (sigcodesz)
  846                 copyout(imgp->proc->p_sysent->sv_sigcode,
  847                         ((caddr_t)arginfo - sigcodesz), sigcodesz);
  848 
  849         /*
  850          * If we have a valid auxargs ptr, prepare some room
  851          * on the stack.
  852          */
  853         if (imgp->auxargs) {
  854                 /*
  855                  * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
  856                  * lower compatibility.
  857                  */
  858                 imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
  859                         : (AT_COUNT * 2);
  860                 /*
  861                  * The '+ 2' is for the null pointers at the end of each of
  862                  * the arg and env vector sets,and imgp->auxarg_size is room
  863                  * for argument of Runtime loader.
  864                  */
  865                 vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 +
  866                                        imgp->auxarg_size) * sizeof(u_int32_t));
  867 
  868         } else
  869                 /*
  870                  * The '+ 2' is for the null pointers at the end of each of
  871                  * the arg and env vector sets
  872                  */
  873                 vectp = (u_int32_t *)
  874                         (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
  875 
  876         /*
  877          * vectp also becomes our initial stack base
  878          */
  879         stack_base = vectp;
  880 
  881         stringp = imgp->args->begin_argv;
  882         argc = imgp->args->argc;
  883         envc = imgp->args->envc;
  884         /*
  885          * Copy out strings - arguments and environment.
  886          */
  887         copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
  888 
  889         /*
  890          * Fill in "ps_strings" struct for ps, w, etc.
  891          */
  892         suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
  893         suword32(&arginfo->ps_nargvstr, argc);
  894 
  895         /*
  896          * Fill in argument portion of vector table.
  897          */
  898         for (; argc > 0; --argc) {
  899                 suword32(vectp++, (u_int32_t)(intptr_t)destp);
  900                 while (*stringp++ != 0)
  901                         destp++;
  902                 destp++;
  903         }
  904 
  905         /* a null vector table pointer separates the argp's from the envp's */
  906         suword32(vectp++, 0);
  907 
  908         suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
  909         suword32(&arginfo->ps_nenvstr, envc);
  910 
  911         /*
  912          * Fill in environment portion of vector table.
  913          */
  914         for (; envc > 0; --envc) {
  915                 suword32(vectp++, (u_int32_t)(intptr_t)destp);
  916                 while (*stringp++ != 0)
  917                         destp++;
  918                 destp++;
  919         }
  920 
  921         /* end of vector table is a null pointer */
  922         suword32(vectp, 0);
  923 
  924         return ((register_t *)stack_base);
  925 }
  926 
  927 SYSCTL_NODE(_compat, OID_AUTO, linux32, CTLFLAG_RW, 0,
  928     "32-bit Linux emulation");
  929 
  930 static u_long   linux32_maxdsiz = LINUX32_MAXDSIZ;
  931 SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxdsiz, CTLFLAG_RW,
  932     &linux32_maxdsiz, 0, "");
  933 static u_long   linux32_maxssiz = LINUX32_MAXSSIZ;
  934 SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxssiz, CTLFLAG_RW,
  935     &linux32_maxssiz, 0, "");
  936 static u_long   linux32_maxvmem = LINUX32_MAXVMEM;
  937 SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
  938     &linux32_maxvmem, 0, "");
  939 
  940 static void
  941 linux32_fixlimit(struct rlimit *rl, int which)
  942 {
  943 
  944         switch (which) {
  945         case RLIMIT_DATA:
  946                 if (linux32_maxdsiz != 0) {                     
  947                         if (rl->rlim_cur > linux32_maxdsiz)
  948                                 rl->rlim_cur = linux32_maxdsiz;
  949                         if (rl->rlim_max > linux32_maxdsiz)
  950                                 rl->rlim_max = linux32_maxdsiz;
  951                 }
  952                 break;
  953         case RLIMIT_STACK:
  954                 if (linux32_maxssiz != 0) {
  955                         if (rl->rlim_cur > linux32_maxssiz)
  956                                 rl->rlim_cur = linux32_maxssiz;
  957                         if (rl->rlim_max > linux32_maxssiz)
  958                                 rl->rlim_max = linux32_maxssiz;
  959                 }
  960                 break;
  961         case RLIMIT_VMEM:
  962                 if (linux32_maxvmem != 0) {
  963                         if (rl->rlim_cur > linux32_maxvmem)
  964                                 rl->rlim_cur = linux32_maxvmem;
  965                         if (rl->rlim_max > linux32_maxvmem)
  966                                 rl->rlim_max = linux32_maxvmem;
  967                 }
  968                 break;
  969         }
  970 }
  971 
  972 struct sysentvec elf_linux_sysvec = {
  973         LINUX_SYS_MAXSYSCALL,
  974         linux_sysent,
  975         0,
  976         LINUX_SIGTBLSZ,
  977         bsd_to_linux_signal,
  978         ELAST + 1,
  979         bsd_to_linux_errno,
  980         translate_traps,
  981         elf_linux_fixup,
  982         linux_sendsig,
  983         linux_sigcode,
  984         &linux_szsigcode,
  985         linux_prepsyscall,
  986         "Linux ELF32",
  987         elf32_coredump,
  988         exec_linux_imgact_try,
  989         LINUX_MINSIGSTKSZ,
  990         PAGE_SIZE,
  991         VM_MIN_ADDRESS,
  992         LINUX32_USRSTACK,
  993         LINUX32_USRSTACK,
  994         LINUX32_PS_STRINGS,
  995         VM_PROT_ALL,
  996         linux_copyout_strings,
  997         exec_linux_setregs,
  998         linux32_fixlimit
  999 };
 1000 
 1001 static Elf32_Brandinfo linux_brand = {
 1002                                         ELFOSABI_LINUX,
 1003                                         EM_386,
 1004                                         "Linux",
 1005                                         "/compat/linux",
 1006                                         "/lib/ld-linux.so.1",
 1007                                         &elf_linux_sysvec,
 1008                                         NULL,
 1009                                  };
 1010 
 1011 static Elf32_Brandinfo linux_glibc2brand = {
 1012                                         ELFOSABI_LINUX,
 1013                                         EM_386,
 1014                                         "Linux",
 1015                                         "/compat/linux",
 1016                                         "/lib/ld-linux.so.2",
 1017                                         &elf_linux_sysvec,
 1018                                         NULL,
 1019                                  };
 1020 
 1021 Elf32_Brandinfo *linux_brandlist[] = {
 1022                                         &linux_brand,
 1023                                         &linux_glibc2brand,
 1024                                         NULL
 1025                                 };
 1026 
 1027 static int
 1028 linux_elf_modevent(module_t mod, int type, void *data)
 1029 {
 1030         Elf32_Brandinfo **brandinfo;
 1031         int error;
 1032         struct linux_ioctl_handler **lihp;
 1033         struct linux_device_handler **ldhp;
 1034 
 1035         error = 0;
 1036 
 1037         switch(type) {
 1038         case MOD_LOAD:
 1039                 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
 1040                      ++brandinfo)
 1041                         if (elf32_insert_brand_entry(*brandinfo) < 0)
 1042                                 error = EINVAL;
 1043                 if (error == 0) {
 1044                         SET_FOREACH(lihp, linux_ioctl_handler_set)
 1045                                 linux_ioctl_register_handler(*lihp);
 1046                         SET_FOREACH(ldhp, linux_device_handler_set)
 1047                                 linux_device_register_handler(*ldhp);
 1048                         if (bootverbose)
 1049                                 printf("Linux ELF exec handler installed\n");
 1050                 } else
 1051                         printf("cannot insert Linux ELF brand handler\n");
 1052                 break;
 1053         case MOD_UNLOAD:
 1054                 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
 1055                      ++brandinfo)
 1056                         if (elf32_brand_inuse(*brandinfo))
 1057                                 error = EBUSY;
 1058                 if (error == 0) {
 1059                         for (brandinfo = &linux_brandlist[0];
 1060                              *brandinfo != NULL; ++brandinfo)
 1061                                 if (elf32_remove_brand_entry(*brandinfo) < 0)
 1062                                         error = EINVAL;
 1063                 }
 1064                 if (error == 0) {
 1065                         SET_FOREACH(lihp, linux_ioctl_handler_set)
 1066                                 linux_ioctl_unregister_handler(*lihp);
 1067                         SET_FOREACH(ldhp, linux_device_handler_set)
 1068                                 linux_device_unregister_handler(*ldhp);
 1069                         if (bootverbose)
 1070                                 printf("Linux ELF exec handler removed\n");
 1071                 } else
 1072                         printf("Could not deinstall ELF interpreter entry\n");
 1073                 break;
 1074         default:
 1075                 break;
 1076         }
 1077         return error;
 1078 }
 1079 
 1080 static moduledata_t linux_elf_mod = {
 1081         "linuxelf",
 1082         linux_elf_modevent,
 1083         0
 1084 };
 1085 
 1086 DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);

Cache object: a44d8785da227905e67f615880ac5a28


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.