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/i386/linux/linux_sysvec.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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: releng/10.0/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 
   75 MODULE_VERSION(linux, 1);
   76 
   77 MALLOC_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 
   96 extern char linux_sigcode[];
   97 extern int linux_szsigcode;
   98 
   99 extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
  100 
  101 SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
  102 SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
  103 
  104 static int      linux_fixup(register_t **stack_base,
  105                     struct image_params *iparams);
  106 static int      elf_linux_fixup(register_t **stack_base,
  107                     struct image_params *iparams);
  108 static void     linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
  109 static void     exec_linux_setregs(struct thread *td,
  110                     struct image_params *imgp, u_long stack);
  111 static register_t *linux_copyout_strings(struct image_params *imgp);
  112 static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel);
  113 
  114 static int linux_szplatform;
  115 const char *linux_platform;
  116 
  117 static eventhandler_tag linux_exit_tag;
  118 static 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  */
  127 static 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 
  140 int 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 
  151 int 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
  163 static 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  */
  207 static int
  208 translate_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 
  223 static int
  224 linux_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 
  239 static int
  240 elf_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  */
  297 static register_t *
  298 linux_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 
  403 extern int _ucodesel, _udatasel;
  404 extern unsigned long linux_sznonrtsigcode;
  405 
  406 static void
  407 linux_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  */
  540 static void
  541 linux_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  */
  658 int
  659 linux_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  */
  745 int
  746 linux_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 
  838 static int
  839 linux_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  */
  873 static int      exec_linux_imgact_try(struct image_params *iparams);
  874 
  875 static int
  876 exec_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  */
  909 static void
  910 exec_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 
  923 static void
  924 linux_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 
  942 struct 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 };
  978 INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
  979 
  980 struct 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 };
 1016 INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
 1017 
 1018 static char GNU_ABI_VENDOR[] = "GNU";
 1019 static int GNULINUX_ABI_DESC = 0;
 1020 
 1021 static boolean_t
 1022 linux_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 
 1043 static 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 
 1052 static 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 
 1064 static 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 
 1076 Elf32_Brandinfo *linux_brandlist[] = {
 1077         &linux_brand,
 1078         &linux_glibc2brand,
 1079         NULL
 1080 };
 1081 
 1082 static int
 1083 linux_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 
 1154 static moduledata_t linux_elf_mod = {
 1155         "linuxelf",
 1156         linux_elf_modevent,
 1157         0
 1158 };
 1159 
 1160 DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);

Cache object: ee8650e8aa69fdda3dedc02051531a26


[ 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.