|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.