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/compat/irix/irix_exec.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 /*      $NetBSD: irix_exec.c,v 1.52 2008/04/29 15:56:11 ad Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.52 2008/04/29 15:56:11 ad Exp $");
   34 
   35 #ifdef _KERNEL_OPT
   36 #include "opt_syscall_debug.h"
   37 #endif
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/proc.h>
   42 #include <sys/rwlock.h>
   43 #include <sys/exec.h>
   44 #include <sys/types.h>
   45 #include <sys/malloc.h>
   46 
   47 #include <machine/regnum.h>
   48 #include <uvm/uvm_extern.h>
   49 
   50 #include <compat/irix/irix_syscall.h>
   51 #include <compat/irix/irix_types.h>
   52 #include <compat/irix/irix_exec.h>
   53 #include <compat/irix/irix_prctl.h>
   54 #include <compat/irix/irix_signal.h>
   55 #include <compat/irix/irix_errno.h>
   56 #include <compat/irix/irix_sysctl.h>
   57 #include <compat/irix/irix_usema.h>
   58 
   59 extern const int native_to_svr4_signo[];
   60 
   61 static void irix_e_proc_exec(struct proc *, struct exec_package *);
   62 static void irix_e_proc_fork(struct proc *, struct proc *, int);
   63 static void irix_e_proc_exit(struct proc *);
   64 static void irix_e_proc_init(struct proc *, struct vmspace *);
   65 
   66 extern struct sysent irix_sysent[];
   67 extern const char * const irix_syscallnames[];
   68 
   69 #ifndef __HAVE_SYSCALL_INTERN
   70 void irix_syscall(void);
   71 #else
   72 void irix_syscall_intern(struct proc *);
   73 #endif
   74 
   75 /*
   76  * Fake sigcode. COMPAT_IRIX does not use it, since the
   77  * signal trampoline is provided by libc. However, some
   78  * other part of the kernel will be happier if we still
   79  * provide non NULL sigcode and esigcode.
   80  */
   81 char irix_sigcode[] = { 0 };
   82 
   83 const struct emul emul_irix = {
   84         "irix",
   85         "/emul/irix",
   86 #ifndef __HAVE_MINIMAL_EMUL
   87         0,
   88         native_to_irix_errno,
   89         IRIX_SYS_syscall,
   90         IRIX_SYS_NSYSENT,
   91 #endif
   92         irix_sysent,
   93 #ifdef SYSCALL_DEBUG
   94         irix_syscallnames,
   95 #else
   96         NULL,
   97 #endif
   98         irix_sendsig,
   99         trapsignal,
  100         NULL,
  101         irix_sigcode,
  102         irix_sigcode,
  103         NULL,
  104         setregs,
  105         irix_e_proc_exec,
  106         irix_e_proc_fork,
  107         irix_e_proc_exit,
  108         NULL,
  109         NULL,
  110 #ifdef __HAVE_SYSCALL_INTERN
  111         irix_syscall_intern,
  112 #else
  113         irix_syscall,
  114 #endif
  115         NULL,
  116         irix_vm_fault,
  117 
  118         uvm_default_mapaddr,
  119 };
  120 
  121 /*
  122  * set registers on exec for N32 applications
  123  */
  124 void
  125 irix_n32_setregs(struct lwp *l, struct exec_package *pack, u_long stack)
  126 {
  127         struct frame *f = (struct frame *)l->l_md.md_regs;
  128 
  129         /* Enable 64 bit instructions (eg: sd) */
  130         f->f_regs[_R_SR] |= MIPS3_SR_UX;
  131 }
  132 
  133 /*
  134  * per-process emuldata allocation
  135  */
  136 static void
  137 irix_e_proc_init(struct proc *p, struct vmspace *vmspace)
  138 {
  139         struct irix_emuldata *ied;
  140         vaddr_t vm_min;
  141         vsize_t vm_len;
  142 
  143         if (!p->p_emuldata)
  144                 p->p_emuldata = malloc(sizeof(struct irix_emuldata),
  145                     M_EMULDATA, M_WAITOK | M_ZERO);
  146 
  147         ied = p->p_emuldata;
  148         ied->ied_p = p;
  149 
  150         LIST_INIT(&ied->ied_shared_regions);
  151         vm_min = vm_map_min(&vmspace->vm_map);
  152         vm_len = vm_map_max(&vmspace->vm_map) - vm_min;
  153         irix_isrr_insert(vm_min, vm_len, IRIX_ISRR_SHARED, p);
  154 }
  155 
  156 /*
  157  * exec() hook used to allocate per process structures
  158  */
  159 static void
  160 irix_e_proc_exec(struct proc *p, struct exec_package *epp)
  161 {
  162         int error;
  163 
  164         irix_e_proc_init(p, p->p_vmspace);
  165 
  166         /* Initialize the process private area (PRDA) */
  167         error = irix_prda_init(p);
  168 #ifdef DEBUG_IRIX
  169         if (error != 0)
  170                 printf("irix_e_proc_exec(): PRDA map failed ");
  171 #endif
  172 }
  173 
  174 /*
  175  * exit() hook used to free per process data structures
  176  */
  177 static void
  178 irix_e_proc_exit(struct proc *p)
  179 {
  180         struct proc *pp;
  181         struct irix_emuldata *ied;
  182         struct irix_share_group *isg;
  183         struct irix_shared_regions_rec *isrr;
  184 
  185         /*
  186          * Send SIGHUP to child process as requested using prctl(2)
  187          */
  188         mutex_enter(proc_lock);
  189         PROCLIST_FOREACH(pp, &allproc) {
  190                 if ((pp->p_flag & PK_MARKER) != 0)
  191                         continue;
  192                 /* Select IRIX processes */
  193                 if (irix_check_exec(pp) == 0)
  194                         continue;
  195 
  196                 ied = (struct irix_emuldata *)(pp->p_emuldata);
  197                 if (ied->ied_termchild && pp->p_pptr == p)
  198                         psignal(pp, native_to_svr4_signo[SIGHUP]);
  199         }
  200         mutex_exit(proc_lock);
  201 
  202         /*
  203          * Remove the process from share group processes list, if relevant.
  204          */
  205         ied = (struct irix_emuldata *)(p->p_emuldata);
  206 
  207         if ((isg = ied->ied_share_group) != NULL) {
  208                 rw_enter(&isg->isg_lock, RW_WRITER);
  209                 LIST_REMOVE(ied, ied_sglist);
  210                 isg->isg_refcount--;
  211 
  212                 if (isg->isg_refcount == 0) {
  213                         /*
  214                          * This was the last process in the share group.
  215                          * Call irix_usema_exit_cleanup() to free in-kernel
  216                          * structures hold by the share group through
  217                          * the irix_usync_cntl system call.
  218                          */
  219                         irix_usema_exit_cleanup(p, NULL);
  220                          /*
  221                           * Free the share group structure (no need to free
  222                           * the lock since we destroy it now).
  223                           */
  224                         rw_destroy(&isg->isg_lock);
  225                         free(isg, M_EMULDATA);
  226                         ied->ied_share_group = NULL;
  227                 } else {
  228                         /*
  229                          * There are other processes remaining in the share
  230                          * group. Call irix_usema_exit_cleanup() to set the
  231                          * first of them as the owner of the structures
  232                          * hold in the kernel by the share group.
  233                          */
  234                         irix_usema_exit_cleanup(p,
  235                             LIST_FIRST(&isg->isg_head)->ied_p);
  236                         rw_exit(&isg->isg_lock);
  237                 }
  238 
  239         } else {
  240                 /*
  241                  * The process is not part of a share group. Call
  242                  * irix_usema_exit_cleanup() to free in-kernel structures hold
  243                  * by the process through the irix_usync_cntl system call.
  244                  */
  245                 irix_usema_exit_cleanup(p, NULL);
  246         }
  247 
  248         /* Free (un)shared region list */
  249         while (!LIST_EMPTY(&ied->ied_shared_regions)) {
  250                 isrr = LIST_FIRST(&ied->ied_shared_regions);
  251                 LIST_REMOVE(isrr , isrr_list);
  252                 free(isrr, M_EMULDATA);
  253         }
  254 
  255         free(p->p_emuldata, M_EMULDATA);
  256         p->p_emuldata = NULL;
  257 }
  258 
  259 /*
  260  * fork() hook used to allocate per process structures
  261  */
  262 static void
  263 irix_e_proc_fork(p, parent, forkflags)
  264         struct proc *p, *parent;
  265         int forkflags;
  266 {
  267         struct irix_emuldata *ied1;
  268         struct irix_emuldata *ied2;
  269 
  270         p->p_emuldata = NULL;
  271 
  272         /* Use parent's vmspace because our vmspace may not be setup yet */
  273         irix_e_proc_init(p, parent->p_vmspace);
  274 
  275         ied1 = p->p_emuldata;
  276         ied2 = parent->p_emuldata;
  277 
  278         (void) memcpy(ied1, ied2, (unsigned)
  279             ((char *)&ied1->ied_endcopy - (char *)&ied1->ied_startcopy));
  280 }

Cache object: 0edbca0fa479726b0e1e35aa64f77142


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