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