root/kern/exec_ecoff.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. exec_ecoff_makecmds
  2. exec_ecoff_prep_omagic
  3. exec_ecoff_prep_nmagic
  4. exec_ecoff_prep_zmagic

    1 /*      $OpenBSD: exec_ecoff.c,v 1.10 2005/11/12 04:31:24 jsg Exp $     */
    2 /*      $NetBSD: exec_ecoff.c,v 1.8 1996/05/19 20:36:06 jonathan Exp $  */
    3 
    4 /*
    5  * Copyright (c) 1994 Adam Glass
    6  * Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by Christopher G. Demetriou.
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/proc.h>
   38 #include <sys/malloc.h>
   39 #include <sys/vnode.h>
   40 #include <sys/exec.h>
   41 #include <sys/resourcevar.h>
   42 #include <uvm/uvm_extern.h>
   43 
   44 #if defined(_KERN_DO_ECOFF)
   45 
   46 #include <sys/exec_ecoff.h>
   47 
   48 /*
   49  * exec_ecoff_makecmds(): Check if it's an ecoff-format executable.
   50  *
   51  * Given a proc pointer and an exec package pointer, see if the referent
   52  * of the epp is in ecoff format.  Check 'standard' magic numbers for
   53  * this architecture.  If that fails, return failure.
   54  *
   55  * This function is  responsible for creating a set of vmcmds which can be
   56  * used to build the process's vm space and inserting them into the exec
   57  * package.
   58  */
   59 int
   60 exec_ecoff_makecmds(struct proc *p, struct exec_package *epp)
   61 {
   62         int error;
   63         struct ecoff_exechdr *execp = epp->ep_hdr;
   64 
   65         if (epp->ep_hdrvalid < ECOFF_HDR_SIZE)
   66                 return ENOEXEC;
   67 
   68         if (ECOFF_BADMAG(execp))
   69                 return ENOEXEC;
   70 
   71         switch (execp->a.magic) {
   72         case ECOFF_OMAGIC:
   73                 error = exec_ecoff_prep_omagic(p, epp);
   74                 break;
   75         case ECOFF_NMAGIC:
   76                 error = exec_ecoff_prep_nmagic(p, epp);
   77                 break;
   78         case ECOFF_ZMAGIC:
   79                 error = exec_ecoff_prep_zmagic(p, epp);
   80                 break;
   81         default:
   82                 return ENOEXEC;
   83         }
   84 
   85         if (error == 0)
   86                 error = cpu_exec_ecoff_hook(p, epp);
   87 
   88         if (error)
   89                 kill_vmcmds(&epp->ep_vmcmds);
   90 
   91         return error;
   92 }
   93 
   94 /*
   95  * exec_ecoff_prep_omagic(): Prepare a ECOFF OMAGIC binary's exec package
   96  */
   97 int
   98 exec_ecoff_prep_omagic(struct proc *p, struct exec_package *epp)
   99 {
  100         struct ecoff_exechdr *execp = epp->ep_hdr;
  101         struct ecoff_aouthdr *eap = &execp->a;
  102 
  103         epp->ep_taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
  104         epp->ep_tsize = eap->tsize;
  105         epp->ep_daddr = ECOFF_SEGMENT_ALIGN(execp, eap->data_start);
  106         epp->ep_dsize = eap->dsize + eap->bsize;
  107         epp->ep_entry = eap->entry;
  108 
  109         /* set up command for text and data segments */
  110         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
  111             eap->tsize + eap->dsize, epp->ep_taddr, epp->ep_vp,
  112             ECOFF_TXTOFF(execp),
  113             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  114 
  115         /* set up command for bss segment */
  116         if (eap->bsize > 0)
  117                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, eap->bsize,
  118                     ECOFF_SEGMENT_ALIGN(execp, eap->bss_start), NULLVP, 0,
  119                     VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  120 
  121         return exec_setup_stack(p, epp);
  122 }
  123 
  124 /*
  125  * exec_ecoff_prep_nmagic(): Prepare a 'native' NMAGIC ECOFF binary's exec
  126  *                           package.
  127  */
  128 int
  129 exec_ecoff_prep_nmagic(struct proc *p, struct exec_package *epp)
  130 {
  131         struct ecoff_exechdr *execp = epp->ep_hdr;
  132         struct ecoff_aouthdr *eap = &execp->a;
  133 
  134         epp->ep_taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
  135         epp->ep_tsize = eap->tsize;
  136         epp->ep_daddr = ECOFF_ROUND(eap->data_start, ECOFF_LDPGSZ);
  137         epp->ep_dsize = eap->dsize + eap->bsize;
  138         epp->ep_entry = eap->entry;
  139 
  140         /* set up command for text segment */
  141         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
  142             epp->ep_taddr, epp->ep_vp, ECOFF_TXTOFF(execp),
  143             VM_PROT_READ|VM_PROT_EXECUTE);
  144 
  145         /* set up command for data segment */
  146         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_dsize,
  147             epp->ep_daddr, epp->ep_vp, ECOFF_DATOFF(execp),
  148             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  149 
  150         /* set up command for bss segment */
  151         if (eap->bsize > 0)
  152                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, eap->bsize,
  153                     ECOFF_SEGMENT_ALIGN(execp, eap->bss_start), NULLVP, 0,
  154                     VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  155 
  156         return exec_setup_stack(p, epp);
  157 }
  158 
  159 /*
  160  * exec_ecoff_prep_zmagic(): Prepare a ECOFF ZMAGIC binary's exec package
  161  *
  162  * First, set the various offsets/lengths in the exec package.
  163  *
  164  * Then, mark the text image busy (so it can be demand paged) or error
  165  * out if this is not possible.  Finally, set up vmcmds for the
  166  * text, data, bss, and stack segments.
  167  */
  168 int
  169 exec_ecoff_prep_zmagic(struct proc *p, struct exec_package *epp)
  170 {
  171         struct ecoff_exechdr *execp = epp->ep_hdr;
  172         struct ecoff_aouthdr *eap = &execp->a;
  173 
  174         epp->ep_taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
  175         epp->ep_tsize = eap->tsize;
  176         epp->ep_daddr = ECOFF_SEGMENT_ALIGN(execp, eap->data_start);
  177         epp->ep_dsize = eap->dsize + eap->bsize;
  178         epp->ep_entry = eap->entry;
  179 
  180         /*
  181          * check if vnode is in open for writing, because we want to
  182          * demand-page out of it.  if it is, don't do it, for various
  183          * reasons
  184          */
  185         if ((eap->tsize != 0 || eap->dsize != 0) &&
  186             epp->ep_vp->v_writecount != 0) {
  187 #ifdef DIAGNOSTIC
  188                 if (epp->ep_vp->v_flag & VTEXT)
  189                         panic("exec: a VTEXT vnode has writecount != 0");
  190 #endif
  191                 return ETXTBSY;
  192         }
  193         vn_marktext(epp->ep_vp);
  194 
  195         /* set up command for text segment */
  196         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, eap->tsize,
  197             epp->ep_taddr, epp->ep_vp, ECOFF_TXTOFF(execp),
  198             VM_PROT_READ|VM_PROT_EXECUTE);
  199 
  200         /* set up command for data segment */
  201         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, eap->dsize,
  202             epp->ep_daddr, epp->ep_vp, ECOFF_DATOFF(execp),
  203             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  204 
  205         /* set up command for bss segment */
  206         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, eap->bsize,
  207             ECOFF_SEGMENT_ALIGN(execp, eap->bss_start), NULLVP, 0,
  208             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  209 
  210         return exec_setup_stack(p, epp);
  211 }
  212 
  213 #endif /* _KERN_DO_ECOFF */

/* [<][>][^][v][top][bottom][index][help] */