root/compat/m68k4k/m68k4k_exec.c

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

DEFINITIONS

This source file includes following definitions.
  1. exec_m68k4k_makecmds
  2. exec_m68k4k_prep_zmagic
  3. exec_m68k4k_prep_nmagic
  4. exec_m68k4k_prep_omagic

    1 /*      $OpenBSD: m68k4k_exec.c,v 1.6 2002/03/14 01:26:50 millert Exp $ */
    2 /*      $NetBSD: m68k4k_exec.c,v 1.1 1996/09/10 22:01:20 thorpej Exp $  */
    3 
    4 /*
    5  * Copyright (c) 1993, 1994 Christopher G. Demetriou
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Christopher G. Demetriou.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 /*
   35  * Exec glue to provide compatibility with older {Net,Open}BSD m68k4k
   36  * exectuables.
   37  *
   38  * Taken directly from kern/exec_aout.c and frobbed to map text and
   39  * data as m68k4k executables expect.
   40  *
   41  * This module only works on machines with PAGE_SIZE == 4096.  It's not clear
   42  * that making it work on other machines is worth the trouble.
   43  */
   44 
   45 #if !defined(__m68k__)
   46 #error YOU GOTTA BE KIDDING!
   47 #endif
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/proc.h>
   52 #include <sys/malloc.h>
   53 #include <sys/vnode.h>
   54 #include <sys/exec.h>
   55 #include <sys/resourcevar.h>
   56 
   57 #include <uvm/uvm_extern.h>
   58 
   59 #include <compat/m68k4k/m68k4k_exec.h>
   60 
   61 int     exec_m68k4k_prep_zmagic(struct proc *, struct exec_package *);
   62 int     exec_m68k4k_prep_nmagic(struct proc *, struct exec_package *);
   63 int     exec_m68k4k_prep_omagic(struct proc *, struct exec_package *);
   64 
   65 /*
   66  * exec_m68k4k_makecmds(): Check if it's an a.out-format executable
   67  * with an m68k4k magic number.
   68  *
   69  * Given a proc pointer and an exec package pointer, see if the referent
   70  * of the epp is in a.out format.  Just check 'standard' magic numbers for
   71  * this architecture.
   72  *
   73  * This function, in the former case, or the hook, in the latter, is
   74  * responsible for creating a set of vmcmds which can be used to build
   75  * the process's vm space and inserting them into the exec package.
   76  */
   77 
   78 int
   79 exec_m68k4k_makecmds(p, epp)
   80         struct proc *p;
   81         struct exec_package *epp;
   82 {
   83         u_long midmag, magic;
   84         u_short mid;
   85         int error;
   86         struct exec *execp = epp->ep_hdr;
   87 
   88         /* See note above... */
   89         if (M68K4K_LDPGSZ != PAGE_SIZE)
   90                 return ENOEXEC;
   91 
   92         if (epp->ep_hdrvalid < sizeof(struct exec))
   93                 return ENOEXEC;
   94 
   95         midmag = ntohl(execp->a_midmag);
   96         mid = (midmag >> 16) & 0x3ff;
   97         magic = midmag & 0xffff;
   98 
   99         midmag = mid << 16 | magic;
  100 
  101         switch (midmag) {
  102         case (MID_M68K4K << 16) | ZMAGIC:
  103                 error = exec_m68k4k_prep_zmagic(p, epp);
  104                 break;
  105         case (MID_M68K4K << 16) | NMAGIC:
  106                 error = exec_m68k4k_prep_nmagic(p, epp);
  107                 break;
  108         case (MID_M68K4K << 16) | OMAGIC:
  109                 error = exec_m68k4k_prep_omagic(p, epp);
  110                 break;
  111         default:
  112                 error = ENOEXEC;
  113         }
  114 
  115         if (error)
  116                 kill_vmcmds(&epp->ep_vmcmds);
  117 
  118         return error;
  119 }
  120 
  121 /*
  122  * exec_m68k4k_prep_zmagic(): Prepare an m68k4k ZMAGIC binary's exec package
  123  *
  124  * First, set of the various offsets/lengths in the exec package.
  125  *
  126  * Then, mark the text image busy (so it can be demand paged) or error
  127  * out if this is not possible.  Finally, set up vmcmds for the
  128  * text, data, bss, and stack segments.
  129  */
  130 
  131 int
  132 exec_m68k4k_prep_zmagic(p, epp)
  133         struct proc *p;
  134         struct exec_package *epp;
  135 {
  136         struct exec *execp = epp->ep_hdr;
  137 
  138         epp->ep_taddr = M68K4K_USRTEXT;
  139         epp->ep_tsize = execp->a_text;
  140         epp->ep_daddr = epp->ep_taddr + execp->a_text;
  141         epp->ep_dsize = execp->a_data + execp->a_bss;
  142         epp->ep_entry = execp->a_entry;
  143 
  144         /*
  145          * check if vnode is in open for writing, because we want to
  146          * demand-page out of it.  if it is, don't do it, for various
  147          * reasons
  148          */
  149         if ((execp->a_text != 0 || execp->a_data != 0) &&
  150             epp->ep_vp->v_writecount != 0) {
  151 #ifdef DIAGNOSTIC
  152                 if (epp->ep_vp->v_flag & VTEXT)
  153                         panic("exec: a VTEXT vnode has writecount != 0");
  154 #endif
  155                 return ETXTBSY;
  156         }
  157         vn_marktext(epp->ep_vp);
  158 
  159         /* set up command for text segment */
  160         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text,
  161             epp->ep_taddr, epp->ep_vp, 0, VM_PROT_READ|VM_PROT_EXECUTE);
  162 
  163         /* set up command for data segment */
  164         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data,
  165             epp->ep_daddr, epp->ep_vp, execp->a_text,
  166             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  167 
  168         /* set up command for bss segment */
  169         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss,
  170             epp->ep_daddr + execp->a_data, NULLVP, 0,
  171             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  172 
  173         return exec_setup_stack(p, epp);
  174 }
  175 
  176 /*
  177  * exec_m68k4k_prep_nmagic(): Prepare a m68k4k NMAGIC binary's exec package
  178  */
  179 
  180 int
  181 exec_m68k4k_prep_nmagic(p, epp)
  182         struct proc *p;
  183         struct exec_package *epp;
  184 {
  185         struct exec *execp = epp->ep_hdr;
  186         long bsize, baddr;
  187 
  188         epp->ep_taddr = M68K4K_USRTEXT;
  189         epp->ep_tsize = execp->a_text;
  190         epp->ep_daddr = roundup(epp->ep_taddr + execp->a_text,
  191             M68K4K_LDPGSZ);
  192         epp->ep_dsize = execp->a_data + execp->a_bss;
  193         epp->ep_entry = execp->a_entry;
  194 
  195         /* set up command for text segment */
  196         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_text,
  197             epp->ep_taddr, epp->ep_vp, sizeof(struct exec),
  198             VM_PROT_READ|VM_PROT_EXECUTE);
  199 
  200         /* set up command for data segment */
  201         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_data,
  202             epp->ep_daddr, epp->ep_vp, execp->a_text + sizeof(struct exec),
  203             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  204 
  205         /* set up command for bss segment */
  206         baddr = round_page(epp->ep_daddr + execp->a_data);
  207         bsize = epp->ep_daddr + epp->ep_dsize - baddr;
  208         if (bsize > 0)
  209                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
  210                     NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  211 
  212         return exec_setup_stack(p, epp);
  213 }
  214 
  215 /*
  216  * exec_m68k4k_prep_omagic(): Prepare a m68k4k OMAGIC binary's exec package
  217  */
  218 
  219 int
  220 exec_m68k4k_prep_omagic(p, epp)
  221         struct proc *p;
  222         struct exec_package *epp;
  223 {
  224         struct exec *execp = epp->ep_hdr;
  225         long dsize, bsize, baddr;
  226 
  227         epp->ep_taddr = M68K4K_USRTEXT;
  228         epp->ep_tsize = execp->a_text;
  229         epp->ep_daddr = epp->ep_taddr + execp->a_text;
  230         epp->ep_dsize = execp->a_data + execp->a_bss;
  231         epp->ep_entry = execp->a_entry;
  232 
  233         /* set up command for text and data segments */
  234         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
  235             execp->a_text + execp->a_data, epp->ep_taddr, epp->ep_vp,
  236             sizeof(struct exec), VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  237 
  238         /* set up command for bss segment */
  239         baddr = round_page(epp->ep_daddr + execp->a_data);
  240         bsize = epp->ep_daddr + epp->ep_dsize - baddr;
  241         if (bsize > 0)
  242                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
  243                     NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  244 
  245         /*
  246          * Make sure (# of pages) mapped above equals (vm_tsize + vm_dsize);
  247          * obreak(2) relies on this fact. Both `vm_tsize' and `vm_dsize' are
  248          * computed (in execve(2)) by rounding *up* `ep_tsize' and `ep_dsize'
  249          * respectively to page boundaries.
  250          * Compensate `ep_dsize' for the amount of data covered by the last
  251          * text page. 
  252          */
  253         dsize = epp->ep_dsize + execp->a_text - round_page(execp->a_text);
  254         epp->ep_dsize = (dsize > 0) ? dsize : 0;
  255         return exec_setup_stack(p, epp);
  256 }

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