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

Cache object: 0951ab0aae88c6f26f16c5df1ab56698


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