Annotation of coherent/d/kernel/USRSRC/coh/exec.c, revision 1.1.1.1

1.1       root        1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/exec.c,v 1.4 91/07/24 07:50:20 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * Exec and driver load code.
                     18:  *
                     19:  * $Log:       exec.c,v $
                     20:  * Revision 1.4  91/07/24  07:50:20  bin
                     21:  * update prov by hal
                     22:  * 
                     23:  * 
                     24:  * Revision 1.1        88/03/24  16:13:39      src
                     25:  * Initial revision
                     26:  * 
                     27:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/exec.c
                     28:  * Exsread() initializes the (new) (IO).io_flag field to 0.
                     29:  */
                     30: #include <sys/coherent.h>
                     31: #include <acct.h>
                     32: #include <sys/buf.h>
                     33: #include <canon.h>
                     34: #include <sys/con.h>
                     35: #include <errno.h>
                     36: #include <sys/filsys.h>
                     37: #include <sys/ino.h>
                     38: #include <sys/inode.h>
                     39: #include <l.out.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/seg.h>
                     42: #include <signal.h>
                     43: #include <sys/uproc.h>
                     44: 
                     45: /*
                     46:  * Sizes.
                     47:  */
                     48: #define        sh      ((fsize_t)sizeof(struct ldheader))
                     49: #define si     lssize[L_SHRI]
                     50: #define pi     lssize[L_PRVI]
                     51: #define bi     lssize[L_BSSI]
                     52: #define sd     lssize[L_SHRD]
                     53: #define pd     lssize[L_PRVD]
                     54: #define bd     lssize[L_BSSD]
                     55: 
                     56: /*
                     57:  * Segments.
                     58:  */
                     59: #define upsp   pp->p_segp[SIUSERP]
                     60: #define sssp   pp->p_segp[SISTACK]
                     61: #define        sisp    pp->p_segp[SISTEXT]
                     62: #define pisp   pp->p_segp[SIPTEXT]
                     63: #define sdsp   pp->p_segp[SISDATA]
                     64: #define pdsp   pp->p_segp[SIPDATA]
                     65: 
                     66: /*
                     67:  * Set up the first process, a small programme which will exec
                     68:  * the init programme.
                     69:  */
                     70: eveinit(sp)
                     71: SEG *sp;
                     72: {
                     73:        register PROC *pp;
                     74: 
                     75:        SELF = pp = eprocp;
                     76:        pp->p_segp[SIUSERP] = sp;
                     77:        if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
                     78:                panic("eveinit()");
                     79:        pp->p_segp[SIPDATA] = sp;
                     80:        kscopy(icodep, sp, 0, icodes);
                     81:        if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
                     82:                panic("eveinit()");
                     83:        pp->p_segp[SISTACK] = sp;
                     84:        u.u_argp = 0;
                     85:        if (sproto() == 0)
                     86:                panic("eveinit()");
                     87:        segload();
                     88: }
                     89: 
                     90: /*
                     91:  * Given a major number, a file containing a device driver and a configuration
                     92:  * pointer, load the driver on the major number.
                     93:  */
                     94: pload(m, np, cp)
                     95: char *np;
                     96: CON *cp;
                     97: {
                     98:        register INODE *ip;
                     99:        register SEG *sp;
                    100:        register DRV *dp;
                    101:        register fsize_t ss;
                    102:        dold_t dold;
                    103:        int lflag;
                    104:        int r;
                    105:        vaddr_t pc;
                    106:        fsize_t lssize[NUSEG];
                    107: 
                    108:        if (m >= drvn) {
                    109:                u.u_error = ENXIO;
                    110:                return;
                    111:        }
                    112:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
                    113:                return;
                    114:        ss = pi+si+pd+sd;
                    115:        sp = ssalloc(&r, ip, SFSHRX, ss+bi+bd, sh, ss);
                    116:        idetach(ip);
                    117:        if (r < 0)
                    118:                return;
                    119:        dp = &drvl[m];
                    120:        lock(dp->d_gate);
                    121:        if (dp->d_conp != NULL) {
                    122:                unlock(dp->d_gate);
                    123:                sfree(sp);
                    124:                u.u_error = EDBUSY;
                    125:                return;
                    126:        }
                    127:        dp->d_time = 0;
                    128:        dp->d_conp = cp;
                    129:        dp->d_segp = sp;
                    130:        dp->d_map = sp->s_mbase;
                    131:        dsave(dold);
                    132:        dmapv(dp->d_map);
                    133:        (*cp->c_load)();
                    134:        drest(dold);
                    135:        unlock(dp->d_gate);
                    136: }
                    137: 
                    138: /*
                    139:  * Given a major number, undo the previous function.
                    140:  */
                    141: puload(m)
                    142: int m;
                    143: {
                    144:        register CON *cp;
                    145:        register DRV *dp;
                    146:        dold_t dold;
                    147: 
                    148:        dp = &drvl[m];
                    149:        lock(dp->d_gate);
                    150:        if (m>=drvn || dp->d_segp==NULL || (cp=dp->d_conp)==NULL) {
                    151:                u.u_error = ENXIO;
                    152:                goto ret;
                    153:        }
                    154:        dsave(dold);
                    155:        dmapv(dp->d_map);
                    156:        (*cp->c_uload)();
                    157:        drest(dold);
                    158:        if (u.u_error)
                    159:                goto ret;
                    160:        sfree(dp->d_segp);
                    161:        dp->d_conp = NULL;
                    162:        dp->d_segp = NULL;
                    163:        dp->d_map = 0;
                    164: ret:
                    165:        unlock(dp->d_gate);
                    166:        return (0);
                    167: }
                    168: 
                    169: /*
                    170:  * Given the name of an executable l.out, a null terminated argument
                    171:  * list and a null terminated environment list, execute the l.out with the
                    172:  * given arguments and environments.
                    173:  */
                    174: pexece(np, argp, envp)
                    175: char   *np;
                    176: char   *argp[];
                    177: char   *envp[];
                    178: {
                    179:        register INODE  *ip;                    /* Load file INODE */
                    180:        register PROC   *pp;                    /* A cheap copy of SELF */
                    181:        register SEG    *ssp;                   /* New stack segment */
                    182:        register fsize_t        ss;                     /* Segment size temp. */
                    183:        register int    kprocflag;              /* Set if kernal process */
                    184:        register int    i;                      /* For looping over segments */
                    185:        int             r;                      /* Flag for "exload" */
                    186:        int             lflag;                  /* l_flags from l.out */
                    187:        vaddr_t         pc;                     /* l_entry from l.out */
                    188:        vaddr_t         sp;                     /* Initial stack pointer */
                    189:        fsize_t         lssize[NUSEG];          /* Segment sizes */
                    190: 
                    191:        pp = SELF;
                    192:        if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
                    193:                return;
                    194:        if ((lflag&LF_KER) != 0) {
                    195:                pp->p_flags |= PFKERN;
                    196:                kprocflag = 1;
                    197:                ssp = NULL;
                    198:                if (super() == 0) {
                    199:                        idetach(ip);
                    200:                        return;
                    201:                }
                    202:        } else {
                    203:                kprocflag = 0;
                    204:                if ((ssp=exstack(&sp, argp, envp)) == NULL) {
                    205:                        idetach(ip);
                    206:                        return;
                    207:                }
                    208:        }
                    209:        /*
                    210:         * At this point the file has been
                    211:         * validated as an object module, and the
                    212:         * argument list has been build. Release all of
                    213:         * the original segments. At this point we have
                    214:         * committed to the new image. A "sys exec" that
                    215:         * gets an I/O error is doomed.
                    216:         */
                    217:        for (i=1; i<NUSEG; ++i) {
                    218:                if (pp->p_segp[i] != NULL) {
                    219:                        sfree(pp->p_segp[i]);
                    220:                        pp->p_segp[i] = NULL;
                    221:                }
                    222:        }
                    223:        sssp = ssp;
                    224:        /*
                    225:         * Read in load module.
                    226:         */
                    227:        switch (lflag&(LF_SHR|LF_SEP)) {
                    228:        case 0:
                    229:                ss = si+pi+sd+pd;
                    230:                pdsp = ssalloc(&r, ip, kprocflag?SFHIGH:0, ss+bi+bd, sh, ss);
                    231:                if (r < 0)
                    232:                        goto out;
                    233:                break;
                    234: 
                    235:        case LF_SHR:
                    236:                sdsp = ssalloc(&r, ip, SFSHRX, si+sd, sh, si);
                    237:                if (r < 0)
                    238:                        goto out;
                    239:                if (r == 0) {
                    240:                        if (exsread(sdsp, ip, sd, sh+si+pi, si) == 0)
                    241:                                goto out;
                    242:                }
                    243:                pdsp = ssalloc(&r, ip, 0, pi+pd+bi+bd, sh+si, pi);
                    244:                if (r < 0)
                    245:                        goto out;
                    246:                if (r == 0) {
                    247:                        if (exsread(pdsp, ip, pd, sh+si+pi+sd, pi) == 0)
                    248:                                goto out;
                    249:                }
                    250:                break;
                    251: 
                    252:        case LF_SEP:
                    253:                pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
                    254:                if (r < 0)
                    255:                        goto out;
                    256:                pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+bi, sd+pd);
                    257:                if (r < 0)
                    258:                        goto out;
                    259:                break;
                    260: 
                    261:        case LF_SHR|LF_SEP:
                    262:                sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
                    263:                if (r < 0)
                    264:                        goto out;
                    265:                pisp = ssalloc(&r, ip, SFTEXT, pi+bi, sh+si, pi);
                    266:                if (r < 0)
                    267:                        goto out;
                    268:                sdsp = ssalloc(&r, ip, SFSHRX, sd, sh+si+pi, sd);
                    269:                if (r < 0)
                    270:                        goto out;
                    271:                pdsp = ssalloc(&r, ip, 0, pd+bd, sh+si+pi+pd, pd);
                    272:                if (r < 0)
                    273:                        goto out;
                    274:        }
                    275:        if (sproto() == 0)
                    276:                goto out;
                    277:        /*
                    278:         * The new image is read in
                    279:         * and mapped. Perform the final grunge
                    280:         * (set-uid stuff, accounting, loading up
                    281:         * registers, etc).
                    282:         */
                    283:        u.u_flag &= ~AFORK;
                    284:        kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
                    285:        if (iaccess(ip, IPR) == 0)
                    286:                pp->p_flags |= PFNDMP;
                    287:        if ((ip->i_mode&ISUID) != 0)
                    288:                pp->p_uid = u.u_uid = ip->i_uid;
                    289:        if ((ip->i_mode&ISGID) != 0)
                    290:                u.u_gid = ip->i_gid;
                    291:        for (i=0; i<NSIG; ++i) {
                    292:                if (u.u_sfunc[i] != SIG_IGN)
                    293:                        u.u_sfunc[i] = SIG_DFL;
                    294:        }
                    295:        if ((pp->p_flags&PFTRAC) != 0)
                    296:                sendsig(SIGTRAP, pp);
                    297:        idetach(ip);
                    298:        msetusr(pc, sp);
                    299:        segload();
                    300:        return (0);
                    301: 
                    302:        /*
                    303:         * We did not make it.
                    304:         * Release the INODE for the load
                    305:         * file, and return through the "sys exit"
                    306:         * code. A better exit status should be
                    307:         * chosen!
                    308:         */
                    309: out:
                    310:        idetach(ip);
                    311:        pexit(0);
                    312: }
                    313: 
                    314: /*
                    315:  * Open an l.out, make sure it is an l.out and executable and return the
                    316:  * appropriate information.
                    317:  */
                    318: INODE *
                    319: exlopen(np, ssizep, flagp, pcp)
                    320: char *np;
                    321: fsize_t *ssizep;
                    322: int *flagp;
                    323: vaddr_t *pcp;
                    324: {
                    325:        register INODE *ip;
                    326:        register struct ldheader *ldp;
                    327:        register int n;
                    328:        register BUF *bp;
                    329:        int m;
                    330: 
                    331:        /*
                    332:         * Make sure the file is really an executable l.out and read the
                    333:         * header in.
                    334:         */
                    335:        if (ftoi(np, 'r') != 0)
                    336:                return (NULL);
                    337:        ip = u.u_cdiri;
                    338:        if (iaccess(ip, IPE) == 0) {
                    339:                idetach(ip);
                    340:                return (NULL);
                    341:        }
                    342:        if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
                    343:                u.u_error = EACCES;
                    344:                idetach(ip);
                    345:                return (NULL);
                    346:        }
                    347:        if ((bp=vread(ip, (daddr_t)0)) == NULL) {
                    348:                u.u_error = EBADFMT;
                    349:                idetach(ip);
                    350:                return (NULL);
                    351:        }
                    352: 
                    353:        /*
                    354:         * Copy everything we need from the l.out header and check magic
                    355:         * number and machine type.
                    356:         */
                    357:        ldp = bp->b_vaddr;
                    358:        m = ldp->l_magic;
                    359:        canint(m);
                    360:        if (m != L_MAGIC) {
                    361:                u.u_error = ENOEXEC;
                    362:                brelease(bp);
                    363:                idetach(ip);
                    364:                return (NULL);
                    365:        }
                    366:        m = ldp->l_machine;
                    367:        canint(m);
                    368:        if (m != mactype) {
                    369:                u.u_error = EBADFMT;
                    370:                brelease(bp);
                    371:                idetach(ip);
                    372:                return (NULL);
                    373:        }
                    374:        kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
                    375:        for (n=0; n<NXSEG; n++)
                    376:                cansize(ssizep[n]);
                    377:        *flagp = ldp->l_flag;
                    378:        canint(*flagp);
                    379:        *pcp = ldp->l_entry;
                    380:        canvaddr(*pcp);
                    381:        brelease(bp);
                    382:        return (ip);
                    383: }
                    384: 
                    385: /*
                    386:  * Given a segment `sp', read `ss' bytes from the inode `ip' starting
                    387:  * at seek address `sa' into offset `so' in the segment.
                    388:  */
                    389: SEG *
                    390: exsread(sp, ip, ss, sa, so)
                    391: register SEG *sp;
                    392: INODE *ip;
                    393: fsize_t sa;
                    394: fsize_t ss;
                    395: fsize_t so;
                    396: {
                    397:        u.u_io.io_seg = IOPHY;
                    398:        u.u_io.io_ioc = ss;
                    399:        u.u_io.io_seek = sa;
                    400:        u.u_io.io_phys = ctob((paddr_t)sp->s_mbase) + so;
                    401:        u.u_io.io_flag = 0;
                    402:        iread(ip, &u.u_io);
                    403:        return (u.u_error==0);
                    404: }
                    405: 
                    406: /*
                    407:  * Given a pointer to a list of arguments and a pointer to a list of
                    408:  * environments, return a stack with the arguments and environments on it.
                    409:  */
                    410: SEG *
                    411: exstack(iusp, argp, envp)
                    412: char **iusp;           /* Back patch sp value */
                    413: char *argp[];          /* Arguments for new process */
                    414: char *envp[];          /* Environments for new process */
                    415: {
                    416:        SEG *sp;                /* Stack segment pointer */
                    417:        struct adata {          /* Storage for arg and env data */
                    418:                char    **up;           /* User vector pointer */
                    419:                int     np;             /* Number of pointers in vector */
                    420:                int     nc;             /* Number of characters in strings */
                    421:        } arg, env;
                    422:        struct sdata {          /* To keep segment pointers */
                    423:                vaddr_t base;           /* Top of segment virtual */
                    424:                vaddr_t ap;             /* Argc, argv, envp pointer */
                    425:                vaddr_t vp;             /* Argv[i], envp[i] pointer */
                    426:                vaddr_t cp;             /* Argv[i][j], envp[i][j] pointer */
                    427:        } aux, stk;
                    428:        aold_t aold;                    /* Auxiliary map storage */
                    429:        register char **usrvp;          /* Vector pointer into user seg */
                    430:        register char *usrcp;           /* Character pointer into user seg */
                    431:        register int c;                 /* Character fetched from user */
                    432:        register int chrsz;             /* Size of strings */
                    433:        register struct adata *adp;     /* Arg and env scanner */
                    434:        register int vecsz;             /* Size of vectors */
                    435:        register int stksz;             /* Size of stack argument region */
                    436: 
                    437:        /* Validate and evaluate size of args and envs */
                    438:        arg.up = argp;
                    439:        env.up = envp;
                    440:        chrsz = 0;
                    441:        vecsz = 0;
                    442:        for (adp = &arg; ; adp = &env) {
                    443:                adp->np = 0;
                    444:                adp->nc = 0;
                    445:                if (excount(adp->up, &adp->np, &adp->nc) == 0)
                    446:                        return (NULL);
                    447:                chrsz += adp->nc * sizeof(char);
                    448:                vecsz += adp->np * sizeof(char *);
                    449:                if (adp == &env)
                    450:                        break;
                    451:        }
                    452: 
                    453:        /* Calculate stack size and allocate it */
                    454:        chrsz = roundu(chrsz, sizeof(int));
                    455:        stksz = sizeof(int)             /* argc */
                    456:                + sizeof(char **)       /* argv */
                    457:                + sizeof(char **)       /* envp */
                    458:                + vecsz                 /* argv[i] and envp[i] */
                    459:                + chrsz                 /* *argv[i] and *envp[i] */
                    460:                + sizeof(int)           /* Mystery zero word */
                    461:                + sizeof(char *)        /* Splimit for z8000 */
                    462:                + sizeof(int);          /* errno */
                    463:        stksz += ISTSIZE;
                    464:        if (stksz > MADSIZE) {
                    465:                u.u_error = E2BIG;
                    466:                return (NULL);
                    467:        }
                    468:        if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
                    469:                return (NULL);
                    470:        stksz -= ISTSIZE;
                    471: 
                    472:        /*
                    473:         * Initialize segment data.
                    474:         */
                    475:        asave(aold);
                    476: 
                    477:        aux.base = abase(sp->s_mbase) + ctob(sp->s_size);
                    478:        aux.ap = aux.base - stksz;
                    479:        aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
                    480:        aux.cp = aux.vp + vecsz;
                    481: 
                    482:        stk.base = ISTVIRT;
                    483:        stk.ap = stk.base - stksz;
                    484:        stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
                    485:        stk.cp = stk.vp + vecsz;
                    486: 
                    487:        /*
                    488:         * Write argc.
                    489:         */
                    490:        aputi((int *)aux.ap, arg.np-1);
                    491:        aux.ap += sizeof(int);
                    492: 
                    493:        /*
                    494:         * Arguments and environments.
                    495:         */
                    496:        for (adp = &arg; ; adp = &env) {
                    497: 
                    498:                /* Write argv or envp */
                    499:                aputp((char ***)aux.ap, (char **)stk.vp);
                    500:                aux.ap += sizeof(char **);
                    501:                if ((usrvp = adp->up) != NULL) {
                    502: 
                    503:                        /* Write argv[i] or envp[i] */
                    504:                        while ((usrcp = getupd(usrvp++)) != NULL) {
                    505:                                aputp((char **)aux.vp, (char *)stk.cp);
                    506:                                aux.vp += sizeof(char *);
                    507:                                stk.vp += sizeof(char *);
                    508: 
                    509:                                /* Write argv[i][j] or envp[i][j] */
                    510:                                do {
                    511:                                        c = getubd(usrcp++);
                    512:                                        aputc((char *)aux.cp, c);
                    513:                                        aux.cp += sizeof(char);
                    514:                                        stk.cp += sizeof(char);
                    515:                                } while (c != '\0');
                    516:                        }
                    517:                }
                    518: 
                    519:                /* Write argv[argc] or envp[envc] */
                    520:                aputp((char **)aux.vp, NULL);
                    521:                aux.vp += sizeof(char *);
                    522:                stk.vp += sizeof(char *);
                    523:                if (adp == &env)
                    524:                        break;
                    525:        }
                    526: 
                    527:        /*
                    528:         * Clear out the slop.
                    529:         */
                    530:        aux.base -= sizeof(int);
                    531:        aputi((int *) aux.base, 0);             /* errno */
                    532:        aux.base -= sizeof(char *);
                    533:        aputp((char **) aux.base, (char *)stk.base-ctob(sp->s_size)+SOVSIZE);
                    534:        aux.base -= sizeof(int);
                    535:        aputi((int *) aux.base, 0);             /* mystery word */
                    536: 
                    537:        arest(aold);
                    538: 
                    539:        /*
                    540:         * Patch some values and return.
                    541:         */
                    542:        *iusp = stk.ap;         /* Patch initial usp */
                    543:        u.u_argc = arg.np-1;
                    544:        u.u_argp = stk.vp;      /* Points after NULL of envs */
                    545:        return (sp);
                    546: }
                    547: 
                    548: /*
                    549:  * Given a pointer to a list of arguments, a pointer to an argument count
                    550:  * and a pointer to a byte count, update incrementally the argument count
                    551:  * and the byte count.
                    552:  */
                    553: excount(usrvp, nap, nbp)
                    554: register char **usrvp;
                    555: int *nap;
                    556: int *nbp;
                    557: {
                    558:        register char *usrcp;
                    559:        register int c;
                    560:        register unsigned nb;
                    561:        register unsigned na;
                    562: 
                    563:        na = 1;
                    564:        nb = 0;
                    565:        if (usrvp != NULL) {
                    566:                for (;;) {
                    567:                        usrcp = getupd(usrvp++);
                    568:                        if (u.u_error)
                    569:                                return (0);
                    570:                        if (usrcp == NULL)
                    571:                                break;
                    572:                        na++;
                    573:                        for (;;) {
                    574:                                c = getubd(usrcp++);
                    575:                                if (u.u_error)
                    576:                                        return (0);
                    577:                                nb++;
                    578:                                if (c == '\0')
                    579:                                        break;
                    580:                        }
                    581:                }
                    582:        }
                    583:        *nap += na;
                    584:        *nbp += nb;
                    585:        return (1);
                    586: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.