[BACK]Return to ibcs2_exec.c CVS log [TXT][DIR] Up to [local] / sys / compat / ibcs2

Annotation of sys/compat/ibcs2/ibcs2_exec.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: ibcs2_exec.c,v 1.18 2006/12/29 13:04:37 pedro Exp $   */
        !             2: /*     $NetBSD: ibcs2_exec.c,v 1.12 1996/10/12 02:13:52 thorpej Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1994, 1995 Scott Bartram
        !             6:  * Copyright (c) 1994 Adam Glass
        !             7:  * Copyright (c) 1993, 1994 Christopher G. Demetriou
        !             8:  * All rights reserved.
        !             9:  *
        !            10:  * originally from kern/exec_ecoff.c
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  * 3. All advertising materials mentioning features or use of this software
        !            21:  *    must display the following acknowledgement:
        !            22:  *      This product includes software developed by Scott Bartram.
        !            23:  * 4. The name of the author may not be used to endorse or promote products
        !            24:  *    derived from this software without specific prior written permission
        !            25:  *
        !            26:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            27:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            28:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            29:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            30:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            31:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            32:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            33:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            35:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            36:  */
        !            37:
        !            38: #include <sys/param.h>
        !            39: #include <sys/systm.h>
        !            40: #include <sys/proc.h>
        !            41: #include <sys/exec.h>
        !            42: #include <sys/malloc.h>
        !            43: #include <sys/vnode.h>
        !            44: #include <sys/resourcevar.h>
        !            45: #include <sys/namei.h>
        !            46: #include <uvm/uvm_extern.h>
        !            47:
        !            48: #include <compat/ibcs2/ibcs2_types.h>
        !            49: #include <compat/ibcs2/ibcs2_exec.h>
        !            50: #include <compat/ibcs2/ibcs2_util.h>
        !            51: #include <compat/ibcs2/ibcs2_syscall.h>
        !            52:
        !            53: int exec_ibcs2_coff_prep_omagic(struct proc *, struct exec_package *,
        !            54:                                     struct coff_filehdr *,
        !            55:                                     struct coff_aouthdr *);
        !            56: int exec_ibcs2_coff_prep_nmagic(struct proc *, struct exec_package *,
        !            57:                                     struct coff_filehdr *,
        !            58:                                     struct coff_aouthdr *);
        !            59: int exec_ibcs2_coff_prep_zmagic(struct proc *, struct exec_package *,
        !            60:                                     struct coff_filehdr *,
        !            61:                                     struct coff_aouthdr *);
        !            62: int exec_ibcs2_coff_setup_stack(struct proc *, struct exec_package *);
        !            63: void cpu_exec_ibcs2_coff_setup(int, struct proc *, struct exec_package *,
        !            64:                                    void *);
        !            65:
        !            66: int exec_ibcs2_xout_prep_nmagic(struct proc *, struct exec_package *,
        !            67:                                     struct xexec *, struct xext *);
        !            68: int exec_ibcs2_xout_prep_zmagic(struct proc *, struct exec_package *,
        !            69:                                     struct xexec *, struct xext *);
        !            70: int exec_ibcs2_xout_setup_stack(struct proc *, struct exec_package *);
        !            71: int coff_load_shlib(struct proc *, char *, struct exec_package *);
        !            72: static int coff_find_section(struct proc *, struct vnode *,
        !            73:                                  struct coff_filehdr *, struct coff_scnhdr *,
        !            74:                                  int);
        !            75:
        !            76:
        !            77: extern int bsd2ibcs_errno[];
        !            78: extern struct sysent ibcs2_sysent[];
        !            79: #ifdef SYSCALL_DEBUG
        !            80: extern char *ibcs2_syscallnames[];
        !            81: #endif
        !            82: extern void ibcs2_sendsig(sig_t, int, int, u_long, int, union sigval);
        !            83: extern char sigcode[], esigcode[];
        !            84:
        !            85: const char ibcs2_emul_path[] = "/emul/ibcs2";
        !            86:
        !            87: struct emul emul_ibcs2 = {
        !            88:        "ibcs2",
        !            89:        bsd2ibcs_errno,
        !            90:        ibcs2_sendsig,
        !            91:        0,
        !            92:        IBCS2_SYS_MAXSYSCALL,
        !            93:        ibcs2_sysent,
        !            94: #ifdef SYSCALL_DEBUG
        !            95:        ibcs2_syscallnames,
        !            96: #else
        !            97:        NULL,
        !            98: #endif
        !            99:        0,
        !           100:        copyargs,
        !           101:        setregs,
        !           102:        NULL,
        !           103:        sigcode,
        !           104:        esigcode,
        !           105: };
        !           106:
        !           107: /*
        !           108:  * exec_ibcs2_coff_makecmds(): Check if it's an coff-format executable.
        !           109:  *
        !           110:  * Given a proc pointer and an exec package pointer, see if the referent
        !           111:  * of the epp is in coff format.  Check 'standard' magic numbers for
        !           112:  * this architecture.  If that fails, return failure.
        !           113:  *
        !           114:  * This function is  responsible for creating a set of vmcmds which can be
        !           115:  * used to build the process's vm space and inserting them into the exec
        !           116:  * package.
        !           117:  */
        !           118:
        !           119: int
        !           120: exec_ibcs2_coff_makecmds(p, epp)
        !           121:        struct proc *p;
        !           122:        struct exec_package *epp;
        !           123: {
        !           124:        int error;
        !           125:        struct coff_filehdr *fp = epp->ep_hdr;
        !           126:        struct coff_aouthdr *ap;
        !           127:
        !           128:        if (epp->ep_hdrvalid < COFF_HDR_SIZE)
        !           129:                return ENOEXEC;
        !           130:
        !           131:        if (COFF_BADMAG(fp))
        !           132:                return ENOEXEC;
        !           133:
        !           134:        ap = (struct coff_aouthdr *)((char *)epp->ep_hdr +
        !           135:            sizeof(struct coff_filehdr));
        !           136:        switch (ap->a_magic) {
        !           137:        case COFF_OMAGIC:
        !           138:                error = exec_ibcs2_coff_prep_omagic(p, epp, fp, ap);
        !           139:                break;
        !           140:        case COFF_NMAGIC:
        !           141:                error = exec_ibcs2_coff_prep_nmagic(p, epp, fp, ap);
        !           142:                break;
        !           143:        case COFF_ZMAGIC:
        !           144:                error = exec_ibcs2_coff_prep_zmagic(p, epp, fp, ap);
        !           145:                break;
        !           146:        default:
        !           147:                return ENOEXEC;
        !           148:        }
        !           149:
        !           150:        if (error == 0)
        !           151:                epp->ep_emul = &emul_ibcs2;
        !           152:
        !           153:        if (error)
        !           154:                kill_vmcmds(&epp->ep_vmcmds);
        !           155:
        !           156:        return error;
        !           157: }
        !           158:
        !           159: /*
        !           160:  * exec_ibcs2_coff_setup_stack(): Set up the stack segment for a coff
        !           161:  * executable.
        !           162:  *
        !           163:  * Note that the ep_ssize parameter must be set to be the current stack
        !           164:  * limit; this is adjusted in the body of execve() to yield the
        !           165:  * appropriate stack segment usage once the argument length is
        !           166:  * calculated.
        !           167:  *
        !           168:  * This function returns an int for uniformity with other (future) formats'
        !           169:  * stack setup functions.  They might have errors to return.
        !           170:  */
        !           171:
        !           172: int
        !           173: exec_ibcs2_coff_setup_stack(p, epp)
        !           174:        struct proc *p;
        !           175:        struct exec_package *epp;
        !           176: {
        !           177:        /* DPRINTF(("enter exec_ibcs2_coff_setup_stack\n")); */
        !           178:
        !           179:        epp->ep_maxsaddr = USRSTACK - MAXSSIZ;
        !           180:        epp->ep_minsaddr = USRSTACK;
        !           181:        epp->ep_ssize = p->p_rlimit[RLIMIT_STACK].rlim_cur;
        !           182:
        !           183:        /*
        !           184:         * set up commands for stack.  note that this takes *two*, one to
        !           185:         * map the part of the stack which we can access, and one to map
        !           186:         * the part which we can't.
        !           187:         *
        !           188:         * arguably, it could be made into one, but that would require the
        !           189:         * addition of another mapping proc, which is unnecessary
        !           190:         *
        !           191:         * note that in memory, things assumed to be: 0 ....... ep_maxsaddr
        !           192:         * <stack> ep_minsaddr
        !           193:         */
        !           194:        /* DPRINTF(("VMCMD: addr %x size %d\n", epp->ep_maxsaddr,
        !           195:                 (epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr)); */
        !           196:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
        !           197:                  ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr),
        !           198:                  epp->ep_maxsaddr, NULLVP, 0, VM_PROT_NONE);
        !           199:        /* DPRINTF(("VMCMD: addr %x size %d\n",
        !           200:                 epp->ep_minsaddr - epp->ep_ssize,
        !           201:                 epp->ep_ssize)); */
        !           202:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize,
        !           203:                  (epp->ep_minsaddr - epp->ep_ssize), NULLVP, 0,
        !           204:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           205:
        !           206:        return 0;
        !           207: }
        !           208:
        !           209:
        !           210: /*
        !           211:  * exec_ibcs2_coff_prep_omagic(): Prepare a COFF OMAGIC binary's exec package
        !           212:  */
        !           213:
        !           214: int
        !           215: exec_ibcs2_coff_prep_omagic(p, epp, fp, ap)
        !           216:        struct proc *p;
        !           217:        struct exec_package *epp;
        !           218:        struct coff_filehdr *fp;
        !           219:        struct coff_aouthdr *ap;
        !           220: {
        !           221:        epp->ep_taddr = COFF_SEGMENT_ALIGN(ap, ap->a_tstart);
        !           222:        epp->ep_tsize = ap->a_tsize;
        !           223:        epp->ep_daddr = COFF_SEGMENT_ALIGN(ap, ap->a_dstart);
        !           224:        epp->ep_dsize = ap->a_dsize;
        !           225:        epp->ep_entry = ap->a_entry;
        !           226:
        !           227:        /* set up command for text and data segments */
        !           228:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
        !           229:                  ap->a_tsize + ap->a_dsize, epp->ep_taddr, epp->ep_vp,
        !           230:                  COFF_TXTOFF(fp, ap),
        !           231:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           232:
        !           233:        /* set up command for bss segment */
        !           234:        if (ap->a_bsize > 0)
        !           235:                NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
        !           236:                          COFF_SEGMENT_ALIGN(ap, ap->a_dstart + ap->a_dsize),
        !           237:                          NULLVP, 0,
        !           238:                          VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           239:
        !           240:        return exec_ibcs2_coff_setup_stack(p, epp);
        !           241: }
        !           242:
        !           243: /*
        !           244:  * exec_ibcs2_coff_prep_nmagic(): Prepare a 'native' NMAGIC COFF binary's exec
        !           245:  *                          package.
        !           246:  */
        !           247:
        !           248: int
        !           249: exec_ibcs2_coff_prep_nmagic(p, epp, fp, ap)
        !           250:        struct proc *p;
        !           251:        struct exec_package *epp;
        !           252:        struct coff_filehdr *fp;
        !           253:        struct coff_aouthdr *ap;
        !           254: {
        !           255:        epp->ep_taddr = COFF_SEGMENT_ALIGN(ap, ap->a_tstart);
        !           256:        epp->ep_tsize = ap->a_tsize;
        !           257:        epp->ep_daddr = COFF_ROUND(ap->a_dstart, COFF_LDPGSZ);
        !           258:        epp->ep_dsize = ap->a_dsize;
        !           259:        epp->ep_entry = ap->a_entry;
        !           260:
        !           261:        /* set up command for text segment */
        !           262:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
        !           263:                  epp->ep_taddr, epp->ep_vp, COFF_TXTOFF(fp, ap),
        !           264:                  VM_PROT_READ|VM_PROT_EXECUTE);
        !           265:
        !           266:        /* set up command for data segment */
        !           267:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_dsize,
        !           268:                  epp->ep_daddr, epp->ep_vp, COFF_DATOFF(fp, ap),
        !           269:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           270:
        !           271:        /* set up command for bss segment */
        !           272:        if (ap->a_bsize > 0)
        !           273:                NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
        !           274:                          COFF_SEGMENT_ALIGN(ap, ap->a_dstart + ap->a_dsize),
        !           275:                          NULLVP, 0,
        !           276:                          VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           277:
        !           278:        return exec_ibcs2_coff_setup_stack(p, epp);
        !           279: }
        !           280:
        !           281: /*
        !           282:  * coff_find_section - load specified section header
        !           283:  *
        !           284:  * TODO - optimize by reading all section headers in at once
        !           285:  */
        !           286:
        !           287: static int
        !           288: coff_find_section(p, vp, fp, sh, s_type)
        !           289:        struct proc *p;
        !           290:        struct vnode *vp;
        !           291:        struct coff_filehdr *fp;
        !           292:        struct coff_scnhdr *sh;
        !           293:        int s_type;
        !           294: {
        !           295:        int i, pos, error;
        !           296:        size_t siz, resid;
        !           297:
        !           298:        pos = COFF_HDR_SIZE;
        !           299:        for (i = 0; i < fp->f_nscns; i++, pos += sizeof(struct coff_scnhdr)) {
        !           300:                siz = sizeof(struct coff_scnhdr);
        !           301:                error = vn_rdwr(UIO_READ, vp, (caddr_t) sh,
        !           302:                    siz, pos, UIO_SYSSPACE, 0, p->p_ucred,
        !           303:                    &resid, p);
        !           304:                if (error) {
        !           305:                        DPRINTF(("section hdr %d read error %d\n", i, error));
        !           306:                        return error;
        !           307:                }
        !           308:                siz -= resid;
        !           309:                if (siz != sizeof(struct coff_scnhdr)) {
        !           310:                        DPRINTF(("incomplete read: hdr %d ask=%d, rem=%u got %u\n",
        !           311:                                 s_type, sizeof(struct coff_scnhdr),
        !           312:                                 resid, siz));
        !           313:                        return ENOEXEC;
        !           314:                }
        !           315:                /* DPRINTF(("found section: %x\n", sh->s_flags)); */
        !           316:                if (sh->s_flags == s_type)
        !           317:                        return 0;
        !           318:        }
        !           319:        return ENOEXEC;
        !           320: }
        !           321:
        !           322: /*
        !           323:  * exec_ibcs2_coff_prep_zmagic(): Prepare a COFF ZMAGIC binary's exec package
        !           324:  *
        !           325:  * First, set the various offsets/lengths in the exec package.
        !           326:  *
        !           327:  * Then, mark the text image busy (so it can be demand paged) or error
        !           328:  * out if this is not possible.  Finally, set up vmcmds for the
        !           329:  * text, data, bss, and stack segments.
        !           330:  */
        !           331:
        !           332: int
        !           333: exec_ibcs2_coff_prep_zmagic(p, epp, fp, ap)
        !           334:        struct proc *p;
        !           335:        struct exec_package *epp;
        !           336:        struct coff_filehdr *fp;
        !           337:        struct coff_aouthdr *ap;
        !           338: {
        !           339:        int error;
        !           340:        u_long offset;
        !           341:        long dsize, baddr, bsize;
        !           342:        struct coff_scnhdr sh;
        !           343:
        !           344:        /* DPRINTF(("enter exec_ibcs2_coff_prep_zmagic\n")); */
        !           345:
        !           346:        /* set up command for text segment */
        !           347:        error = coff_find_section(p, epp->ep_vp, fp, &sh, COFF_STYP_TEXT);
        !           348:        if (error) {
        !           349:                DPRINTF(("can't find text section: %d\n", error));
        !           350:                return error;
        !           351:        }
        !           352:        /* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr,
        !           353:                 sh.s_size, sh.s_scnptr)); */
        !           354:        epp->ep_taddr = COFF_ALIGN(sh.s_vaddr);
        !           355:        offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_taddr);
        !           356:        epp->ep_tsize = sh.s_size + (sh.s_vaddr - epp->ep_taddr);
        !           357:
        !           358: #ifdef notyet
        !           359:        /*
        !           360:         * check if vnode is in open for writing, because we want to
        !           361:         * demand-page out of it.  if it is, don't do it, for various
        !           362:         * reasons
        !           363: n       */
        !           364:        if ((ap->a_tsize != 0 || ap->a_dsize != 0) &&
        !           365:            epp->ep_vp->v_writecount != 0) {
        !           366: #ifdef DIAGNOSTIC
        !           367:                if (epp->ep_vp->v_flag & VTEXT)
        !           368:                        panic("exec: a VTEXT vnode has writecount != 0");
        !           369: #endif
        !           370:                return ETXTBSY;
        !           371:        }
        !           372:        vn_marktext(epp->ep_vp);
        !           373: #endif
        !           374:
        !           375:        /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_taddr,
        !           376:                 epp->ep_tsize, offset)); */
        !           377: #ifdef notyet
        !           378:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, epp->ep_tsize,
        !           379:                  epp->ep_taddr, epp->ep_vp, offset,
        !           380:                  VM_PROT_READ|VM_PROT_EXECUTE);
        !           381: #else
        !           382:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
        !           383:                  epp->ep_taddr, epp->ep_vp, offset,
        !           384:                  VM_PROT_READ|VM_PROT_EXECUTE);
        !           385: #endif
        !           386:
        !           387:        /* set up command for data segment */
        !           388:        error = coff_find_section(p, epp->ep_vp, fp, &sh, COFF_STYP_DATA);
        !           389:        if (error) {
        !           390:                DPRINTF(("can't find data section: %d\n", error));
        !           391:                return error;
        !           392:        }
        !           393:        /* DPRINTF(("COFF data addr %x size %d offset %d\n", sh.s_vaddr,
        !           394:                 sh.s_size, sh.s_scnptr)); */
        !           395:        epp->ep_daddr = COFF_ALIGN(sh.s_vaddr);
        !           396:        offset = sh.s_scnptr - (sh.s_vaddr - epp->ep_daddr);
        !           397:        dsize = sh.s_size + (sh.s_vaddr - epp->ep_daddr);
        !           398:        epp->ep_dsize = dsize + ap->a_bsize;
        !           399:
        !           400:        /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", epp->ep_daddr,
        !           401:                 dsize, offset)); */
        !           402: #ifdef notyet
        !           403:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, dsize,
        !           404:                  epp->ep_daddr, epp->ep_vp, offset,
        !           405:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           406: #else
        !           407:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
        !           408:                  dsize, epp->ep_daddr, epp->ep_vp, offset,
        !           409:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           410: #endif
        !           411:
        !           412:        /* set up command for bss segment */
        !           413:        baddr = round_page(epp->ep_daddr + dsize);
        !           414:        bsize = epp->ep_daddr + epp->ep_dsize - baddr;
        !           415:        if (bsize > 0) {
        !           416:                /* DPRINTF(("VMCMD: addr %x size %d offset %d\n",
        !           417:                         baddr, bsize, 0)); */
        !           418:                NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
        !           419:                          bsize, baddr, NULLVP, 0,
        !           420:                          VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           421:        }
        !           422:
        !           423:        /* load any shared libraries */
        !           424:        error = coff_find_section(p, epp->ep_vp, fp, &sh, COFF_STYP_SHLIB);
        !           425:        if (!error) {
        !           426:                size_t resid;
        !           427:                struct coff_slhdr *slhdr;
        !           428:                char buf[128], *bufp;   /* FIXME */
        !           429:                unsigned int len = sh.s_size, entry_len;
        !           430:
        !           431:                /* DPRINTF(("COFF shlib size %d offset %d\n",
        !           432:                         sh.s_size, sh.s_scnptr)); */
        !           433:
        !           434:                if (len > sizeof(buf))
        !           435:                        return (ENOEXEC);
        !           436:
        !           437:                error = vn_rdwr(UIO_READ, epp->ep_vp, (caddr_t) buf,
        !           438:                                len, sh.s_scnptr,
        !           439:                                UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred,
        !           440:                                &resid, p);
        !           441:                if (error) {
        !           442:                        DPRINTF(("shlib section read error %d\n", error));
        !           443:                        return ENOEXEC;
        !           444:                }
        !           445:                bufp = buf;
        !           446:                while (len) {
        !           447:                        slhdr = (struct coff_slhdr *)bufp;
        !           448: #ifdef notyet
        !           449:                        path_index = slhdr->path_index * sizeof(long);
        !           450: #endif
        !           451:                        entry_len = slhdr->entry_len * sizeof(long);
        !           452:
        !           453:                        /* DPRINTF(("path_index: %d entry_len: %d name: %s\n",
        !           454:                                 path_index, entry_len, slhdr->sl_name)); */
        !           455:
        !           456:                        if (entry_len > len)
        !           457:                                return (ENOEXEC);
        !           458:
        !           459:                        error = coff_load_shlib(p, slhdr->sl_name, epp);
        !           460:                        if (error)
        !           461:                                return ENOEXEC;
        !           462:                        bufp += entry_len;
        !           463:                        len -= entry_len;
        !           464:                }
        !           465:        }
        !           466:
        !           467:        /* set up entry point */
        !           468:        epp->ep_entry = ap->a_entry;
        !           469:
        !           470: #if 0
        !           471:        DPRINTF(("text addr: %x size: %d data addr: %x size: %d entry: %x\n",
        !           472:                 epp->ep_taddr, epp->ep_tsize,
        !           473:                 epp->ep_daddr, epp->ep_dsize,
        !           474:                 epp->ep_entry));
        !           475: #endif
        !           476:
        !           477:        return exec_ibcs2_coff_setup_stack(p, epp);
        !           478: }
        !           479:
        !           480: int
        !           481: coff_load_shlib(p, path, epp)
        !           482:        struct proc *p;
        !           483:        char *path;
        !           484:        struct exec_package *epp;
        !           485: {
        !           486:        int error, taddr, tsize, daddr, dsize, offset;
        !           487:        size_t siz, resid;
        !           488:        struct nameidata nd;
        !           489:        struct coff_filehdr fh, *fhp = &fh;
        !           490:        struct coff_scnhdr sh, *shp = &sh;
        !           491:        caddr_t sg = stackgap_init(p->p_emul);
        !           492:
        !           493:        /*
        !           494:         * 1. open shlib file
        !           495:         * 2. read filehdr
        !           496:         * 3. map text, data, and bss out of it using VM_*
        !           497:         */
        !           498:        IBCS2_CHECK_ALT_EXIST(p, &sg, path);
        !           499:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
        !           500:        /* first get the vnode */
        !           501:        if ((error = namei(&nd)) != 0) {
        !           502:                DPRINTF(("coff_load_shlib: can't find library %s\n", path));
        !           503:                return error;
        !           504:        }
        !           505:
        !           506:        siz = sizeof(struct coff_filehdr);
        !           507:        error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t) fhp, siz, 0,
        !           508:            UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
        !           509:        if (error) {
        !           510:            DPRINTF(("filehdr read error %d\n", error));
        !           511:            vrele(nd.ni_vp);
        !           512:            return error;
        !           513:        }
        !           514:        siz -= resid;
        !           515:        if (siz != sizeof(struct coff_filehdr)) {
        !           516:            DPRINTF(("coff_load_shlib: incomplete read: ask=%d, rem=%u got %u\n",
        !           517:                     sizeof(struct coff_filehdr), resid, siz));
        !           518:            vrele(nd.ni_vp);
        !           519:            return ENOEXEC;
        !           520:        }
        !           521:
        !           522:        /* load text */
        !           523:        error = coff_find_section(p, nd.ni_vp, fhp, shp, COFF_STYP_TEXT);
        !           524:        if (error) {
        !           525:            DPRINTF(("can't find shlib text section\n"));
        !           526:            vrele(nd.ni_vp);
        !           527:            return error;
        !           528:        }
        !           529:        /* DPRINTF(("COFF text addr %x size %d offset %d\n", sh.s_vaddr,
        !           530:                 sh.s_size, sh.s_scnptr)); */
        !           531:        taddr = COFF_ALIGN(shp->s_vaddr);
        !           532:        offset = shp->s_scnptr - (shp->s_vaddr - taddr);
        !           533:        tsize = shp->s_size + (shp->s_vaddr - taddr);
        !           534:        /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", taddr, tsize, offset)); */
        !           535:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, tsize, taddr,
        !           536:                  nd.ni_vp, offset,
        !           537:                  VM_PROT_READ|VM_PROT_EXECUTE);
        !           538:
        !           539:        /* load data */
        !           540:        error = coff_find_section(p, nd.ni_vp, fhp, shp, COFF_STYP_DATA);
        !           541:        if (error) {
        !           542:            DPRINTF(("can't find shlib data section\n"));
        !           543:            vrele(nd.ni_vp);
        !           544:            return error;
        !           545:        }
        !           546:        /* DPRINTF(("COFF data addr %x size %d offset %d\n", shp->s_vaddr,
        !           547:                 shp->s_size, shp->s_scnptr)); */
        !           548:        daddr = COFF_ALIGN(shp->s_vaddr);
        !           549:        offset = shp->s_scnptr - (shp->s_vaddr - daddr);
        !           550:        dsize = shp->s_size + (shp->s_vaddr - daddr);
        !           551:        /* epp->ep_dsize = dsize + ap->a_bsize; */
        !           552:
        !           553:        /* DPRINTF(("VMCMD: addr %x size %d offset %d\n", daddr, dsize, offset)); */
        !           554:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
        !           555:                  dsize, daddr, nd.ni_vp, offset,
        !           556:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           557:
        !           558:        /* load bss */
        !           559:        error = coff_find_section(p, nd.ni_vp, fhp, shp, COFF_STYP_BSS);
        !           560:        if (!error) {
        !           561:                int baddr = round_page(daddr + dsize);
        !           562:                int bsize = daddr + dsize + shp->s_size - baddr;
        !           563:                if (bsize > 0) {
        !           564:                        /* DPRINTF(("VMCMD: addr %x size %d offset %d\n",
        !           565:                           baddr, bsize, 0)); */
        !           566:                        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
        !           567:                                  bsize, baddr, NULLVP, 0,
        !           568:                                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           569:            }
        !           570:        }
        !           571:        vrele(nd.ni_vp);
        !           572:
        !           573:        return 0;
        !           574: }
        !           575:
        !           576: int
        !           577: exec_ibcs2_xout_makecmds(p, epp)
        !           578:        struct proc *p;
        !           579:        struct exec_package *epp;
        !           580: {
        !           581:        int error;
        !           582:        struct xexec *xp = epp->ep_hdr;
        !           583:        struct xext *xep;
        !           584:
        !           585:        if (epp->ep_hdrvalid < XOUT_HDR_SIZE)
        !           586:                return ENOEXEC;
        !           587:
        !           588:        if ((xp->x_magic != XOUT_MAGIC) || (xp->x_cpu != XC_386))
        !           589:                return ENOEXEC;
        !           590:        if ((xp->x_renv & (XE_ABS | XE_VMOD)) || !(xp->x_renv & XE_EXEC))
        !           591:                return ENOEXEC;
        !           592:
        !           593:        xep = (struct xext *)((char *)epp->ep_hdr + sizeof(struct xexec));
        !           594: #ifdef notyet
        !           595:        if (xp->x_renv & XE_PURE)
        !           596:                error = exec_ibcs2_xout_prep_zmagic(p, epp, xp, xep);
        !           597:        else
        !           598: #endif
        !           599:                error = exec_ibcs2_xout_prep_nmagic(p, epp, xp, xep);
        !           600:
        !           601:        if (error == 0)
        !           602:                epp->ep_emul = &emul_ibcs2;
        !           603:
        !           604:        if (error)
        !           605:                kill_vmcmds(&epp->ep_vmcmds);
        !           606:
        !           607:        return error;
        !           608: }
        !           609:
        !           610: /*
        !           611:  * exec_ibcs2_xout_prep_nmagic(): Prepare a pure x.out binary's exec package
        !           612:  *
        !           613:  */
        !           614:
        !           615: int
        !           616: exec_ibcs2_xout_prep_nmagic(p, epp, xp, xep)
        !           617:        struct proc *p;
        !           618:        struct exec_package *epp;
        !           619:        struct xexec *xp;
        !           620:        struct xext *xep;
        !           621: {
        !           622:        int error, nseg, i;
        !           623:        size_t resid;
        !           624:        long baddr, bsize;
        !           625:        struct xseg *xs;
        !           626:
        !           627:        /* read in segment table */
        !           628:        if (xep->xe_segsize > 16 * sizeof(*xs))
        !           629:                return (ENOEXEC);
        !           630:        xs = (struct xseg *)malloc(xep->xe_segsize, M_TEMP, M_WAITOK);
        !           631:        error = vn_rdwr(UIO_READ, epp->ep_vp, (caddr_t)xs,
        !           632:                        xep->xe_segsize, xep->xe_segpos,
        !           633:                        UIO_SYSSPACE, 0, p->p_ucred,
        !           634:                        &resid, p);
        !           635:        if (error) {
        !           636:                DPRINTF(("segment table read error %d\n", error));
        !           637:                free(xs, M_TEMP);
        !           638:                return ENOEXEC;
        !           639:        }
        !           640:
        !           641:        for (nseg = xep->xe_segsize / sizeof(*xs), i = 0; i < nseg; i++) {
        !           642:                switch (xs[i].xs_type) {
        !           643:                case XS_TTEXT:  /* text segment */
        !           644:
        !           645:                        DPRINTF(("text addr %x psize %d vsize %d off %d\n",
        !           646:                                 xs[i].xs_rbase, xs[i].xs_psize,
        !           647:                                 xs[i].xs_vsize, xs[i].xs_filpos));
        !           648:
        !           649:                        epp->ep_taddr = xs[i].xs_rbase; /* XXX - align ??? */
        !           650:                        epp->ep_tsize = xs[i].xs_vsize;
        !           651:
        !           652:                        DPRINTF(("VMCMD: addr %x size %d offset %d\n",
        !           653:                                 epp->ep_taddr, epp->ep_tsize,
        !           654:                                 xs[i].xs_filpos));
        !           655:                        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
        !           656:                                  epp->ep_tsize, epp->ep_taddr,
        !           657:                                  epp->ep_vp, xs[i].xs_filpos,
        !           658:                                  VM_PROT_READ|VM_PROT_EXECUTE);
        !           659:                        break;
        !           660:
        !           661:                case XS_TDATA:  /* data segment */
        !           662:
        !           663:                        DPRINTF(("data addr %x psize %d vsize %d off %d\n",
        !           664:                                 xs[i].xs_rbase, xs[i].xs_psize,
        !           665:                                 xs[i].xs_vsize, xs[i].xs_filpos));
        !           666:
        !           667:                        epp->ep_daddr = xs[i].xs_rbase; /* XXX - align ??? */
        !           668:                        epp->ep_dsize = xs[i].xs_vsize;
        !           669:
        !           670:                        DPRINTF(("VMCMD: addr %x size %d offset %d\n",
        !           671:                                 epp->ep_daddr, xs[i].xs_psize,
        !           672:                                 xs[i].xs_filpos));
        !           673:                        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
        !           674:                                  xs[i].xs_psize, epp->ep_daddr,
        !           675:                                  epp->ep_vp, xs[i].xs_filpos,
        !           676:                                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           677:
        !           678:                        /* set up command for bss segment */
        !           679:                        baddr = round_page(epp->ep_daddr + xs[i].xs_psize);
        !           680:                        bsize = epp->ep_daddr + epp->ep_dsize - baddr;
        !           681:                        if (bsize > 0) {
        !           682:                                DPRINTF(("VMCMD: bss addr %x size %d off %d\n",
        !           683:                                         baddr, bsize, 0));
        !           684:                                NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
        !           685:                                          bsize, baddr, NULLVP, 0,
        !           686:                                          VM_PROT_READ|VM_PROT_WRITE|
        !           687:                                          VM_PROT_EXECUTE);
        !           688:                        }
        !           689:                        break;
        !           690:
        !           691:                default:
        !           692:                        break;
        !           693:                }
        !           694:        }
        !           695:
        !           696:        /* set up entry point */
        !           697:        epp->ep_entry = xp->x_entry;
        !           698:
        !           699:        DPRINTF(("text addr: %x size: %d data addr: %x size: %d entry: %x\n",
        !           700:                 epp->ep_taddr, epp->ep_tsize,
        !           701:                 epp->ep_daddr, epp->ep_dsize,
        !           702:                 epp->ep_entry));
        !           703:
        !           704:        free(xs, M_TEMP);
        !           705:        return exec_ibcs2_xout_setup_stack(p, epp);
        !           706: }
        !           707:
        !           708: /*
        !           709:  * exec_ibcs2_xout_setup_stack(): Set up the stack segment for a x.out
        !           710:  * executable.
        !           711:  *
        !           712:  * Note that the ep_ssize parameter must be set to be the current stack
        !           713:  * limit; this is adjusted in the body of execve() to yield the
        !           714:  * appropriate stack segment usage once the argument length is
        !           715:  * calculated.
        !           716:  *
        !           717:  * This function returns an int for uniformity with other (future) formats'
        !           718:  * stack setup functions.  They might have errors to return.
        !           719:  */
        !           720:
        !           721: int
        !           722: exec_ibcs2_xout_setup_stack(p, epp)
        !           723:        struct proc *p;
        !           724:        struct exec_package *epp;
        !           725: {
        !           726:        epp->ep_maxsaddr = USRSTACK - MAXSSIZ;
        !           727:        epp->ep_minsaddr = USRSTACK;
        !           728:        epp->ep_ssize = p->p_rlimit[RLIMIT_STACK].rlim_cur;
        !           729:
        !           730:        /*
        !           731:         * set up commands for stack.  note that this takes *two*, one to
        !           732:         * map the part of the stack which we can access, and one to map
        !           733:         * the part which we can't.
        !           734:         *
        !           735:         * arguably, it could be made into one, but that would require the
        !           736:         * addition of another mapping proc, which is unnecessary
        !           737:         *
        !           738:         * note that in memory, things assumed to be: 0 ....... ep_maxsaddr
        !           739:         * <stack> ep_minsaddr
        !           740:         */
        !           741:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
        !           742:                  ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr),
        !           743:                  epp->ep_maxsaddr, NULLVP, 0, VM_PROT_NONE);
        !           744:        NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize,
        !           745:                  (epp->ep_minsaddr - epp->ep_ssize), NULLVP, 0,
        !           746:                  VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        !           747:
        !           748:        return 0;
        !           749: }

CVSweb