[BACK]Return to hpux_exec.c CVS log [TXT][DIR] Up to [local] / sys / compat / hpux / m68k

Annotation of sys/compat/hpux/m68k/hpux_exec.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb