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