root/compat/hpux/m68k/hpux_exec.c

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

DEFINITIONS

This source file includes following definitions.
  1. exec_hpux_makecmds
  2. exec_hpux_prep_nmagic
  3. exec_hpux_prep_zmagic
  4. exec_hpux_prep_omagic
  5. hpux_sys_execv
  6. hpux_sys_execve

    1 /*      $OpenBSD: hpux_exec.c,v 1.2 2005/12/30 19:46:55 miod Exp $      */
    2 /*      $NetBSD: hpux_exec.c,v 1.8 1997/03/16 10:14:44 thorpej Exp $    */
    3 
    4 /*
    5  * Copyright (c) 1995, 1997 Jason R. Thorpe.  All rights reserved.
    6  * Copyright (c) 1993, 1994 Christopher G. Demetriou
    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  *      This product includes software developed by Christopher G. Demetriou.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Glue for exec'ing HP-UX executables and the HP-UX execv() system call.
   35  * Based on sys/kern/exec_aout.c
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/proc.h>
   42 #include <sys/malloc.h>
   43 #include <sys/mount.h>
   44 #include <sys/namei.h>
   45 #include <sys/user.h>
   46 #include <sys/vnode.h>
   47 #include <sys/mman.h>
   48 #include <sys/stat.h>
   49 
   50 #include <uvm/uvm_extern.h>
   51 
   52 #include <machine/cpu.h>
   53 #include <machine/reg.h>
   54 
   55 #include <sys/syscallargs.h>    
   56 
   57 #include <compat/hpux/hpux.h>
   58 #include <compat/hpux/hpux_util.h>
   59 #include <compat/hpux/m68k/hpux_syscall.h>
   60 #include <compat/hpux/m68k/hpux_syscallargs.h>
   61 
   62 #include <machine/hpux_machdep.h>
   63 
   64 const char hpux_emul_path[] = "/emul/hpux";
   65 extern char sigcode[], esigcode[];
   66 extern struct sysent hpux_sysent[];
   67 #ifdef SYSCALL_DEBUG
   68 extern char *hpux_syscallnames[];
   69 #endif
   70 extern int bsdtohpuxerrnomap[];
   71 
   72 static  int exec_hpux_prep_nmagic(struct proc *, struct exec_package *);
   73 static  int exec_hpux_prep_zmagic(struct proc *, struct exec_package *);
   74 static  int exec_hpux_prep_omagic(struct proc *, struct exec_package *);
   75 
   76 struct emul emul_hpux = {
   77         "hpux",
   78         bsdtohpuxerrnomap,
   79         hpux_sendsig,
   80         HPUX_SYS_syscall,
   81         HPUX_SYS_MAXSYSCALL,
   82         hpux_sysent,
   83 #ifdef SYSCALL_DEBUG
   84         hpux_syscallnames,
   85 #else
   86         NULL,
   87 #endif
   88         0,
   89         copyargs,
   90         hpux_setregs,
   91         NULL,
   92         sigcode,
   93         esigcode,
   94 };
   95 
   96 int
   97 exec_hpux_makecmds(p, epp)
   98         struct proc *p;
   99         struct exec_package *epp;
  100 {
  101         struct hpux_exec *hpux_ep = epp->ep_hdr;
  102         short sysid, magic;
  103         int error = ENOEXEC;
  104 
  105         if (epp->ep_hdrvalid < sizeof(struct hpux_exec))
  106                 return (ENOEXEC);
  107 
  108         magic = HPUX_MAGIC(hpux_ep);
  109         sysid = HPUX_SYSID(hpux_ep);
  110 
  111         if (sysid != MID_HPUX)
  112                 return (ENOEXEC);
  113 
  114         /*
  115          * HP-UX is a 4k page size system, and executables assume
  116          * this.
  117          */
  118         if (PAGE_SIZE != HPUX_LDPGSZ)
  119                 return (ENOEXEC);
  120 
  121         switch (magic) {
  122         case OMAGIC:
  123                 error = exec_hpux_prep_omagic(p, epp);
  124                 break;
  125 
  126         case NMAGIC:
  127                 error = exec_hpux_prep_nmagic(p, epp);
  128                 break;
  129 
  130         case ZMAGIC:
  131                 error = exec_hpux_prep_zmagic(p, epp);
  132                 break;
  133         }
  134 
  135         if (error == 0) {
  136                 /* set up our emulation information */
  137                 epp->ep_emul = &emul_hpux;
  138         } else
  139                 kill_vmcmds(&epp->ep_vmcmds);
  140 
  141         return (error);
  142 }
  143 
  144 static int
  145 exec_hpux_prep_nmagic(p, epp)
  146         struct proc *p;
  147         struct exec_package *epp;
  148 {
  149         struct hpux_exec *execp = epp->ep_hdr;
  150         long bsize, baddr;
  151 
  152         epp->ep_taddr = 0;
  153         epp->ep_tsize = execp->ha_text;
  154         epp->ep_daddr = epp->ep_taddr + roundup(execp->ha_text, HPUX_LDPGSZ);
  155         epp->ep_dsize = execp->ha_data + execp->ha_bss;
  156         epp->ep_entry = execp->ha_entry;
  157 
  158         /* set up command for text segment */
  159         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->ha_text,
  160             epp->ep_taddr, epp->ep_vp, HPUX_TXTOFF(*execp, NMAGIC),
  161             VM_PROT_READ|VM_PROT_EXECUTE);
  162 
  163         /* set up command for data segment */
  164         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->ha_data,
  165             epp->ep_daddr, epp->ep_vp, HPUX_DATAOFF(*execp, NMAGIC),
  166             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  167 
  168         /* set up command for bss segment */
  169         baddr = round_page(epp->ep_daddr + execp->ha_data);
  170         bsize = epp->ep_daddr + epp->ep_dsize - baddr;
  171         if (bsize > 0)
  172                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
  173                     NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  174 
  175         return (exec_setup_stack(p, epp));
  176 }
  177 
  178 static int
  179 exec_hpux_prep_zmagic(p, epp)
  180         struct proc *p;
  181         struct exec_package *epp;
  182 {
  183         struct hpux_exec *execp = epp->ep_hdr;
  184         long bsize, baddr;
  185         long nontext;
  186 
  187         /*
  188          * Check if vnode is in open for writing, because we want to
  189          * demand-page out of it.  If it is, don't do it, for various
  190          * reasons.
  191          */
  192         if ((execp->ha_text != 0 || execp->ha_data != 0) &&
  193             epp->ep_vp->v_writecount != 0)
  194                 return (ETXTBSY);
  195         vn_marktext(epp->ep_vp);
  196 
  197         /*
  198          * HP-UX ZMAGIC executables need to have their segment
  199          * sizes frobbed.
  200          */
  201         nontext = execp->ha_data + execp->ha_bss;
  202         execp->ha_text = ctob(btoc(execp->ha_text));
  203         execp->ha_data = ctob(btoc(execp->ha_data));
  204         execp->ha_bss = nontext - execp->ha_data;
  205         if (execp->ha_bss < 0)
  206                 execp->ha_bss = 0;
  207 
  208         epp->ep_taddr = 0;
  209         epp->ep_tsize = execp->ha_text;
  210         epp->ep_daddr = epp->ep_taddr + roundup(execp->ha_text, HPUX_LDPGSZ);
  211         epp->ep_dsize = execp->ha_data + execp->ha_bss;
  212         epp->ep_entry = execp->ha_entry;
  213 
  214         /* set up command for text segment */
  215         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->ha_text,
  216             epp->ep_taddr, epp->ep_vp, HPUX_TXTOFF(*execp, ZMAGIC),
  217             VM_PROT_READ|VM_PROT_EXECUTE);
  218 
  219         /* set up command for data segment */
  220         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->ha_data,
  221             epp->ep_daddr, epp->ep_vp, HPUX_DATAOFF(*execp, ZMAGIC),
  222             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  223 
  224         /* set up command for bss segment */
  225         baddr = round_page(epp->ep_daddr + execp->ha_data);
  226         bsize = epp->ep_daddr + epp->ep_dsize - baddr;
  227         if (bsize > 0)
  228                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
  229                     NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  230 
  231         return (exec_setup_stack(p, epp));
  232 }
  233 
  234 /*
  235  * HP-UX's version of OMAGIC.
  236  */
  237 static int
  238 exec_hpux_prep_omagic(p, epp)
  239         struct proc *p;
  240         struct exec_package *epp;
  241 {
  242         struct hpux_exec *execp = epp->ep_hdr;
  243         long dsize, bsize, baddr;
  244 
  245         epp->ep_taddr = 0;
  246         epp->ep_tsize = execp->ha_text;
  247         epp->ep_daddr = epp->ep_taddr + roundup(execp->ha_text, HPUX_LDPGSZ);
  248         epp->ep_dsize = execp->ha_data + execp->ha_bss;
  249         epp->ep_entry = execp->ha_entry;
  250 
  251         /* set up command for text and data segments */
  252         NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
  253             execp->ha_text + execp->ha_data, epp->ep_taddr, epp->ep_vp,
  254             HPUX_TXTOFF(*execp, OMAGIC),
  255             VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  256 
  257         /* set up command for bss segment */
  258         baddr = round_page(epp->ep_daddr + execp->ha_data);
  259         bsize = epp->ep_daddr + epp->ep_dsize - baddr;
  260         if (bsize > 0)
  261                 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
  262                     NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  263 
  264         /*
  265          * Make sure (# of pages) mapped above equals (vm_tsize + vm_dsize);
  266          * obreak(2) relies on this fact. Both `vm_tsize' and `vm_dsize' are
  267          * computed (in execve(2)) by rounding *up* `ep_tsize' and `ep_dsize'
  268          * respectively to page boundaries.
  269          * Compensate `ep_dsize' for the amount of data covered by the last
  270          * text page.
  271          */
  272         dsize = epp->ep_dsize + execp->ha_text - round_page(execp->ha_text);
  273         epp->ep_dsize = (dsize > 0) ? dsize : 0;
  274         return (exec_setup_stack(p, epp));
  275 }
  276 
  277 /*
  278  * The HP-UX execv(2) system call.
  279  *
  280  * Just check the alternate emulation path, and pass it on to the NetBSD
  281  * execve().
  282  */
  283 int
  284 hpux_sys_execv(p, v, retval)
  285         struct proc *p;
  286         void *v;
  287         register_t *retval;
  288 {
  289         struct hpux_sys_execv_args /* {
  290                 syscallarg(char *) path;
  291                 syscallarg(char **) argv;
  292         } */ *uap = v;
  293         struct sys_execve_args ap;
  294         caddr_t sg;
  295 
  296         sg = stackgap_init(p->p_emul);
  297         HPUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  298 
  299         SCARG(&ap, path) = SCARG(uap, path);
  300         SCARG(&ap, argp) = SCARG(uap, argp);
  301         SCARG(&ap, envp) = NULL;
  302 
  303         return sys_execve(p, &ap, retval);
  304 }
  305 
  306 int
  307 hpux_sys_execve(p, v, retval)
  308         struct proc *p;
  309         void *v;
  310         register_t *retval;
  311 {
  312         struct hpux_sys_execve_args /* {
  313                 syscallarg(char *) path;
  314                 syscallarg(char **) argv;
  315                 syscallarg(char **) envp;
  316         } */ *uap = v;
  317         struct sys_execve_args ap;
  318         caddr_t sg;
  319 
  320         sg = stackgap_init(p->p_emul);
  321         HPUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  322 
  323         SCARG(&ap, path) = SCARG(uap, path);
  324         SCARG(&ap, argp) = SCARG(uap, argp);
  325         SCARG(&ap, envp) = SCARG(uap, envp);
  326 
  327         return (sys_execve(p, &ap, retval));
  328 }

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